mirror of
https://github.com/stefanpejcic/openpanel
synced 2025-06-26 18:28:26 +00:00
fork refine
This commit is contained in:
16
packages/core/src/interfaces/actions.ts
Normal file
16
packages/core/src/interfaces/actions.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
export type Action = "create" | "edit" | "list" | "show" | "clone";
|
||||
|
||||
export type RouteAction = Exclude<Action, "list"> | undefined;
|
||||
|
||||
export type RedirectAction =
|
||||
| Extract<Action, "list" | "show" | "edit" | "create">
|
||||
| false;
|
||||
|
||||
/**
|
||||
* @deprecated use RedirectAction type instead
|
||||
*/
|
||||
export type RedirectionTypes = RedirectAction;
|
||||
|
||||
export type FormAction = Extract<Action, "create" | "edit" | "clone">;
|
||||
|
||||
export type ActionWithPage = Extract<Action, "show" | "create" | "edit">;
|
||||
1
packages/core/src/interfaces/auditLog/index.ts
Normal file
1
packages/core/src/interfaces/auditLog/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from "./logData";
|
||||
15
packages/core/src/interfaces/auditLog/logData.ts
Normal file
15
packages/core/src/interfaces/auditLog/logData.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { BaseKey } from "..";
|
||||
|
||||
export interface ILog<TData = any> {
|
||||
id: BaseKey;
|
||||
createdAt: string;
|
||||
author?: Record<number | string, any>;
|
||||
name?: string;
|
||||
data: TData;
|
||||
previousData: TData;
|
||||
resource: string;
|
||||
action: string;
|
||||
meta?: Record<number | string, any>;
|
||||
}
|
||||
|
||||
export type ILogData<TData = any> = ILog<TData>[];
|
||||
228
packages/core/src/interfaces/auth.tsx
Normal file
228
packages/core/src/interfaces/auth.tsx
Normal file
@@ -0,0 +1,228 @@
|
||||
import React, { PropsWithChildren } from "react";
|
||||
|
||||
export type OAuthProvider = {
|
||||
name: string;
|
||||
icon?: React.ReactNode;
|
||||
label?: string;
|
||||
};
|
||||
|
||||
export interface LoginFormTypes {
|
||||
email?: string;
|
||||
password?: string;
|
||||
remember?: boolean;
|
||||
providerName?: string;
|
||||
redirectPath?: string;
|
||||
}
|
||||
|
||||
export interface RegisterFormTypes {
|
||||
email?: string;
|
||||
password?: string;
|
||||
providerName?: string;
|
||||
}
|
||||
|
||||
export interface ForgotPasswordFormTypes {
|
||||
email?: string;
|
||||
}
|
||||
|
||||
export interface UpdatePasswordFormTypes {
|
||||
password?: string;
|
||||
confirmPassword?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* This should be the base type for `AuthPage` component implementations in UI integrations.
|
||||
*/
|
||||
export type AuthPageProps<
|
||||
TWrapperProps extends {} = Record<keyof any, unknown>,
|
||||
TContentProps extends {} = Record<keyof any, unknown>,
|
||||
TFormProps extends {} = Record<keyof any, unknown>,
|
||||
> = (
|
||||
| PropsWithChildren<{
|
||||
/**
|
||||
* @description The type of the auth page.
|
||||
* @default "login"
|
||||
* @optional
|
||||
*/
|
||||
type?: "login";
|
||||
/**
|
||||
* @description Providers array for login with third party auth services.
|
||||
* @type [OAuthProvider](/docs/api-reference/core/components/auth-page/#interface)
|
||||
* @optional
|
||||
*/
|
||||
providers?: OAuthProvider[];
|
||||
/**
|
||||
* @description Render a redirect to register page button node. If set to false, register button will not be rendered.
|
||||
* @default `"/register"`
|
||||
* @optional
|
||||
*/
|
||||
registerLink?: React.ReactNode;
|
||||
/**
|
||||
* @description Render a redirect to forgot password page button node. If set to false, forgot password button will not be rendered.
|
||||
* @default `"/forgot-password"`
|
||||
* @optional
|
||||
*/
|
||||
forgotPasswordLink?: React.ReactNode;
|
||||
/**
|
||||
* @description Render a remember me button node. If set to false, remember me button will not be rendered.
|
||||
* @optional
|
||||
*/
|
||||
rememberMe?: React.ReactNode;
|
||||
/**
|
||||
* @description Can be used to hide the form components
|
||||
* @optional
|
||||
*/
|
||||
hideForm?: boolean;
|
||||
}>
|
||||
| PropsWithChildren<{
|
||||
/**
|
||||
* @description The type of the auth page.
|
||||
* @optional
|
||||
*/
|
||||
type: "register";
|
||||
/**
|
||||
* @description Providers array for login with third party auth services.
|
||||
* @optional
|
||||
*/
|
||||
providers?: OAuthProvider[];
|
||||
/**
|
||||
* @description Render a redirect to login page button node. If set to false, login button will not be rendered.
|
||||
* @default `"/login"`
|
||||
* @optional
|
||||
*/
|
||||
loginLink?: React.ReactNode;
|
||||
/**
|
||||
* @description Can be used to hide the form components
|
||||
* @optional
|
||||
*/
|
||||
hideForm?: boolean;
|
||||
}>
|
||||
| PropsWithChildren<{
|
||||
/**
|
||||
* @description The type of the auth page.
|
||||
* @optional
|
||||
*/
|
||||
type: "forgotPassword";
|
||||
/**
|
||||
* @description render a redirect to login page button node. If set to false, login button will not be rendered.
|
||||
* @optional
|
||||
*/
|
||||
loginLink?: React.ReactNode;
|
||||
}>
|
||||
| PropsWithChildren<{
|
||||
/**
|
||||
* @description The type of the auth page.
|
||||
* @optional
|
||||
*/
|
||||
type: "updatePassword";
|
||||
}>
|
||||
) & {
|
||||
/**
|
||||
* @description The props that will be passed to the wrapper component.
|
||||
* @optional
|
||||
*/
|
||||
wrapperProps?: TWrapperProps;
|
||||
/**
|
||||
* @description The props that will be passed to the content component.
|
||||
* @optional
|
||||
*/
|
||||
contentProps?: TContentProps;
|
||||
/**
|
||||
* @description This method gives you the ability to render a custom content node.
|
||||
* @optional
|
||||
*/
|
||||
renderContent?: (
|
||||
content: React.ReactNode,
|
||||
title: React.ReactNode,
|
||||
) => React.ReactNode;
|
||||
/**
|
||||
* @description Can be used to pass additional properties for the `Form`
|
||||
* @optional
|
||||
*/
|
||||
formProps?: TFormProps;
|
||||
/**
|
||||
* @description Can be used to pass `Title`
|
||||
* @optional
|
||||
* */
|
||||
title?: React.ReactNode;
|
||||
};
|
||||
|
||||
/**
|
||||
* This should be the base type for `AuthPage` `Login` component implementations in UI integrations.
|
||||
*/
|
||||
export type LoginPageProps<
|
||||
TWrapperProps extends {} = Record<keyof any, unknown>,
|
||||
TContentProps extends {} = Record<keyof any, unknown>,
|
||||
TFormProps extends {} = Record<keyof any, unknown>,
|
||||
> = PropsWithChildren<{
|
||||
providers?: OAuthProvider[];
|
||||
registerLink?: React.ReactNode;
|
||||
forgotPasswordLink?: React.ReactNode;
|
||||
rememberMe?: React.ReactNode;
|
||||
wrapperProps?: TWrapperProps;
|
||||
renderContent?: (
|
||||
content: React.ReactNode,
|
||||
title: React.ReactNode,
|
||||
) => React.ReactNode;
|
||||
contentProps?: TContentProps;
|
||||
formProps?: TFormProps;
|
||||
title?: React.ReactNode;
|
||||
hideForm?: boolean;
|
||||
}>;
|
||||
|
||||
/**
|
||||
* This should be the base type for `AuthPage` `Register` component implementations in UI integrations.
|
||||
*/
|
||||
export type RegisterPageProps<
|
||||
TWrapperProps extends {} = Record<keyof any, unknown>,
|
||||
TContentProps extends {} = Record<keyof any, unknown>,
|
||||
TFormProps extends {} = Record<keyof any, unknown>,
|
||||
> = PropsWithChildren<{
|
||||
providers?: OAuthProvider[];
|
||||
loginLink?: React.ReactNode;
|
||||
wrapperProps?: TWrapperProps;
|
||||
renderContent?: (
|
||||
content: React.ReactNode,
|
||||
title: React.ReactNode,
|
||||
) => React.ReactNode;
|
||||
contentProps?: TContentProps;
|
||||
formProps?: TFormProps;
|
||||
title?: React.ReactNode;
|
||||
hideForm?: boolean;
|
||||
}>;
|
||||
|
||||
/**
|
||||
* This should be the base type for `AuthPage` `Reset Password` component implementations in UI integrations.
|
||||
*/
|
||||
export type ForgotPasswordPageProps<
|
||||
TWrapperProps extends {} = Record<keyof any, unknown>,
|
||||
TContentProps extends {} = Record<keyof any, unknown>,
|
||||
TFormProps extends {} = Record<keyof any, unknown>,
|
||||
> = PropsWithChildren<{
|
||||
loginLink?: React.ReactNode;
|
||||
wrapperProps?: TWrapperProps;
|
||||
renderContent?: (
|
||||
content: React.ReactNode,
|
||||
title: React.ReactNode,
|
||||
) => React.ReactNode;
|
||||
contentProps?: TContentProps;
|
||||
formProps?: TFormProps;
|
||||
title?: React.ReactNode;
|
||||
}>;
|
||||
|
||||
/**
|
||||
* This should be the base type for `AuthPage` `Update Password` component implementations in UI integrations.
|
||||
*/
|
||||
export type UpdatePasswordPageProps<
|
||||
TWrapperProps extends {} = Record<keyof any, unknown>,
|
||||
TContentProps extends {} = Record<keyof any, unknown>,
|
||||
TFormProps extends {} = Record<keyof any, unknown>,
|
||||
> = PropsWithChildren<{
|
||||
wrapperProps?: TWrapperProps;
|
||||
renderContent?: (
|
||||
content: React.ReactNode,
|
||||
title: React.ReactNode,
|
||||
) => React.ReactNode;
|
||||
contentProps?: TContentProps;
|
||||
formProps?: TFormProps;
|
||||
title?: React.ReactNode;
|
||||
}>;
|
||||
54
packages/core/src/interfaces/autoSave.ts
Normal file
54
packages/core/src/interfaces/autoSave.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import React from "react";
|
||||
import { BaseRecord, HttpError, UpdateResponse } from ".";
|
||||
import { UseUpdateReturnType } from "../hooks/data/useUpdate";
|
||||
|
||||
export type AutoSaveProps<TVariables> = {
|
||||
autoSave?: {
|
||||
enabled: boolean;
|
||||
debounce?: number;
|
||||
onFinish?: (values: TVariables) => TVariables;
|
||||
invalidateOnUnmount?: boolean;
|
||||
invalidateOnClose?: boolean;
|
||||
};
|
||||
};
|
||||
|
||||
export type AutoSaveReturnType<
|
||||
TData extends BaseRecord = BaseRecord,
|
||||
TError extends HttpError = HttpError,
|
||||
TVariables = {},
|
||||
> = {
|
||||
autoSaveProps: Pick<
|
||||
UseUpdateReturnType<TData, TError, TVariables>,
|
||||
"data" | "error" | "status"
|
||||
>;
|
||||
onFinishAutoSave: (
|
||||
values: TVariables,
|
||||
) => Promise<UpdateResponse<TData> | void> | void;
|
||||
};
|
||||
|
||||
export type AutoSaveIndicatorElements = Partial<
|
||||
Record<"success" | "error" | "loading" | "idle", React.ReactNode>
|
||||
>;
|
||||
|
||||
export type AutoSaveIndicatorProps<
|
||||
TData extends BaseRecord = BaseRecord,
|
||||
TError extends HttpError = HttpError,
|
||||
TVariables = {},
|
||||
> = {
|
||||
/**
|
||||
* The data returned by the update request.
|
||||
*/
|
||||
data?: UseUpdateReturnType<TData, TError, TVariables>["data"];
|
||||
/**
|
||||
* The error returned by the update request.
|
||||
*/
|
||||
error?: UseUpdateReturnType<TData, TError, TVariables>["error"];
|
||||
/**
|
||||
* The status of the update request.
|
||||
*/
|
||||
status: UseUpdateReturnType<TData, TError, TVariables>["status"];
|
||||
/**
|
||||
* The elements to display for each status.
|
||||
*/
|
||||
elements?: AutoSaveIndicatorElements;
|
||||
};
|
||||
53
packages/core/src/interfaces/bindings/access-control.ts
Normal file
53
packages/core/src/interfaces/bindings/access-control.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* @author aliemir
|
||||
*
|
||||
* `AccessControlBindings` interface, used to define the access control bindings of refine.
|
||||
*
|
||||
* Currently, there's no change in the interface, but only in the `params.resource` property.
|
||||
*
|
||||
* This also had `{ children?: ITreeMenu[] }` type extension but we can remove it now.
|
||||
*
|
||||
* There's an error behind this extension, since we're using `Tanstack Query` to check the `can` function,
|
||||
* params are stringified and Nodes can't be stringified properly, which throws an error.
|
||||
*
|
||||
* These kinds of errors should be handled by the user of the `can` function, not by the `can` function itself.
|
||||
*
|
||||
* In this case, its the `CanAccess` component, which wraps the `can` function and is used in the `Sider` components.
|
||||
* `Sider` should sanitize the `params.resource` property and remove the `children` property (if exists).
|
||||
*
|
||||
* This may also apply to `resource.icon` property.
|
||||
*
|
||||
*/
|
||||
|
||||
import { IResourceItem } from "@contexts/resource";
|
||||
import { BaseKey } from "src";
|
||||
|
||||
export type CanParams = {
|
||||
/**
|
||||
* Resource name for API data interactions
|
||||
*/
|
||||
resource: string;
|
||||
/**
|
||||
* Intenden action on resource
|
||||
*/
|
||||
action: string;
|
||||
/**
|
||||
* Parameters associated with the resource
|
||||
* @type { resource?: [IResourceItem](https://refine.dev/docs/api-reference/core/interfaceReferences/#canparams), id?: [BaseKey](https://refine.dev/docs/api-reference/core/interfaceReferences/#basekey), [key: string]: any }
|
||||
*/
|
||||
params?: {
|
||||
resource?: IResourceItem;
|
||||
id?: BaseKey;
|
||||
[key: string]: unknown;
|
||||
};
|
||||
};
|
||||
|
||||
export type CanResponse = {
|
||||
can: boolean;
|
||||
reason?: string;
|
||||
[key: string]: unknown;
|
||||
};
|
||||
|
||||
export type AccessControlBindings = {
|
||||
can: (params: CanParams) => Promise<CanResponse>;
|
||||
};
|
||||
76
packages/core/src/interfaces/bindings/auth.ts
Normal file
76
packages/core/src/interfaces/bindings/auth.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* @author aliemir
|
||||
*
|
||||
* In the current internal structure, sometimes we pass params and args from one function to another,
|
||||
* like in case of `check` (formerly `checkAuth`) function, we pass the reject value to `useLogout` hook,
|
||||
* which handles the redirect after logout.
|
||||
*
|
||||
* These actions should be separated,
|
||||
*
|
||||
* Apps can exist with an optional auth,
|
||||
* or do not redirect after logout,
|
||||
* or do the redirect but not log out,
|
||||
* or do the redirect to a different page than `/login`.
|
||||
*
|
||||
* To cover all those cases, we should return more information from auth functions.
|
||||
*
|
||||
* Let's say, they should always resolve, even if user is not authenticated,
|
||||
* but have the proper information to handle the situation.
|
||||
*
|
||||
* like `authenticated: false`, `redirect: '/login'` and `logout: true`
|
||||
* which will inform refine that user is not authenticated and should be redirected to `/login` and logout.
|
||||
* In some cases, redirect might need to be transferred to other hooks (like `useLogout` hook),
|
||||
* but these cases can be handled internally.
|
||||
*
|
||||
* If the response from `check` is `{ authenticated: false, logout: false, redirect: "/not-authenticated" }`,
|
||||
* then the user will be redirected to `/not-authenticated` without logging out.
|
||||
*
|
||||
* If the response from `check` is `{ authenticated: false, logout: true, redirect: false }`,
|
||||
* then the user will be logged out without redirecting.
|
||||
*
|
||||
* Same goes for `onError` function, it should always resolve.
|
||||
*/
|
||||
|
||||
import { RefineError } from "../errors";
|
||||
|
||||
export type CheckResponse = {
|
||||
authenticated: boolean;
|
||||
redirectTo?: string;
|
||||
logout?: boolean;
|
||||
error?: RefineError | Error;
|
||||
};
|
||||
|
||||
export type OnErrorResponse = {
|
||||
redirectTo?: string;
|
||||
logout?: boolean;
|
||||
error?: RefineError | Error;
|
||||
};
|
||||
|
||||
export type AuthActionResponse = {
|
||||
success: boolean;
|
||||
redirectTo?: string;
|
||||
error?: RefineError | Error;
|
||||
[key: string]: unknown;
|
||||
};
|
||||
|
||||
export type PermissionResponse = unknown;
|
||||
|
||||
export type IdentityResponse = unknown;
|
||||
|
||||
export type AuthBindings = {
|
||||
login: (params: any) => Promise<AuthActionResponse>;
|
||||
logout: (params: any) => Promise<AuthActionResponse>;
|
||||
check: (params?: any) => Promise<CheckResponse>;
|
||||
onError: (error: any) => Promise<OnErrorResponse>;
|
||||
register?: (params: any) => Promise<AuthActionResponse>;
|
||||
forgotPassword?: (params: any) => Promise<AuthActionResponse>;
|
||||
updatePassword?: (params: any) => Promise<AuthActionResponse>;
|
||||
getPermissions?: (params?: any) => Promise<PermissionResponse>;
|
||||
getIdentity?: (params?: any) => Promise<IdentityResponse>;
|
||||
};
|
||||
|
||||
export interface IAuthBindingsContext extends Partial<AuthProvider> {
|
||||
isProvided: boolean;
|
||||
}
|
||||
|
||||
export type AuthProvider = AuthBindings;
|
||||
18
packages/core/src/interfaces/bindings/data.ts
Normal file
18
packages/core/src/interfaces/bindings/data.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* @author aliemir
|
||||
*
|
||||
* There's no change between `DataBindings` and `DataProvider` interfaces.
|
||||
*
|
||||
* But we should probably throw a soft error to the console if there's no `default` key in `MultipleDataBinding`.
|
||||
*/
|
||||
|
||||
import { IDataContext } from "@contexts/data/IDataContext";
|
||||
|
||||
export type SingleDataBinding = IDataContext;
|
||||
|
||||
export type MultipleDataBinding = {
|
||||
default: IDataContext;
|
||||
[key: string]: IDataContext;
|
||||
};
|
||||
|
||||
export type DataBindings = SingleDataBinding | MultipleDataBinding;
|
||||
29
packages/core/src/interfaces/bindings/i18n.ts
Normal file
29
packages/core/src/interfaces/bindings/i18n.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* @author aliemir
|
||||
*
|
||||
* i18n bindings are same with the `i18nProvider` interface.
|
||||
*
|
||||
* We should probably enforce the three or single parameter use in our hooks.
|
||||
*
|
||||
* Currently, we cover the `key, options`, `key, defaultMessage`, `key, options, defaultMessage` usages internally in i18n hooks.
|
||||
* Which creates an unnecessary confusion in the codebase.
|
||||
*/
|
||||
|
||||
export type TranslateFunction = (
|
||||
key: string,
|
||||
options?: unknown,
|
||||
defaultMessage?: string,
|
||||
) => string;
|
||||
|
||||
export type ChangeLocaleFunction = (
|
||||
locale: string,
|
||||
options?: unknown,
|
||||
) => Promise<unknown> | unknown;
|
||||
|
||||
export type GetLocaleFunction = () => string;
|
||||
|
||||
export type i18nBindings = {
|
||||
translate: TranslateFunction;
|
||||
changeLocale: ChangeLocaleFunction;
|
||||
getLocale: GetLocaleFunction;
|
||||
};
|
||||
25
packages/core/src/interfaces/bindings/index.ts
Normal file
25
packages/core/src/interfaces/bindings/index.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
export { AccessControlBindings } from "./access-control";
|
||||
export {
|
||||
AuthBindings,
|
||||
IAuthBindingsContext,
|
||||
AuthActionResponse,
|
||||
IdentityResponse,
|
||||
CheckResponse,
|
||||
OnErrorResponse,
|
||||
PermissionResponse,
|
||||
AuthProvider,
|
||||
} from "./auth";
|
||||
export { DataBindings } from "./data";
|
||||
export { i18nBindings } from "./i18n";
|
||||
export { LiveBindings } from "./live";
|
||||
export { NotificationsBindings } from "./notifications";
|
||||
export { ResourceBindings } from "./resource";
|
||||
export {
|
||||
RouterBindings,
|
||||
ParseResponse,
|
||||
ParsedParams,
|
||||
GoConfig,
|
||||
BackFunction,
|
||||
GoFunction,
|
||||
ParseFunction,
|
||||
} from "./router";
|
||||
56
packages/core/src/interfaces/bindings/live.ts
Normal file
56
packages/core/src/interfaces/bindings/live.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* @author aliemir
|
||||
*
|
||||
* There's a small change in the `LiveBindings` interface, we've defined the `params` property of `subscribe` function
|
||||
* as a combination of `LiveCommonParams` and `LiveListParams & LiveOneParams & LiveManyParams`.
|
||||
* which creates a bit of a confusion because in `list` type we don't need `id` or `ids` and in `one` type we don't need `ids`.
|
||||
* There should be an update like below to make it more clear in usage.
|
||||
*
|
||||
* A small but kinda important change for the consistency of the codebase.
|
||||
*/
|
||||
|
||||
import {
|
||||
BaseKey,
|
||||
CrudFilters,
|
||||
CrudSorting,
|
||||
LiveEvent,
|
||||
MetaQuery,
|
||||
Pagination,
|
||||
} from "src";
|
||||
|
||||
export type LiveListParams = {
|
||||
resource?: string;
|
||||
pagination?: Pagination;
|
||||
hasPagination?: boolean;
|
||||
sort?: CrudSorting;
|
||||
filters?: CrudFilters;
|
||||
meta?: MetaQuery;
|
||||
metaData?: MetaQuery;
|
||||
};
|
||||
|
||||
export type LiveOneParams = {
|
||||
resource?: string;
|
||||
id?: BaseKey;
|
||||
};
|
||||
|
||||
export type LiveManyParams = {
|
||||
resource?: string;
|
||||
ids?: BaseKey[];
|
||||
};
|
||||
|
||||
export type LiveCommonParams = {
|
||||
subscriptionType: "useList" | "useOne" | "useMany";
|
||||
[key: string]: unknown;
|
||||
};
|
||||
|
||||
export type LiveBindings = {
|
||||
publish?: (event: LiveEvent) => void;
|
||||
subscribe: (options: {
|
||||
channel: string;
|
||||
types: Array<LiveEvent["type"]>;
|
||||
callback: (event: LiveEvent) => void;
|
||||
params?: LiveCommonParams &
|
||||
(LiveListParams | LiveOneParams | LiveManyParams);
|
||||
}) => unknown;
|
||||
unsubscribe: (subscription: unknown) => void;
|
||||
};
|
||||
25
packages/core/src/interfaces/bindings/notifications.ts
Normal file
25
packages/core/src/interfaces/bindings/notifications.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* @author aliemir
|
||||
*
|
||||
* While switching to NotificationBindings, we can try to experiment and explore the idea of
|
||||
* user controlled undoable notifications.
|
||||
*
|
||||
* Currently, we're handling the undoable notifications internally by updating the existing notification.
|
||||
* This is leading to some uncontrollable behaviors in the notification bindings.
|
||||
*
|
||||
* While leaving the control might not be possible, we can still try it at least. :)
|
||||
*/
|
||||
|
||||
export interface OpenNotificationParams {
|
||||
key?: string;
|
||||
message: string;
|
||||
type: "success" | "error" | "progress";
|
||||
description?: string;
|
||||
cancelMutation?: () => void;
|
||||
undoableTimeout?: number;
|
||||
}
|
||||
|
||||
export type NotificationsBindings = {
|
||||
open: (params: OpenNotificationParams) => void;
|
||||
close: (key: string) => void;
|
||||
};
|
||||
178
packages/core/src/interfaces/bindings/resource.ts
Normal file
178
packages/core/src/interfaces/bindings/resource.ts
Normal file
@@ -0,0 +1,178 @@
|
||||
import { ReactNode, ComponentType } from "react";
|
||||
import { UseQueryResult } from "@tanstack/react-query";
|
||||
import { ILogData } from "src/interfaces";
|
||||
|
||||
/**
|
||||
* Resource route components
|
||||
*/
|
||||
export type ResourceRouteComponent = ComponentType<
|
||||
IResourceComponentsProps<any, any>
|
||||
>;
|
||||
|
||||
export type ResourceRoutePath = string;
|
||||
|
||||
export type ResourceRouteDefinition = {
|
||||
path: ResourceRoutePath;
|
||||
component: ResourceRouteComponent;
|
||||
};
|
||||
|
||||
export type ResourceRouteComposition =
|
||||
| ResourceRouteDefinition
|
||||
| ResourceRoutePath
|
||||
| ResourceRouteComponent;
|
||||
|
||||
export interface IResourceComponents {
|
||||
list?: ResourceRouteComposition;
|
||||
create?: ResourceRouteComposition;
|
||||
clone?: ResourceRouteComposition;
|
||||
edit?: ResourceRouteComposition;
|
||||
show?: ResourceRouteComposition;
|
||||
}
|
||||
|
||||
export type AnyString = string & { __ignore?: never };
|
||||
|
||||
export type ResourceAuditLogPermissions =
|
||||
| "create"
|
||||
| "update"
|
||||
| "delete"
|
||||
| AnyString;
|
||||
|
||||
/** Resource `meta` */
|
||||
export interface KnownResourceMeta {
|
||||
/**
|
||||
* This is used when setting the document title, in breadcrumbs and `<Sider />` components.
|
||||
* Therefore it will only work if the related components have implemented the `label` property.
|
||||
*/
|
||||
label?: string;
|
||||
/**
|
||||
* Whether to hide the resource from the sidebar or not.
|
||||
* This property is checked by the `<Sider />` components.
|
||||
* Therefore it will only work if the `<Sider />` component has implemented the `hide` property.
|
||||
*/
|
||||
hide?: boolean;
|
||||
/**
|
||||
* Dedicated data provider name for the resource.
|
||||
* If not set, the default data provider will be used.
|
||||
* You can use this property to pick a data provider for a resource when you have multiple data providers.
|
||||
*/
|
||||
dataProviderName?: string;
|
||||
/**
|
||||
* To nest a resource under another resource, set the parent property to the name of the parent resource.
|
||||
* This will work even if the parent resource is not explicitly defined.
|
||||
*/
|
||||
parent?: string;
|
||||
/**
|
||||
* To determine if the resource has ability to delete or not.
|
||||
*/
|
||||
canDelete?: boolean;
|
||||
/**
|
||||
* To permit the audit log for actions on the resource.
|
||||
* @default All actions are permitted to be logged.
|
||||
*/
|
||||
audit?: ResourceAuditLogPermissions[];
|
||||
/**
|
||||
* To pass `icon` to the resource.
|
||||
*/
|
||||
icon?: ReactNode;
|
||||
}
|
||||
|
||||
export interface DeprecatedOptions {
|
||||
/**
|
||||
* @deprecated Please use `audit` property instead.
|
||||
*/
|
||||
auditLog?: {
|
||||
permissions?: ResourceAuditLogPermissions[];
|
||||
};
|
||||
/**
|
||||
* @deprecated Define the route in the resource components instead
|
||||
*/
|
||||
route?: string;
|
||||
}
|
||||
|
||||
export interface ResourceMeta extends KnownResourceMeta {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export interface ResourceProps extends IResourceComponents {
|
||||
name: string;
|
||||
/**
|
||||
* This property can be used to identify a resource. In some cases, `name` of the resource might be repeated in different resources.
|
||||
* To avoid conflicts, you pass the `identifier` property to be used as the key of the resource.
|
||||
* @default `name` of the resource
|
||||
*/
|
||||
identifier?: string;
|
||||
/**
|
||||
* @deprecated This property is not used anymore.
|
||||
*/
|
||||
key?: string;
|
||||
/**
|
||||
* @deprecated Please use the `meta` property instead.
|
||||
*/
|
||||
options?: ResourceMeta & DeprecatedOptions;
|
||||
/**
|
||||
* To configure the resource, you can set `meta` properties. You can use `meta` to store any data related to the resource.
|
||||
* There are some known `meta` properties that are used by the core and extension packages.
|
||||
*/
|
||||
meta?: ResourceMeta & DeprecatedOptions;
|
||||
/**
|
||||
* @deprecated Please use the `meta.canDelete` property instead.
|
||||
*/
|
||||
canDelete?: boolean;
|
||||
/**
|
||||
* @deprecated Please use the `meta.icon` property instead
|
||||
*/
|
||||
icon?: ReactNode;
|
||||
/**
|
||||
* @deprecated Please use the `meta.parent` property instead
|
||||
*/
|
||||
parentName?: string;
|
||||
}
|
||||
|
||||
export interface RouteableProperties {
|
||||
/**
|
||||
* @deprecated Please use action props instead.
|
||||
*/
|
||||
canCreate?: boolean;
|
||||
/**
|
||||
* @deprecated Please use action props instead.
|
||||
*/
|
||||
canEdit?: boolean;
|
||||
/**
|
||||
* @deprecated Please use action props instead.
|
||||
*/
|
||||
canShow?: boolean;
|
||||
/**
|
||||
* @deprecated Please use the `meta.canDelete` property instead.
|
||||
*/
|
||||
canDelete?: boolean;
|
||||
}
|
||||
|
||||
export interface IResourceComponentsProps<
|
||||
TCrudData = any,
|
||||
TLogQueryResult = ILogData,
|
||||
> extends RouteableProperties {
|
||||
name?: string;
|
||||
initialData?: TCrudData;
|
||||
options?: ResourceMeta & DeprecatedOptions;
|
||||
logQueryResult?: UseQueryResult<TLogQueryResult>;
|
||||
}
|
||||
|
||||
export interface IResourceItem
|
||||
extends IResourceComponents,
|
||||
RouteableProperties,
|
||||
ResourceProps {
|
||||
/**
|
||||
* @deprecated Please use the `meta.label` property instead.
|
||||
*/
|
||||
label?: string;
|
||||
/**
|
||||
* @deprecated Please use action components and `getDefaultActionPath` helper instead.
|
||||
*/
|
||||
route?: string;
|
||||
}
|
||||
|
||||
export interface IResourceContext {
|
||||
resources: IResourceItem[];
|
||||
}
|
||||
|
||||
export type ResourceBindings = ResourceProps[];
|
||||
78
packages/core/src/interfaces/bindings/router.ts
Normal file
78
packages/core/src/interfaces/bindings/router.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* @author aliemir
|
||||
*
|
||||
* Router bindings interface, used to define the router bindings of refine.
|
||||
*
|
||||
* We're marking of the functions as optional, some features may not work properly but this is intentional.
|
||||
* Users can choose to use the router bindings or not, or use their own router bindings.
|
||||
* Leaving the control to the user is the best way to go.
|
||||
*
|
||||
* We're defining the functions as function generators, this is to allow the user to use hooks inside the functions.
|
||||
*
|
||||
* `go` function is used to navigate to a specific route. We're expecting a `GoConfig` object as the only parameter.
|
||||
* Passing `query` as an object, will also let users to stringify the object as they like or ignore it completely or even use a custom logic to handle query strings.
|
||||
*
|
||||
* `back` function is used to navigate back to the previous route. It doesn't take any parameters.
|
||||
* This one is a basic function for the back buttons, absence of this function can also hide the back button,
|
||||
* but this depends on the UI package implementations.
|
||||
*
|
||||
* `parse` function is used to parse the current route, query parameters and other information.
|
||||
* We're expecting this function to lead refine to the correct resource, action and id (again, not required but recommended).
|
||||
* Also there's `params` property, which is used in data hooks and other places.
|
||||
* This property has an interface to match but not restricted to it.
|
||||
*
|
||||
* Instead of a single `useNavigation` hook,
|
||||
* we can separate those functions into three different hooks,
|
||||
* `useGo`, `useBack` and `useParsed`
|
||||
*/
|
||||
|
||||
import { CrudFilters, CrudSorting } from "@contexts/data/IDataContext";
|
||||
import { IResourceItem } from "./resource";
|
||||
import { Action, BaseKey } from "..";
|
||||
|
||||
export type GoConfig = {
|
||||
to?: string;
|
||||
query?: Record<string, unknown>;
|
||||
hash?: string;
|
||||
options?: {
|
||||
keepQuery?: boolean;
|
||||
keepHash?: boolean;
|
||||
};
|
||||
type?: "push" | "replace" | "path";
|
||||
};
|
||||
|
||||
export type ParsedParams<
|
||||
TParams extends Record<string, any> = Record<string, any>,
|
||||
> = {
|
||||
filters?: CrudFilters;
|
||||
sorters?: CrudSorting;
|
||||
current?: number;
|
||||
pageSize?: number;
|
||||
} & TParams;
|
||||
|
||||
export type ParseResponse<
|
||||
TParams extends Record<string, any> = Record<string, any>,
|
||||
> = {
|
||||
params?: ParsedParams<TParams>;
|
||||
resource?: IResourceItem;
|
||||
id?: BaseKey;
|
||||
action?: Action;
|
||||
pathname?: string;
|
||||
};
|
||||
|
||||
export type GoFunction = (config: GoConfig) => void | string;
|
||||
|
||||
export type BackFunction = () => void;
|
||||
|
||||
export type ParseFunction<
|
||||
TParams extends Record<string, any> = Record<string, any>,
|
||||
> = () => ParseResponse<TParams>;
|
||||
|
||||
export type RouterBindings = {
|
||||
go?: () => GoFunction;
|
||||
back?: () => BackFunction;
|
||||
parse?: () => ParseFunction;
|
||||
Link?: React.ComponentType<
|
||||
React.PropsWithChildren<{ to: string; [prop: string]: any }>
|
||||
>;
|
||||
};
|
||||
28
packages/core/src/interfaces/customComponents.ts
Normal file
28
packages/core/src/interfaces/customComponents.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import React, { ReactNode } from "react";
|
||||
|
||||
export type TitleProps = {
|
||||
collapsed: boolean;
|
||||
};
|
||||
|
||||
export type LayoutProps = {
|
||||
Sider?: React.FC<{
|
||||
Title?: React.FC<TitleProps>;
|
||||
render?: (props: {
|
||||
items: JSX.Element[];
|
||||
logout: React.ReactNode;
|
||||
dashboard: React.ReactNode;
|
||||
collapsed: boolean;
|
||||
}) => React.ReactNode;
|
||||
meta?: Record<string, unknown>;
|
||||
}>;
|
||||
Header?: React.FC;
|
||||
Title?: React.FC<TitleProps>;
|
||||
Footer?: React.FC;
|
||||
OffLayoutArea?: React.FC;
|
||||
dashboard?: boolean;
|
||||
children?: ReactNode;
|
||||
};
|
||||
|
||||
export type DashboardPageProps<TCrudData = any> = {
|
||||
initialData?: TCrudData;
|
||||
} & Record<any, any>;
|
||||
13
packages/core/src/interfaces/errors/HttpError.ts
Normal file
13
packages/core/src/interfaces/errors/HttpError.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
export interface ValidationErrors {
|
||||
[field: string]:
|
||||
| string
|
||||
| string[]
|
||||
| boolean
|
||||
| { key: string; message: string };
|
||||
}
|
||||
|
||||
export interface HttpError extends Record<string, any> {
|
||||
message: string;
|
||||
statusCode: number;
|
||||
errors?: ValidationErrors;
|
||||
}
|
||||
3
packages/core/src/interfaces/errors/RefineError.ts
Normal file
3
packages/core/src/interfaces/errors/RefineError.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { HttpError } from "./HttpError";
|
||||
|
||||
export type RefineError = HttpError;
|
||||
2
packages/core/src/interfaces/errors/index.ts
Normal file
2
packages/core/src/interfaces/errors/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from "./HttpError";
|
||||
export * from "./RefineError";
|
||||
8
packages/core/src/interfaces/form-url-params.ts
Normal file
8
packages/core/src/interfaces/form-url-params.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export type FormWithSyncWithLocationParams = {
|
||||
/**
|
||||
* If true, the form will be synced with the location.
|
||||
* If an object is passed, the key property will be used as the key for the query params.
|
||||
* By default, query params are placed under the key, `${resource.name}-${action}`.
|
||||
*/
|
||||
syncWithLocation?: boolean | { key?: string; syncId?: boolean };
|
||||
};
|
||||
98
packages/core/src/interfaces/index.ts
Normal file
98
packages/core/src/interfaces/index.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
import { IResourceItem } from "./bindings/resource";
|
||||
|
||||
// contexts
|
||||
export * from "../contexts/data/IDataContext";
|
||||
export * from "../contexts/live/ILiveContext";
|
||||
export * from "../contexts/auth/IAuthContext";
|
||||
export * from "../contexts/refine/IRefineContext";
|
||||
export * from "../contexts/translation/ITranslationContext";
|
||||
export * from "../contexts/undoableQueue/IUndoableQueueContext";
|
||||
export * from "../contexts/resource/IResourceContext";
|
||||
export * from "../contexts/unsavedWarn/IUnsavedWarnContext";
|
||||
export * from "../contexts/legacy-router/IRouterContext";
|
||||
export * from "../contexts/accessControl/IAccessControlContext";
|
||||
export * from "../contexts/notification/INotificationContext";
|
||||
export * from "../contexts/auditLog/IAuditLogContext";
|
||||
|
||||
export * from "../components/pages/login";
|
||||
|
||||
// actions
|
||||
export * from "./actions";
|
||||
|
||||
// notification
|
||||
export * from "./notification";
|
||||
|
||||
// mutationMode
|
||||
export * from "./mutationMode";
|
||||
|
||||
// mutationMode
|
||||
export * from "./errors";
|
||||
|
||||
// custom components
|
||||
export * from "./customComponents";
|
||||
|
||||
// resourceRouterParams
|
||||
export * from "./resourceRouterParams";
|
||||
|
||||
// resourceErrorRouterParams
|
||||
export * from "./resourceErrorRouterParams";
|
||||
|
||||
// mapData
|
||||
export * from "./mapDataFn";
|
||||
|
||||
// successErrorNotification
|
||||
export * from "./successErrorNotification";
|
||||
|
||||
//metaData
|
||||
export * from "./metaData";
|
||||
|
||||
//queryKeys
|
||||
export * from "./queryKey";
|
||||
|
||||
//metaData
|
||||
export * from "./live";
|
||||
|
||||
//auditLog
|
||||
export * from "./auditLog";
|
||||
|
||||
export type BaseKey = string | number;
|
||||
export type BaseRecord = {
|
||||
id?: BaseKey;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
[key: string]: any;
|
||||
};
|
||||
export type BaseOption = {
|
||||
label: any;
|
||||
value: any;
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated Use `BaseOption` instead.
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
export interface Option extends BaseOption {}
|
||||
|
||||
/* Backward compatible version of 'TreeMenuItem' */
|
||||
export type ITreeMenu = IResourceItem & {
|
||||
key?: string;
|
||||
children: ITreeMenu[];
|
||||
};
|
||||
|
||||
export type IMenuItem = IResourceItem & {
|
||||
key: string;
|
||||
route: string;
|
||||
};
|
||||
|
||||
export * from "./form-url-params";
|
||||
|
||||
export * from "./auth";
|
||||
|
||||
export * from "./bindings";
|
||||
|
||||
export * from "./prettify";
|
||||
|
||||
export * from "./autoSave";
|
||||
|
||||
export * from "./textTransformers";
|
||||
|
||||
export * from "./optimistic-update-map";
|
||||
14
packages/core/src/interfaces/live/LiveEvent.ts
Normal file
14
packages/core/src/interfaces/live/LiveEvent.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { BaseKey, MetaQuery } from "..";
|
||||
|
||||
export type LiveEvent = {
|
||||
channel: string;
|
||||
type: "deleted" | "updated" | "created" | "*" | string;
|
||||
payload: {
|
||||
ids?: BaseKey[];
|
||||
[x: string]: any;
|
||||
};
|
||||
date: Date;
|
||||
meta?: MetaQuery & {
|
||||
dataProviderName?: string;
|
||||
};
|
||||
};
|
||||
28
packages/core/src/interfaces/live/LiveModeProps.ts
Normal file
28
packages/core/src/interfaces/live/LiveModeProps.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { LiveEvent } from ".";
|
||||
import { BaseKey } from "..";
|
||||
|
||||
export type LiveModeProps = {
|
||||
/**
|
||||
* Whether to update data automatically ("auto") or not ("manual") if a related live event is received. The "off" value is used to avoid creating a subscription.
|
||||
* @type [`"auto" | "manual" | "off"`](/docs/api-reference/core/providers/live-provider/#livemode)
|
||||
* @default `"off"`
|
||||
*/
|
||||
liveMode?: "auto" | "manual" | "off";
|
||||
/**
|
||||
* Callback to handle all related live events of this hook.
|
||||
* @type [`(event: LiveEvent) => void`](/docs/api-reference/core/interfaceReferences/#livemodeprops)
|
||||
* @default `undefined`
|
||||
*/
|
||||
onLiveEvent?: (event: LiveEvent) => void;
|
||||
/**
|
||||
* Params to pass to liveProvider's subscribe method if liveMode is enabled.
|
||||
* @type [`{ ids?: BaseKey[]; [key: string]: any; }`](/docs/api-reference/core/interfaceReferences/#livemodeprops)
|
||||
* @default `undefined`
|
||||
*/
|
||||
liveParams?: {
|
||||
ids?: BaseKey[];
|
||||
[key: string]: any;
|
||||
};
|
||||
};
|
||||
|
||||
export type ILiveModeContextProvider = LiveModeProps;
|
||||
2
packages/core/src/interfaces/live/index.ts
Normal file
2
packages/core/src/interfaces/live/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from "./LiveEvent";
|
||||
export * from "./LiveModeProps";
|
||||
3
packages/core/src/interfaces/mapDataFn.ts
Normal file
3
packages/core/src/interfaces/mapDataFn.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export interface MapDataFn<TItem, TVariables> {
|
||||
(item: TItem, index?: number, items?: TItem[]): TVariables;
|
||||
}
|
||||
3
packages/core/src/interfaces/metaData/fields.ts
Normal file
3
packages/core/src/interfaces/metaData/fields.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { NestedField } from "./nestedField";
|
||||
|
||||
export type Fields = Array<string | object | NestedField>;
|
||||
53
packages/core/src/interfaces/metaData/graphqlQueryOptions.ts
Normal file
53
packages/core/src/interfaces/metaData/graphqlQueryOptions.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import type { DocumentNode } from "graphql";
|
||||
|
||||
export type GraphQLQueryOptions = {
|
||||
/**
|
||||
* @description GraphQL query to be used by data providers.
|
||||
* @optional
|
||||
* @example
|
||||
* ```tsx
|
||||
* import gql from 'graphql-tag'
|
||||
* import { useOne } from '@refinedev/core'
|
||||
*
|
||||
* const PRODUCT_QUERY = gql`
|
||||
* query GetProduct($id: ID!) {
|
||||
* product(id: $id) {
|
||||
* id
|
||||
* name
|
||||
* }
|
||||
* }
|
||||
* `
|
||||
*
|
||||
* useOne({
|
||||
* id: 1,
|
||||
* meta: { gqlQuery: PRODUCT_QUERY }
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
gqlQuery?: DocumentNode;
|
||||
/**
|
||||
* @description GraphQL mutation to be used by data providers.
|
||||
* @optional
|
||||
* @example
|
||||
* ```tsx
|
||||
* import gql from 'graphql-tag'
|
||||
* import { useCreate } from '@refinedev/core'
|
||||
*
|
||||
* const PRODUCT_CREATE_MUTATION = gql`
|
||||
* mutation CreateProduct($input: CreateOneProductInput!) {
|
||||
* createProduct(input: $input) {
|
||||
* id
|
||||
* name
|
||||
* }
|
||||
* }
|
||||
* `
|
||||
* const { mutate } = useCreate()
|
||||
*
|
||||
* mutate({
|
||||
* values: { name: "My Product" },
|
||||
* meta: { gqlQuery: PRODUCT_QUERY }
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
gqlMutation?: DocumentNode;
|
||||
};
|
||||
2
packages/core/src/interfaces/metaData/index.ts
Normal file
2
packages/core/src/interfaces/metaData/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from "./metaDataQuery";
|
||||
export * from "./metaQuery";
|
||||
10
packages/core/src/interfaces/metaData/metaDataQuery.ts
Normal file
10
packages/core/src/interfaces/metaData/metaDataQuery.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { QueryFunctionContext } from "@tanstack/react-query";
|
||||
import { QueryBuilderOptions } from "./queryBuilderOptions";
|
||||
|
||||
/**
|
||||
* @deprecated `MetaDataQuery` is deprecated with refine@4, use `MetaQuery` instead, however, we still support `MetaDataQuery` for backward compatibility.
|
||||
*/
|
||||
export type MetaDataQuery = {
|
||||
[k: string]: any;
|
||||
queryContext?: Omit<QueryFunctionContext, "meta">;
|
||||
} & QueryBuilderOptions;
|
||||
9
packages/core/src/interfaces/metaData/metaQuery.ts
Normal file
9
packages/core/src/interfaces/metaData/metaQuery.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { QueryFunctionContext } from "@tanstack/react-query";
|
||||
import { QueryBuilderOptions } from "./queryBuilderOptions";
|
||||
import { GraphQLQueryOptions } from "./graphqlQueryOptions";
|
||||
|
||||
export type MetaQuery = {
|
||||
[k: string]: any;
|
||||
queryContext?: Omit<QueryFunctionContext, "meta">;
|
||||
} & QueryBuilderOptions &
|
||||
GraphQLQueryOptions;
|
||||
8
packages/core/src/interfaces/metaData/nestedField.ts
Normal file
8
packages/core/src/interfaces/metaData/nestedField.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { Fields } from "./fields";
|
||||
import { QueryBuilderOptions } from "./queryBuilderOptions";
|
||||
|
||||
export type NestedField = {
|
||||
operation: string;
|
||||
variables: QueryBuilderOptions[];
|
||||
fields: Fields;
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
import { VariableOptions } from "./variableOptions";
|
||||
import { Fields } from "./fields";
|
||||
|
||||
export interface QueryBuilderOptions {
|
||||
operation?: string;
|
||||
fields?: Fields;
|
||||
variables?: VariableOptions;
|
||||
}
|
||||
9
packages/core/src/interfaces/metaData/variableOptions.ts
Normal file
9
packages/core/src/interfaces/metaData/variableOptions.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
export type VariableOptions =
|
||||
| {
|
||||
type?: string;
|
||||
name?: string;
|
||||
value: any;
|
||||
list?: boolean;
|
||||
required?: boolean;
|
||||
}
|
||||
| { [k: string]: any };
|
||||
32
packages/core/src/interfaces/mutationMode.ts
Normal file
32
packages/core/src/interfaces/mutationMode.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import {
|
||||
BaseRecord,
|
||||
GetListResponse,
|
||||
GetOneResponse,
|
||||
IQueryKeys,
|
||||
} from "../interfaces";
|
||||
import { QueryKey } from "@tanstack/react-query";
|
||||
|
||||
export type MutationMode = "pessimistic" | "optimistic" | "undoable";
|
||||
|
||||
export type QueryResponse<T = BaseRecord> =
|
||||
| GetListResponse<T>
|
||||
| GetOneResponse<T>;
|
||||
|
||||
export type PreviousQuery<TData> = [QueryKey, TData | unknown];
|
||||
|
||||
export type PrevContext<TData> = {
|
||||
previousQueries: PreviousQuery<TData>[];
|
||||
/**
|
||||
* @deprecated `QueryKeys` is deprecated in favor of `keys`. Please use `keys` instead to construct query keys for queries and mutations.
|
||||
*/
|
||||
queryKey: IQueryKeys;
|
||||
};
|
||||
|
||||
export type Context = {
|
||||
previousQueries: ContextQuery[];
|
||||
};
|
||||
|
||||
export type ContextQuery<T = BaseRecord> = {
|
||||
query: QueryResponse<T>;
|
||||
queryKey: QueryKey;
|
||||
};
|
||||
10
packages/core/src/interfaces/notification.ts
Normal file
10
packages/core/src/interfaces/notification.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { BaseKey } from ".";
|
||||
export interface IUndoableQueue {
|
||||
id: BaseKey;
|
||||
resource: string;
|
||||
cancelMutation: () => void;
|
||||
doMutation: () => void;
|
||||
seconds: number;
|
||||
isRunning: boolean;
|
||||
isSilent: boolean;
|
||||
}
|
||||
49
packages/core/src/interfaces/optimistic-update-map.ts
Normal file
49
packages/core/src/interfaces/optimistic-update-map.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { BaseKey, GetListResponse, GetManyResponse, GetOneResponse } from ".";
|
||||
|
||||
export type OptimisticUpdateMapType<TData, TVariables> = {
|
||||
list?:
|
||||
| ((
|
||||
previous: GetListResponse<TData> | null | undefined,
|
||||
values: TVariables,
|
||||
id: BaseKey,
|
||||
) => GetListResponse<TData> | null)
|
||||
| boolean;
|
||||
many?:
|
||||
| ((
|
||||
previous: GetManyResponse<TData> | null | undefined,
|
||||
values: TVariables,
|
||||
id: BaseKey,
|
||||
) => GetManyResponse<TData> | null)
|
||||
| boolean;
|
||||
detail?:
|
||||
| ((
|
||||
previous: GetOneResponse<TData> | null | undefined,
|
||||
values: TVariables,
|
||||
id: BaseKey,
|
||||
) => GetOneResponse<TData> | null)
|
||||
| boolean;
|
||||
};
|
||||
|
||||
export type OptimisticUpdateManyMapType<TData, TVariables> = {
|
||||
list?:
|
||||
| ((
|
||||
previous: GetListResponse<TData> | null | undefined,
|
||||
values: TVariables,
|
||||
ids: BaseKey[],
|
||||
) => GetListResponse<TData> | null)
|
||||
| boolean;
|
||||
many?:
|
||||
| ((
|
||||
previous: GetManyResponse<TData> | null | undefined,
|
||||
values: TVariables,
|
||||
ids: BaseKey[],
|
||||
) => GetManyResponse<TData> | null)
|
||||
| boolean;
|
||||
detail?:
|
||||
| ((
|
||||
previous: GetOneResponse<TData> | null | undefined,
|
||||
values: TVariables,
|
||||
id: BaseKey,
|
||||
) => GetOneResponse<TData> | null)
|
||||
| boolean;
|
||||
};
|
||||
3
packages/core/src/interfaces/prettify.ts
Normal file
3
packages/core/src/interfaces/prettify.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export type Prettify<T> = {
|
||||
[K in keyof T]: T[K];
|
||||
} & {};
|
||||
23
packages/core/src/interfaces/queryKey.ts
Normal file
23
packages/core/src/interfaces/queryKey.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { QueryKey } from "@tanstack/react-query";
|
||||
|
||||
import { UseListConfig } from "@hooks/data/useList";
|
||||
import { BaseKey, CrudFilters, CrudSorting, Pagination } from "src/interfaces";
|
||||
|
||||
export interface IQueryKeys {
|
||||
all: QueryKey;
|
||||
resourceAll: QueryKey;
|
||||
list: (
|
||||
config?:
|
||||
| UseListConfig
|
||||
| {
|
||||
pagination?: Required<Pagination>;
|
||||
hasPagination?: boolean;
|
||||
sorters?: CrudSorting;
|
||||
filters?: CrudFilters;
|
||||
}
|
||||
| undefined,
|
||||
) => QueryKey;
|
||||
many: (ids?: BaseKey[]) => QueryKey;
|
||||
detail: (id?: BaseKey) => QueryKey;
|
||||
logList: (meta?: Record<number | string, any>) => QueryKey;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import { ActionWithPage } from "./actions";
|
||||
|
||||
export type ResourceErrorRouterParams = {
|
||||
resource: string;
|
||||
action: ActionWithPage | undefined;
|
||||
};
|
||||
7
packages/core/src/interfaces/resourceRouterParams.ts
Normal file
7
packages/core/src/interfaces/resourceRouterParams.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { RouteAction } from "./actions";
|
||||
|
||||
export type ResourceRouterParams = {
|
||||
resource: string;
|
||||
id?: string;
|
||||
action: RouteAction;
|
||||
};
|
||||
33
packages/core/src/interfaces/successErrorNotification.ts
Normal file
33
packages/core/src/interfaces/successErrorNotification.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { OpenNotificationParams } from ".";
|
||||
|
||||
export type SuccessErrorNotification<
|
||||
TData = unknown,
|
||||
TError = unknown,
|
||||
TVariables = unknown,
|
||||
> = {
|
||||
/**
|
||||
* Success notification configuration to be displayed when the mutation is successful.
|
||||
* @default '"There was an error creating resource (status code: `statusCode`)" or "Error when updating resource (status code: statusCode)"'
|
||||
|
||||
*/
|
||||
successNotification?:
|
||||
| OpenNotificationParams
|
||||
| false
|
||||
| ((
|
||||
data?: TData,
|
||||
values?: TVariables,
|
||||
resource?: string,
|
||||
) => OpenNotificationParams | false);
|
||||
/**
|
||||
* Error notification configuration to be displayed when the mutation fails.
|
||||
* @default '"There was an error creating resource (status code: `statusCode`)" or "Error when updating resource (status code: statusCode)"'
|
||||
*/
|
||||
errorNotification?:
|
||||
| OpenNotificationParams
|
||||
| false
|
||||
| ((
|
||||
error?: TError,
|
||||
values?: TVariables,
|
||||
resource?: string,
|
||||
) => OpenNotificationParams | false);
|
||||
};
|
||||
15
packages/core/src/interfaces/telemetry.ts
Normal file
15
packages/core/src/interfaces/telemetry.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
export type ITelemetryData = {
|
||||
providers: {
|
||||
auth?: boolean;
|
||||
data?: boolean;
|
||||
router?: boolean;
|
||||
notification?: boolean;
|
||||
live?: boolean;
|
||||
auditLog?: boolean;
|
||||
i18n?: boolean;
|
||||
accessControl?: boolean;
|
||||
};
|
||||
version: string;
|
||||
resourceCount: number;
|
||||
projectId?: string;
|
||||
};
|
||||
20
packages/core/src/interfaces/textTransformers.ts
Normal file
20
packages/core/src/interfaces/textTransformers.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
export type TextTransformers = {
|
||||
/**
|
||||
* Convert a camelized/dasherized/underscored string into a humanized one
|
||||
* @example
|
||||
* humanize("some_name") => "Some name"
|
||||
*/
|
||||
humanize?: (text: string) => string;
|
||||
/**
|
||||
* Pluralize a word
|
||||
* @example
|
||||
* plural('regex') => "regexes"
|
||||
*/
|
||||
plural?: (word: string) => string;
|
||||
/**
|
||||
* Singularize a word
|
||||
* @example
|
||||
* singular('singles') => "single"
|
||||
*/
|
||||
singular?: (word: string) => string;
|
||||
};
|
||||
Reference in New Issue
Block a user