react-admin-base-bootstrap 0.7.8 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/lib/esm/Components/ApiSelect.d.ts +19 -1
  2. package/lib/esm/Components/ApiSelect.js +3 -1
  3. package/lib/esm/Components/BootstrapDataTable.d.ts +24 -7
  4. package/lib/esm/Components/BootstrapDataTable.js +37 -29
  5. package/lib/esm/Components/CRUD.d.ts +7 -1
  6. package/lib/esm/Components/CRUD.js +2 -2
  7. package/lib/esm/Components/CheckBox.d.ts +10 -1
  8. package/lib/esm/Components/CheckBox.js +1 -1
  9. package/lib/esm/Components/DefaultValidatorOptions.d.ts +6 -3
  10. package/lib/esm/Components/ExternalLoginButton.d.ts +8 -6
  11. package/lib/esm/Components/FilePickerCore.d.ts +5 -3
  12. package/lib/esm/Components/FilePickerCore.js +4 -4
  13. package/lib/esm/Components/ImagePicker.d.ts +9 -1
  14. package/lib/esm/Components/LanguageProvider.d.ts +8 -5
  15. package/lib/esm/Components/LoadingButton.d.ts +2 -1
  16. package/lib/esm/Components/MenuState.d.ts +1 -1
  17. package/lib/esm/Components/SingleFilePicker.d.ts +2 -3
  18. package/lib/esm/Components/StepList.d.ts +14 -2
  19. package/lib/esm/Components/TopProgressBar.d.ts +6 -3
  20. package/lib/esm/Components/Validator.d.ts +1 -1
  21. package/lib/esm/index.d.ts +2 -2
  22. package/lib/esm/index.js +2 -2
  23. package/package.json +13 -13
  24. package/src/Components/ApiSelect.tsx +31 -11
  25. package/src/Components/BootstrapDataTable.tsx +80 -44
  26. package/src/Components/CRUD.tsx +10 -4
  27. package/src/Components/CheckBox.tsx +10 -3
  28. package/src/Components/DefaultValidatorOptions.tsx +5 -1
  29. package/src/Components/ExcelExportButton.tsx +5 -3
  30. package/src/Components/ExternalLoginButton.tsx +8 -1
  31. package/src/Components/FilePickerCore.tsx +9 -5
  32. package/src/Components/ImagePicker.tsx +4 -4
  33. package/src/Components/LanguageProvider.tsx +8 -1
  34. package/src/Components/LoadingButton.tsx +2 -2
  35. package/src/Components/SingleFilePicker.tsx +4 -4
  36. package/src/Components/StepList.tsx +14 -2
  37. package/src/Components/TopProgressBar.tsx +6 -2
  38. package/src/Components/Validator.tsx +5 -5
  39. package/src/index.ts +2 -1
@@ -1,3 +1,21 @@
1
1
  /** @jsx jsx */
2
2
  import { jsx } from '@emotion/react';
3
- export default function ApiSelect(props: any): jsx.JSX.Element;
3
+ import React from 'react';
4
+ export interface ApiSelectProps<Option = any> {
5
+ url?: string;
6
+ value: Option | Option[];
7
+ onChange: (a: Option | Option[] | null) => void;
8
+ getOptionLabel?: (a: any) => string;
9
+ getOptionValue?: (a: any) => string;
10
+ onCreateOption?: (a: string) => Option | Promise<Option>;
11
+ filter?: (a: Option) => boolean;
12
+ group?: (a: Option[]) => any[];
13
+ isMulti?: boolean;
14
+ idKey?: string;
15
+ nameKey?: string;
16
+ disabled?: boolean;
17
+ placeholder?: string;
18
+ staticOptions?: any[];
19
+ getNewOptionData?: (name: string, elem: React.ReactNode) => any | null;
20
+ }
21
+ export default function ApiSelect<Option = any>(props: ApiSelectProps<Option>): jsx.JSX.Element;
@@ -55,6 +55,8 @@ export default function ApiSelect(props) {
55
55
  }
56
56
  const handleCreateOption = useCallback(function (input) {
57
57
  return __awaiter(this, void 0, void 0, function* () {
58
+ if (!onCreateOption)
59
+ return null;
58
60
  setCreating(true);
59
61
  try {
60
62
  let option = yield onCreateOption(input);
@@ -78,5 +80,5 @@ export default function ApiSelect(props) {
78
80
  setIsMenuOpen(false);
79
81
  }, [setIsMenuOpen]);
80
82
  const Component = onCreateOption ? CreatableSelect : Select;
81
- return jsx(Component, Object.assign({}, props, { className: 'react-select-container', classNamePrefix: "react-select", onCreateOption: (onCreateOption && handleCreateOption) || null, getNewOptionData: onCreateOption ? getNewOptionData ? getNewOptionData : (inputValue) => ({ [nameKey || 'name']: inputValue, __isNew__: true }) : null, inputValue: search, onInputChange: a => setSearch(a), components: Components, isLoading: !!loading || creating, getOptionLabel: getOptionLabel || ((row) => row[nameKey || 'name']), getOptionValue: getOptionValue || ((row) => row[idKey || 'id']), isDisabled: !!disabled || creating, isClearable: true, isSearchable: true, placeholder: placeholder || intl.formatMessage({ id: 'SELECT' }), options: !options ? [] : ((filter && options.filter(filter)) || options), isMenuOpen: isMenuOpen, onMenuOpen: onMenuOpen, onMenuClose: onMenuClose }));
83
+ return jsx(Component, Object.assign({}, props, { className: 'react-select-container', classNamePrefix: "react-select", onCreateOption: onCreateOption && handleCreateOption, getNewOptionData: (onCreateOption && (getNewOptionData || ((inputValue) => ({ [nameKey || 'name']: inputValue, __isNew__: true })))) || undefined, inputValue: search, onInputChange: a => setSearch(a), components: Components, isLoading: !!loading || creating, getOptionLabel: getOptionLabel || ((row) => row[nameKey || 'name']), getOptionValue: getOptionValue || ((row) => row[idKey || 'id']), isDisabled: !!disabled || creating, isClearable: true, isSearchable: true, placeholder: placeholder || intl.formatMessage({ id: 'SELECT' }), options: !options ? [] : ((filter && options.filter(filter)) || options), onMenuOpen: onMenuOpen, onMenuClose: onMenuClose }));
82
84
  }
@@ -1,11 +1,28 @@
1
+ import React from 'react';
1
2
  export declare function useDataTableContext(): any;
2
- export declare function Actions({ edit, del, rowSpan, children }: {
3
- edit: any;
4
- del: any;
5
- rowSpan?: any;
6
- children?: any;
7
- }): JSX.Element;
3
+ declare type ActionsProp = {
4
+ edit?: string;
5
+ del?: string;
6
+ rowSpan?: number | undefined;
7
+ children?: React.ReactNode;
8
+ };
9
+ export declare function Actions({ edit, del, rowSpan, children }: ActionsProp): JSX.Element;
8
10
  export declare function IdColumn(): JSX.Element;
9
11
  export declare function ActionsColumn(): JSX.Element;
10
12
  export declare function Column(props: any): JSX.Element;
11
- export default function BootstrapTable({ url, bordered, noStrip, defaultParams, add, children, innerRef, body }: any): JSX.Element;
13
+ export interface BootstrapTableProps {
14
+ url: string;
15
+ bordered?: boolean;
16
+ noStrip?: boolean;
17
+ defaultParams?: any;
18
+ body?: any;
19
+ add?: string;
20
+ children: any;
21
+ innerRef?: any;
22
+ }
23
+ interface RowRendererProps<Row = any> {
24
+ render: (row: Row) => React.ReactNode;
25
+ }
26
+ export declare function RowRenderer<Row = any>({ render }: RowRendererProps<Row>): JSX.Element;
27
+ export default function BootstrapTable({ url, bordered, noStrip, defaultParams, add, children, innerRef, body }: BootstrapTableProps): JSX.Element;
28
+ export {};
@@ -15,6 +15,8 @@ import { Alert, Button, Card, CardFooter, CardHeader, Col, Input, Row, Table } f
15
15
  import Swal from 'sweetalert2';
16
16
  import BootstrapPagination from "./BootstrapPagination";
17
17
  const DataTableContext = React.createContext(null);
18
+ const RowDatasContext = React.createContext(null);
19
+ const RowDataContext = React.createContext(null);
18
20
  export function useDataTableContext() {
19
21
  return useContext(DataTableContext);
20
22
  }
@@ -74,13 +76,18 @@ export function Column(props) {
74
76
  React.createElement("i", { className: "fa fa-sort-down" }) :
75
77
  React.createElement("i", { className: "fa fa-sort-up" }) : '');
76
78
  }
79
+ export function RowRenderer({ render }) {
80
+ const rows = useContext(RowDatasContext);
81
+ return React.createElement("tbody", null, rows.map(render));
82
+ }
77
83
  export default function BootstrapTable({ url, bordered, noStrip, defaultParams, add, children, innerRef, body }) {
78
- var state = useState(Object.assign({ sort: 'id' }, defaultParams));
84
+ const state = useState(Object.assign({ sort: 'id' }, defaultParams));
79
85
  const [params, setParams] = state;
80
86
  const [page, lastPage, setPage, data, itemPerPage, setItemPerPage, update] = useDataTable(url, params, body);
81
87
  const intl = useIntl();
82
88
  const [api] = useAuth();
83
- var ref = useRef(defaultParams);
89
+ console.log(children[1]);
90
+ const ref = useRef(defaultParams);
84
91
  useEffect(function () {
85
92
  if (ref.current !== defaultParams) {
86
93
  ref.current = defaultParams;
@@ -109,31 +116,32 @@ export default function BootstrapTable({ url, bordered, noStrip, defaultParams,
109
116
  React.createElement(DataTableContext.Provider, { value: state },
110
117
  React.createElement(DataContextProvider, { value: fetchData },
111
118
  React.createElement(RefreshScope, { update: update },
112
- React.createElement(CardHeader, null,
113
- React.createElement(Row, null,
114
- add && React.createElement(Col, { xs: "12", md: "2" },
115
- React.createElement(Link, { to: add, className: "btn btn-primary font-xl d-block" },
116
- React.createElement("i", { className: "fa fa-plus" }))),
117
- React.createElement(Col, { md: "2" },
118
- React.createElement(Input, { type: "select", value: itemPerPage.toString(), onChange: a => setItemPerPage(+a.currentTarget.value) },
119
- React.createElement("option", { value: "1" }, "1"),
120
- React.createElement("option", { value: "20" }, "20"),
121
- React.createElement("option", { value: "50" }, "50"),
122
- React.createElement("option", { value: "100" }, "100"),
123
- React.createElement("option", { value: "150" }, "150"),
124
- React.createElement("option", { value: "200" }, "200"),
125
- React.createElement("option", { value: "-1" }, intl.formatMessage({ id: "ALL" })))),
126
- children[2],
127
- React.createElement(Col, { md: "3", className: "ms-auto" },
128
- React.createElement(Input, { placeholder: intl.formatMessage({ id: "SEARCH" }), type: "text", value: params.query || '', onChange: e => setParams(Object.assign(Object.assign({}, params), { query: e.currentTarget.value })) })))),
129
- data === null ? React.createElement(Alert, { className: "text-center mb-0 mx-3 ", color: "warning" },
130
- React.createElement("i", { className: "fas fa-spinner fa-spin" })) : !data.length ? React.createElement(Alert, { className: "text-center mx-3", color: "danger" },
131
- React.createElement("i", { className: "far fa-times-circle" }),
132
- " ",
133
- React.createElement(FormattedMessage, { id: "NO_DATA_IS_AVAILABLE" })) : React.createElement(Table, { hover: true, bordered: bordered, striped: !noStrip, responsive: true, size: "md", className: "mb-0 dataTable" },
134
- children[0],
135
- React.createElement("tbody", null, data && data.map(children[1].props.children))),
136
- lastPage > 1 && React.createElement(CardFooter, null,
137
- React.createElement("nav", null,
138
- React.createElement(BootstrapPagination, { currentPage: page, pageCount: lastPage, onPageChange: index => setPage(index) })))))));
119
+ React.createElement(RowDatasContext.Provider, { value: data },
120
+ React.createElement(CardHeader, null,
121
+ React.createElement(Row, null,
122
+ add && React.createElement(Col, { xs: "12", md: "2" },
123
+ React.createElement(Link, { to: add, className: "btn btn-primary font-xl d-block" },
124
+ React.createElement("i", { className: "fa fa-plus" }))),
125
+ React.createElement(Col, { md: "2" },
126
+ React.createElement(Input, { type: "select", value: itemPerPage.toString(), onChange: a => setItemPerPage(+a.currentTarget.value) },
127
+ React.createElement("option", { value: "1" }, "1"),
128
+ React.createElement("option", { value: "20" }, "20"),
129
+ React.createElement("option", { value: "50" }, "50"),
130
+ React.createElement("option", { value: "100" }, "100"),
131
+ React.createElement("option", { value: "150" }, "150"),
132
+ React.createElement("option", { value: "200" }, "200"),
133
+ React.createElement("option", { value: "-1" }, intl.formatMessage({ id: "ALL" })))),
134
+ children[2],
135
+ React.createElement(Col, { md: "3", className: "ms-auto" },
136
+ React.createElement(Input, { placeholder: intl.formatMessage({ id: "SEARCH" }), type: "text", value: params.query || '', onChange: e => setParams(Object.assign(Object.assign({}, params), { query: e.currentTarget.value })) })))),
137
+ data === null ? React.createElement(Alert, { className: "text-center mb-0 mx-3 ", color: "warning" },
138
+ React.createElement("i", { className: "fas fa-spinner fa-spin" })) : !data.length ? React.createElement(Alert, { className: "text-center mx-3", color: "danger" },
139
+ React.createElement("i", { className: "far fa-times-circle" }),
140
+ " ",
141
+ React.createElement(FormattedMessage, { id: "NO_DATA_IS_AVAILABLE" })) : React.createElement(Table, { hover: true, bordered: bordered, striped: !noStrip, responsive: true, size: "md", className: "mb-0 dataTable" },
142
+ children[0],
143
+ children[1].type === "tbody" ? React.createElement("tbody", null, data && data.map(children[1].props.children)) : children[1]),
144
+ lastPage > 1 && React.createElement(CardFooter, null,
145
+ React.createElement("nav", null,
146
+ React.createElement(BootstrapPagination, { currentPage: page, pageCount: lastPage, onPageChange: index => setPage(index) }))))))));
139
147
  }
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import { BootstrapTableProps } from './BootstrapDataTable';
2
3
  declare type ModalEntityEditorParams = {
3
4
  entity: any;
4
5
  title?: string;
@@ -16,5 +17,10 @@ declare type CrudActionProps = {
16
17
  children?: React.ReactNode;
17
18
  };
18
19
  export declare function CRUDActions({ id, edit, del, children }: CrudActionProps): JSX.Element;
19
- export default function CRUD(props: any): JSX.Element;
20
+ interface CRUDProps extends BootstrapTableProps {
21
+ apiUrl?: string;
22
+ Component: any;
23
+ noAdd?: boolean;
24
+ }
25
+ export default function CRUD(props: CRUDProps): JSX.Element;
20
26
  export {};
@@ -92,7 +92,7 @@ function ComponentWrapper(_a) {
92
92
  export default function CRUD(props) {
93
93
  const ref = useRef(null);
94
94
  const { url, apiUrl, Component, defaultParams, noAdd } = props;
95
- var reload = useCallback(function () {
95
+ const reload = useCallback(function () {
96
96
  return __awaiter(this, void 0, void 0, function* () {
97
97
  if (ref.current) {
98
98
  ref.current({});
@@ -103,5 +103,5 @@ export default function CRUD(props) {
103
103
  React.createElement(Routes, null,
104
104
  !noAdd && React.createElement(Route, { path: "create", element: React.createElement(ComponentWrapper, Object.assign({ Component: Component, url: url, onReload: reload }, (defaultParams || {}))) }),
105
105
  React.createElement(Route, { path: ":id/edit", element: React.createElement(ComponentWrapper, Object.assign({ Component: Component, url: url, onReload: reload }, (defaultParams || {}))) })),
106
- React.createElement(BootstrapDataTable, Object.assign({ innerRef: ref, add: !noAdd && "create" }, props, { url: apiUrl || url })));
106
+ React.createElement(BootstrapDataTable, Object.assign({ innerRef: ref, add: (!noAdd && "create") || undefined }, props, { url: apiUrl || url })));
107
107
  }
@@ -1 +1,10 @@
1
- export default function CheckBox(props: any): JSX.Element;
1
+ import React from "react";
2
+ import { InputProps } from "reactstrap";
3
+ interface CheckBoxProps extends InputProps {
4
+ id: string;
5
+ type?: "checkbox" | "radio";
6
+ label?: React.ReactNode;
7
+ children: React.ReactNode;
8
+ }
9
+ export default function CheckBox(props: CheckBoxProps): JSX.Element;
10
+ export {};
@@ -2,6 +2,6 @@ import React from "react";
2
2
  import { FormGroup, Input, Label } from "reactstrap";
3
3
  export default function CheckBox(props) {
4
4
  return React.createElement(FormGroup, { check: true },
5
- React.createElement(Input, Object.assign({ type: props.type || "checkbox" }, props, { label: undefined })),
5
+ React.createElement(Input, Object.assign({ type: props.type || "checkbox" }, props, { children: undefined, label: undefined })),
6
6
  React.createElement(Label, { check: true, for: props.id }, props.children || props.label));
7
7
  }
@@ -1,3 +1,6 @@
1
- export default function DefaultValidatorOptions({ children }: {
2
- children: any;
3
- }): JSX.Element;
1
+ import React from "react";
2
+ declare type DefaultValidatorOptionsProps = {
3
+ children: React.ReactNode;
4
+ };
5
+ export default function DefaultValidatorOptions({ children }: DefaultValidatorOptionsProps): JSX.Element;
6
+ export {};
@@ -1,6 +1,8 @@
1
- export default function ExternalLoginButton({ id, icon, name, url }: {
2
- id: any;
3
- icon: any;
4
- name: any;
5
- url: any;
6
- }): JSX.Element;
1
+ declare type ExternalLoginButtonProps = {
2
+ id: string;
3
+ icon?: string;
4
+ name: string;
5
+ url: string;
6
+ };
7
+ export default function ExternalLoginButton({ id, icon, name, url }: ExternalLoginButtonProps): JSX.Element;
8
+ export {};
@@ -1,7 +1,8 @@
1
1
  import React from 'react';
2
- export declare function Relative({ children }: {
3
- children: any;
4
- }): React.ReactSVGElement | null;
2
+ declare type RelativeProps = {
3
+ children: JSX.Element;
4
+ };
5
+ export declare function Relative({ children }: RelativeProps): React.FunctionComponentElement<any> | null;
5
6
  export declare function Preview({ value }: {
6
7
  value: any;
7
8
  }): JSX.Element | null;
@@ -14,3 +15,4 @@ export default function FilePickerCore({ disabled, className, accepts, value, on
14
15
  children?: any;
15
16
  transform?: any;
16
17
  }): JSX.Element | null;
18
+ export {};
@@ -3,14 +3,14 @@ import prettysize from 'prettysize';
3
3
  import { Button } from "reactstrap";
4
4
  import { useApp, useFilePicker, usePreviewComponent } from "react-admin-base";
5
5
  import { FormattedMessage } from "react-intl";
6
- var photo_ext = ["png", "jpg", "jpeg", "svg"];
6
+ const photo_ext = ["png", "jpg", "jpeg", "svg"];
7
7
  function is_photo(name) {
8
8
  return photo_ext.indexOf(name.split('.')[1]) !== -1;
9
9
  }
10
10
  function is_absolute(url) {
11
11
  if (url.indexOf("blob:") === 0)
12
12
  return false;
13
- var pat = /^https?:\/\//i;
13
+ const pat = /^https?:\/\//i;
14
14
  return !pat.test(url);
15
15
  }
16
16
  export function Relative({ children }) {
@@ -24,8 +24,8 @@ export function Relative({ children }) {
24
24
  });
25
25
  }
26
26
  export function Preview({ value }) {
27
- var name = value.$name;
28
- var src = value.$blob_url || value.$src;
27
+ const name = value.$name;
28
+ const src = value.$blob_url || value.$src;
29
29
  if (is_photo(name)) {
30
30
  return React.createElement("div", { className: "mt-2" },
31
31
  React.createElement(Relative, null,
@@ -1 +1,9 @@
1
- export default function ImagePicker(props: any): JSX.Element;
1
+ import { SingleFilePickerProps } from './SingleFilePicker';
2
+ interface ImagePickerProps extends SingleFilePickerProps {
3
+ width: number;
4
+ height: number;
5
+ type: string;
6
+ exact?: boolean;
7
+ }
8
+ export default function ImagePicker(props: ImagePickerProps): JSX.Element;
9
+ export {};
@@ -1,8 +1,11 @@
1
+ import React from 'react';
1
2
  export declare function useLanguage(): any;
2
- export default function LanguageProvider({ defaultLanguage, languages, loader, children }: {
3
- defaultLanguage: any;
3
+ declare type LanguageProviderProps = {
4
+ defaultLanguage: string;
4
5
  languages: any;
5
- loader: any;
6
- children: any;
7
- }): JSX.Element | null;
6
+ loader?: (language: any) => any;
7
+ children: React.ReactNode;
8
+ };
9
+ export default function LanguageProvider({ defaultLanguage, languages, loader, children }: LanguageProviderProps): JSX.Element | null;
8
10
  export declare function LanguageSwitcher(): JSX.Element | null;
11
+ export {};
@@ -1 +1,2 @@
1
- export default function LoadingButton(props: any): JSX.Element;
1
+ import { ButtonProps } from 'reactstrap';
2
+ export default function LoadingButton(props: ButtonProps): JSX.Element;
@@ -1,3 +1,3 @@
1
1
  /// <reference types="react" />
2
- export declare function useIsMobile(): any;
2
+ export declare function useIsMobile(): boolean;
3
3
  export declare function useMenuState(): [boolean, import("react").DispatchWithoutAction];
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- declare type SingleFilePickerProps = {
2
+ export interface SingleFilePickerProps {
3
3
  disabled?: boolean;
4
4
  className?: string;
5
5
  accepts?: string;
@@ -7,6 +7,5 @@ declare type SingleFilePickerProps = {
7
7
  onChange: (value: any) => void;
8
8
  children?: (value: any) => React.ReactNode;
9
9
  transform?: any;
10
- };
10
+ }
11
11
  export default function SingleFilePicker({ disabled, className, accepts, value, onChange, transform, children }: SingleFilePickerProps): JSX.Element;
12
- export {};
@@ -1,2 +1,14 @@
1
- export default function StepList({ active, setActive, children }: any): JSX.Element;
2
- export declare function StepItem({ title, translate, disabled }: any): JSX.Element;
1
+ import React from "react";
2
+ declare type StepListProps = {
3
+ active: number;
4
+ setActive: (active: number) => {};
5
+ children: React.ReactNode;
6
+ };
7
+ export default function StepList({ active, setActive, children }: StepListProps): JSX.Element;
8
+ declare type StepItemProps = {
9
+ title?: string;
10
+ translate?: string;
11
+ disabled?: boolean;
12
+ };
13
+ export declare function StepItem({ title, translate, disabled }: StepItemProps): JSX.Element;
14
+ export {};
@@ -1,3 +1,6 @@
1
- export default function TopProgressBar({ children }: {
2
- children: any;
3
- }): any;
1
+ import React from 'react';
2
+ declare type TopProgressBarProps = {
3
+ children: React.ReactNode;
4
+ };
5
+ export default function TopProgressBar({ children }: TopProgressBarProps): React.ReactNode;
6
+ export {};
@@ -1,7 +1,7 @@
1
1
  declare type ValidatorProps = {
2
2
  name: string;
3
3
  type: any;
4
- children: any;
4
+ children: JSX.Element;
5
5
  };
6
6
  export declare function Validator({ name, type, children }: ValidatorProps): JSX.Element;
7
7
  declare type ValueValidatorProps = {
@@ -1,4 +1,4 @@
1
- import BootstrapTable, { Actions, ActionsColumn, Column, default as BootstrapDataTable, IdColumn, useDataTableContext } from './Components/BootstrapDataTable';
1
+ import BootstrapTable, { RowRenderer, Actions, ActionsColumn, Column, default as BootstrapDataTable, IdColumn, useDataTableContext } from './Components/BootstrapDataTable';
2
2
  import CRUD, { CRUDActions, ModalEntityEditor } from './Components/CRUD';
3
3
  import EntityEditor from "./Components/EntityEditor";
4
4
  import ExcelExportButton from './Components/ExcelExportButton';
@@ -20,4 +20,4 @@ import ThemeProvider, { useTheme, useAllThemes } from './Components/ThemeProvide
20
20
  import StepList, { StepItem } from './Components/StepList';
21
21
  import PasswordInput from './Components/PasswordInput';
22
22
  import DefaultValidatorOptions from './Components/DefaultValidatorOptions';
23
- export { ThemeProvider, useTheme, useAllThemes, useIsMobile, useMenuState, DefaultValidatorOptions, PasswordInput, StepList, StepItem, TopProgressBar, CRUD, ModalEntityEditor, CRUDActions, Relative, ApiSelect, Preview, ExcelExportButton, ExternalLoginButton, SingleFilePicker, MultiFilePicker, ImagePicker, BootstrapTable, EntityEditor, GoToTop, Validator, ValueValidator, ValidationErrors, LoadingButton, BootstrapDataTable, IdColumn, Column, ActionsColumn, Actions, useDataTableContext, LanguageProvider, useLanguage, LanguageSwitcher, ErrorBoundary, CheckBox };
23
+ export { ThemeProvider, useTheme, useAllThemes, useIsMobile, useMenuState, DefaultValidatorOptions, PasswordInput, StepList, StepItem, TopProgressBar, CRUD, ModalEntityEditor, CRUDActions, Relative, ApiSelect, Preview, ExcelExportButton, ExternalLoginButton, SingleFilePicker, MultiFilePicker, ImagePicker, BootstrapTable, EntityEditor, GoToTop, Validator, ValueValidator, ValidationErrors, LoadingButton, BootstrapDataTable, IdColumn, Column, ActionsColumn, Actions, useDataTableContext, RowRenderer, LanguageProvider, useLanguage, LanguageSwitcher, ErrorBoundary, CheckBox };
package/lib/esm/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import BootstrapTable, { Actions, ActionsColumn, Column, default as BootstrapDataTable, IdColumn, useDataTableContext } from './Components/BootstrapDataTable';
1
+ import BootstrapTable, { RowRenderer, Actions, ActionsColumn, Column, default as BootstrapDataTable, IdColumn, useDataTableContext } from './Components/BootstrapDataTable';
2
2
  import CRUD, { CRUDActions, ModalEntityEditor } from './Components/CRUD';
3
3
  import EntityEditor from "./Components/EntityEditor";
4
4
  import ExcelExportButton from './Components/ExcelExportButton';
@@ -20,4 +20,4 @@ import ThemeProvider, { useTheme, useAllThemes } from './Components/ThemeProvide
20
20
  import StepList, { StepItem } from './Components/StepList';
21
21
  import PasswordInput from './Components/PasswordInput';
22
22
  import DefaultValidatorOptions from './Components/DefaultValidatorOptions';
23
- export { ThemeProvider, useTheme, useAllThemes, useIsMobile, useMenuState, DefaultValidatorOptions, PasswordInput, StepList, StepItem, TopProgressBar, CRUD, ModalEntityEditor, CRUDActions, Relative, ApiSelect, Preview, ExcelExportButton, ExternalLoginButton, SingleFilePicker, MultiFilePicker, ImagePicker, BootstrapTable, EntityEditor, GoToTop, Validator, ValueValidator, ValidationErrors, LoadingButton, BootstrapDataTable, IdColumn, Column, ActionsColumn, Actions, useDataTableContext, LanguageProvider, useLanguage, LanguageSwitcher, ErrorBoundary, CheckBox };
23
+ export { ThemeProvider, useTheme, useAllThemes, useIsMobile, useMenuState, DefaultValidatorOptions, PasswordInput, StepList, StepItem, TopProgressBar, CRUD, ModalEntityEditor, CRUDActions, Relative, ApiSelect, Preview, ExcelExportButton, ExternalLoginButton, SingleFilePicker, MultiFilePicker, ImagePicker, BootstrapTable, EntityEditor, GoToTop, Validator, ValueValidator, ValidationErrors, LoadingButton, BootstrapDataTable, IdColumn, Column, ActionsColumn, Actions, useDataTableContext, RowRenderer, LanguageProvider, useLanguage, LanguageSwitcher, ErrorBoundary, CheckBox };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-admin-base-bootstrap",
3
- "version": "0.7.8",
3
+ "version": "0.8.1",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",
@@ -28,29 +28,29 @@
28
28
  "react": "^18.2.0",
29
29
  "react-dom": "^18.2.0",
30
30
  "react-intl": "^5.21.0",
31
- "react-router-dom": "^6.3.0"
31
+ "react-router-dom": "^6.4.2"
32
32
  },
33
33
  "dependencies": {
34
- "@emotion/react": "^11.9.3",
35
- "@fortawesome/fontawesome-free": "^6.1.1",
36
- "bootstrap": "^5.1.3",
34
+ "@emotion/react": "^11.10.4",
35
+ "@fortawesome/fontawesome-free": "^6.2.0",
36
+ "bootstrap": "^5.2.2",
37
37
  "file-dialog": "^0.0.8",
38
38
  "modal-cropper": "^1.2.3",
39
39
  "nprogress": "^0.2.0",
40
40
  "prettysize": "^2.0.0",
41
41
  "react-admin-base": "^0.7.3",
42
42
  "react-password-strength-bar": "^0.4.1",
43
- "react-responsive": "^8.2.0",
44
- "react-select": "^5.3.2",
45
- "reactstrap": "^9.1.1",
43
+ "react-responsive": "^9.0.0",
44
+ "react-select": "^5.4.0",
45
+ "reactstrap": "^9.1.4",
46
46
  "rewire": "^6.0.0",
47
- "sweetalert2": "^11.4.17"
47
+ "sweetalert2": "^11.5.1"
48
48
  },
49
49
  "devDependencies": {
50
- "@types/react": "^18.0.12",
50
+ "@types/react": "^18.0.21",
51
51
  "cross-env": "^7.0.3",
52
- "nodemon": "^2.0.16",
53
- "react-intl": "^6.0.4",
54
- "typescript": "^4.7.3"
52
+ "nodemon": "^2.0.20",
53
+ "react-intl": "^6.1.2",
54
+ "typescript": "^4.8.4"
55
55
  }
56
56
  }
@@ -1,10 +1,10 @@
1
1
  /** @jsx jsx */
2
- import { jsx } from '@emotion/react';
3
- import React, { useCallback, useMemo, useState } from 'react';
4
- import { useFetch } from 'react-admin-base';
5
- import { FormattedMessage, useIntl } from 'react-intl';
6
- import Select, { components } from "react-select";
7
- import CreatableSelect from 'react-select/creatable';
2
+ import { jsx } from '@emotion/react';
3
+ import React, { useCallback, useMemo, useState } from 'react';
4
+ import { useFetch } from 'react-admin-base';
5
+ import { FormattedMessage, useIntl } from 'react-intl';
6
+ import Select, { components } from "react-select";
7
+ import CreatableSelect from 'react-select/creatable';
8
8
 
9
9
  function Option(props) {
10
10
  return <components.Option {...props}>
@@ -60,7 +60,25 @@ function IndicatorsContainer(props) {
60
60
 
61
61
  const Components = { Option, SingleValue, IndicatorsContainer };
62
62
 
63
- export default function ApiSelect(props) {
63
+ export interface ApiSelectProps<Option = any> {
64
+ url?: string;
65
+ value: Option|Option[];
66
+ onChange: (a: Option|Option[]|null) => void;
67
+ getOptionLabel?: (a: any) => string;
68
+ getOptionValue?: (a: any) => string;
69
+ onCreateOption?: (a: string) => Option|Promise<Option>;
70
+ filter?: (a: Option) => boolean;
71
+ group?: (a: Option[]) => any[];
72
+ isMulti?: boolean;
73
+ idKey?: string;
74
+ nameKey?: string;
75
+ disabled?: boolean;
76
+ placeholder?: string;
77
+ staticOptions?: any[];
78
+ getNewOptionData?: (name: string, elem: React.ReactNode) => any|null;
79
+ }
80
+
81
+ export default function ApiSelect<Option = any>(props: ApiSelectProps<Option>) {
64
82
  const { disabled, url, getOptionLabel, getOptionValue, idKey, nameKey, filter, group, onCreateOption, getNewOptionData, isMulti, onChange, value, placeholder, staticOptions } = props;
65
83
  const intl = useIntl();
66
84
  const [ search, setSearch ] = useState('');
@@ -76,11 +94,14 @@ export default function ApiSelect(props) {
76
94
  }
77
95
 
78
96
  const handleCreateOption = useCallback(async function(input) {
97
+ if (!onCreateOption)
98
+ return null;
99
+
79
100
  setCreating(true);
80
101
  try {
81
102
  let option = await onCreateOption(input);
82
103
  if (isMulti) {
83
- onChange((value || []).concat([option]));
104
+ onChange(((value as Option[]) || []).concat([option]));
84
105
  } else {
85
106
  onChange(option);
86
107
  }
@@ -104,8 +125,8 @@ export default function ApiSelect(props) {
104
125
  {...props}
105
126
  className='react-select-container'
106
127
  classNamePrefix="react-select"
107
- onCreateOption={(onCreateOption && handleCreateOption) || null}
108
- getNewOptionData={onCreateOption ? getNewOptionData ? getNewOptionData : (inputValue) =>( { [nameKey || 'name']: inputValue, __isNew__: true }) : null}
128
+ onCreateOption={onCreateOption && handleCreateOption}
129
+ getNewOptionData={(onCreateOption && (getNewOptionData || ((inputValue) =>( { [nameKey || 'name']: inputValue, __isNew__: true })))) || undefined}
109
130
  inputValue={search}
110
131
  onInputChange={a => setSearch(a)}
111
132
  components={Components}
@@ -117,7 +138,6 @@ export default function ApiSelect(props) {
117
138
  isSearchable
118
139
  placeholder={placeholder || intl.formatMessage({ id: 'SELECT' })}
119
140
  options={!options ? [] : ((filter && options.filter(filter)) || options)}
120
- isMenuOpen={isMenuOpen}
121
141
  onMenuOpen={onMenuOpen}
122
142
  onMenuClose={onMenuClose}
123
143
  />;
@@ -7,12 +7,21 @@ import Swal from 'sweetalert2';
7
7
  import BootstrapPagination from "./BootstrapPagination";
8
8
 
9
9
  const DataTableContext = React.createContext(null as any);
10
+ const RowDatasContext = React.createContext(null as any);
11
+ const RowDataContext = React.createContext(null as any);
10
12
 
11
13
  export function useDataTableContext() {
12
14
  return useContext(DataTableContext);
13
15
  }
14
16
 
15
- export function Actions({edit, del, rowSpan, children} : {edit: any, del: any, rowSpan?:any, children?: any}) {
17
+ type ActionsProp = {
18
+ edit?: string;
19
+ del?: string;
20
+ rowSpan?: number|undefined;
21
+ children?: React.ReactNode;
22
+ };
23
+
24
+ export function Actions({edit, del, rowSpan, children}: ActionsProp) {
16
25
  const [api] = useAuth();
17
26
  const [, setParams] = useContext(DataTableContext);
18
27
  const intl = useIntl();
@@ -75,14 +84,39 @@ export function Column(props) {
75
84
  </th>;
76
85
  }
77
86
 
78
- export default function BootstrapTable({url, bordered, noStrip, defaultParams, add, children, innerRef, body}: any) {
79
- var state = useState({sort: 'id', ...defaultParams});
87
+ export interface BootstrapTableProps {
88
+ url: string;
89
+ bordered?: boolean;
90
+ noStrip?: boolean;
91
+ defaultParams?: any;
92
+ body?: any;
93
+ add?: string;
94
+ children: any;
95
+ innerRef?: any;
96
+ }
97
+
98
+ interface RowRendererProps<Row = any> {
99
+ render: (row: Row) => React.ReactNode;
100
+ }
101
+
102
+ export function RowRenderer<Row = any>({render}: RowRendererProps<Row>) {
103
+ const rows = useContext(RowDatasContext);
104
+
105
+ return <tbody>
106
+ { rows.map(render) }
107
+ </tbody>;
108
+ }
109
+
110
+ export default function BootstrapTable({url, bordered, noStrip, defaultParams, add, children, innerRef, body}: BootstrapTableProps) {
111
+ const state = useState({sort: 'id', ...defaultParams});
80
112
  const [params, setParams] = state;
81
113
  const [page, lastPage, setPage, data, itemPerPage, setItemPerPage, update] = useDataTable(url, params, body);
82
114
  const intl = useIntl();
83
115
  const [ api ] = useAuth();
84
116
 
85
- var ref = useRef(defaultParams);
117
+ console.log(children[1]);
118
+
119
+ const ref = useRef(defaultParams);
86
120
  useEffect(function () {
87
121
  if (ref.current !== defaultParams) {
88
122
  ref.current = defaultParams;
@@ -114,47 +148,49 @@ export default function BootstrapTable({url, bordered, noStrip, defaultParams, a
114
148
  <DataTableContext.Provider value={state}>
115
149
  <DataContextProvider value={fetchData}>
116
150
  <RefreshScope update={update}>
117
- <CardHeader>
118
- <Row>
119
- {add && <Col xs="12" md="2"><Link to={add} className="btn btn-primary font-xl d-block"><i className="fa fa-plus"/></Link></Col>}
120
- <Col md="2">
121
- <Input type="select" value={itemPerPage.toString()} onChange={a => setItemPerPage(+a.currentTarget.value)}>
122
- <option value="1">1</option>
123
- <option value="20">20</option>
124
- <option value="50">50</option>
125
- <option value="100">100</option>
126
- <option value="150">150</option>
127
- <option value="200">200</option>
128
- <option value="-1">{intl.formatMessage({id: "ALL"})}</option>
129
- </Input>
130
- </Col>
131
- {children[2]}
132
- <Col md="3" className="ms-auto">
133
- <Input
134
- placeholder={intl.formatMessage({id: "SEARCH"})} type="text"
135
- value={params.query || ''}
136
- onChange={e => setParams({...params, query: e.currentTarget.value})}
151
+ <RowDatasContext.Provider value={data}>
152
+ <CardHeader>
153
+ <Row>
154
+ {add && <Col xs="12" md="2"><Link to={add} className="btn btn-primary font-xl d-block"><i className="fa fa-plus"/></Link></Col>}
155
+ <Col md="2">
156
+ <Input type="select" value={itemPerPage.toString()} onChange={a => setItemPerPage(+a.currentTarget.value)}>
157
+ <option value="1">1</option>
158
+ <option value="20">20</option>
159
+ <option value="50">50</option>
160
+ <option value="100">100</option>
161
+ <option value="150">150</option>
162
+ <option value="200">200</option>
163
+ <option value="-1">{intl.formatMessage({id: "ALL"})}</option>
164
+ </Input>
165
+ </Col>
166
+ {children[2]}
167
+ <Col md="3" className="ms-auto">
168
+ <Input
169
+ placeholder={intl.formatMessage({id: "SEARCH"})} type="text"
170
+ value={params.query || ''}
171
+ onChange={e => setParams({...params, query: e.currentTarget.value})}
172
+ />
173
+ </Col>
174
+ </Row>
175
+ </CardHeader>
176
+ {data === null ? <Alert className="text-center mb-0 mx-3 " color="warning"><i className="fas fa-spinner fa-spin"></i></Alert> : !data.length ? <Alert className="text-center mx-3" color="danger">
177
+ <i className="far fa-times-circle"></i> <FormattedMessage id="NO_DATA_IS_AVAILABLE"/>
178
+ </Alert> : <Table hover bordered={bordered} striped={!noStrip} responsive size="md" className="mb-0 dataTable">
179
+ {children[0]}
180
+ {children[1].type === "tbody" ? <tbody>
181
+ {data && data.map(children[1].props.children)}
182
+ </tbody> : children[1]}
183
+ </Table>}
184
+ { lastPage > 1 && <CardFooter>
185
+ <nav>
186
+ <BootstrapPagination
187
+ currentPage={page}
188
+ pageCount={lastPage}
189
+ onPageChange={index => setPage(index)}
137
190
  />
138
- </Col>
139
- </Row>
140
- </CardHeader>
141
- {data === null ? <Alert className="text-center mb-0 mx-3 " color="warning"><i className="fas fa-spinner fa-spin"></i></Alert> : !data.length ? <Alert className="text-center mx-3" color="danger">
142
- <i className="far fa-times-circle"></i> <FormattedMessage id="NO_DATA_IS_AVAILABLE"/>
143
- </Alert> : <Table hover bordered={bordered} striped={!noStrip} responsive size="md" className="mb-0 dataTable">
144
- {children[0]}
145
- <tbody>
146
- {data && data.map(children[1].props.children)}
147
- </tbody>
148
- </Table>}
149
- { lastPage > 1 && <CardFooter>
150
- <nav>
151
- <BootstrapPagination
152
- currentPage={page}
153
- pageCount={lastPage}
154
- onPageChange={index => setPage(index)}
155
- />
156
- </nav>
157
- </CardFooter> }
191
+ </nav>
192
+ </CardFooter> }
193
+ </RowDatasContext.Provider>
158
194
  </RefreshScope>
159
195
  </DataContextProvider>
160
196
  </DataTableContext.Provider>
@@ -4,7 +4,7 @@ import { FormattedMessage } from 'react-intl';
4
4
  import { Navigate, Routes, useParams, Route } from 'react-router-dom';
5
5
  import { Alert, Button, Col, Form, Modal, ModalFooter, ModalHeader, Row } from "reactstrap";
6
6
  import LoadingButton from '../Components/LoadingButton';
7
- import BootstrapDataTable, { Actions } from './BootstrapDataTable';
7
+ import BootstrapDataTable, { Actions, BootstrapTableProps } from './BootstrapDataTable';
8
8
 
9
9
  type ModalEntityEditorParams = {
10
10
  entity: any;
@@ -109,11 +109,17 @@ function ComponentWrapper({ Component, ...props }) {
109
109
  return <Component {...props} id={id} />;
110
110
  }
111
111
 
112
- export default function CRUD(props) {
112
+ interface CRUDProps extends BootstrapTableProps {
113
+ apiUrl?: string;
114
+ Component: any;
115
+ noAdd?: boolean;
116
+ }
117
+
118
+ export default function CRUD(props: CRUDProps) {
113
119
  const ref = useRef(null as any);
114
120
  const { url, apiUrl, Component, defaultParams, noAdd } = props;
115
121
 
116
- var reload = useCallback(async function() {
122
+ const reload = useCallback(async function() {
117
123
  if (ref.current) {
118
124
  ref.current({});
119
125
  }
@@ -124,6 +130,6 @@ export default function CRUD(props) {
124
130
  { !noAdd && <Route path="create" element={<ComponentWrapper Component={Component} url={url} onReload={reload} {...(defaultParams || {})} />} /> }
125
131
  <Route path=":id/edit" element={<ComponentWrapper Component={Component} url={url} onReload={reload} {...(defaultParams || {})} />} />
126
132
  </Routes>
127
- <BootstrapDataTable innerRef={ref} add={!noAdd && "create"} {...props} url={apiUrl || url} />
133
+ <BootstrapDataTable innerRef={ref} add={(!noAdd && "create") || undefined} {...props} url={apiUrl || url} />
128
134
  </UrlContext.Provider>;
129
135
  }
@@ -1,9 +1,16 @@
1
1
  import React from "react";
2
- import { FormGroup, Input, Label } from "reactstrap";
2
+ import { FormGroup, Input, InputProps, Label } from "reactstrap";
3
3
 
4
- export default function CheckBox(props: any) {
4
+ interface CheckBoxProps extends InputProps {
5
+ id: string;
6
+ type?: "checkbox"|"radio";
7
+ label?: React.ReactNode;
8
+ children: React.ReactNode;
9
+ }
10
+
11
+ export default function CheckBox(props: CheckBoxProps) {
5
12
  return <FormGroup check>
6
- <Input type={props.type || "checkbox"} {...props} label={undefined} />
13
+ <Input type={props.type || "checkbox"} {...props} children={undefined} label={undefined} />
7
14
  <Label check for={props.id}>{props.children || props.label}</Label>
8
15
  </FormGroup>;
9
16
  }
@@ -3,7 +3,11 @@ import { ValidatorOptionProvider } from "react-admin-base";
3
3
  import { useIntl } from "react-intl";
4
4
  import zxcvbn from 'zxcvbn';
5
5
 
6
- export default function DefaultValidatorOptions({ children }) {
6
+ type DefaultValidatorOptionsProps = {
7
+ children: React.ReactNode;
8
+ };
9
+
10
+ export default function DefaultValidatorOptions({ children }: DefaultValidatorOptionsProps) {
7
11
  const intl = useIntl();
8
12
 
9
13
  const options = useMemo(() => ({
@@ -5,7 +5,9 @@ import {Button, Col} from "reactstrap";
5
5
  export default function ExcelExportButton({name, header, params, size, map, extra}) {
6
6
  const [ handleExport, loading ] = useExporter(header, params, map, extra);
7
7
 
8
- return <Col><Button className="w-100 d-block" type="button" size={size} color="success" outline disabled={!!loading} onClick={() => handleExport(name)}>
9
- {loading ? <i className="fas fa-spin fa-spinner"/> : <i className="fas fa-file-excel"/>}
10
- </Button></Col>
8
+ return <Col>
9
+ <Button className="w-100 d-block" type="button" size={size} color="success" outline disabled={!!loading} onClick={() => handleExport(name)}>
10
+ {loading ? <i className="fas fa-spin fa-spinner"/> : <i className="fas fa-file-excel"/>}
11
+ </Button>
12
+ </Col>;
11
13
  }
@@ -3,7 +3,14 @@ import React from 'react';
3
3
  import { useApp, useAuth, useLogin } from 'react-admin-base';
4
4
  import { FormattedMessage } from 'react-intl';
5
5
 
6
- export default function ExternalLoginButton({ id, icon, name, url }) {
6
+ type ExternalLoginButtonProps = {
7
+ id: string;
8
+ icon?: string;
9
+ name: string;
10
+ url: string;
11
+ };
12
+
13
+ export default function ExternalLoginButton({ id, icon, name, url }: ExternalLoginButtonProps) {
7
14
  const { endpoint } = useApp();
8
15
  const [{ client_id }] = useAuth();
9
16
  const { login } = useLogin();
@@ -5,7 +5,7 @@ import {Button} from "reactstrap";
5
5
  import { useApp, useFilePicker, usePreviewComponent } from "react-admin-base";
6
6
  import {FormattedMessage} from "react-intl";
7
7
 
8
- var photo_ext = ["png", "jpg", "jpeg", "svg"];
8
+ const photo_ext = ["png", "jpg", "jpeg", "svg"];
9
9
 
10
10
  function is_photo(name) {
11
11
  return photo_ext.indexOf(name.split('.')[1]) !== -1;
@@ -15,11 +15,15 @@ function is_absolute(url) {
15
15
  if (url.indexOf("blob:") === 0)
16
16
  return false;
17
17
 
18
- var pat = /^https?:\/\//i;
18
+ const pat = /^https?:\/\//i;
19
19
  return !pat.test(url);
20
20
  }
21
21
 
22
- export function Relative({ children }) {
22
+ type RelativeProps = {
23
+ children: JSX.Element;
24
+ };
25
+
26
+ export function Relative({ children }: RelativeProps) {
23
27
  const app = useApp();
24
28
 
25
29
  if (!children)
@@ -34,8 +38,8 @@ export function Relative({ children }) {
34
38
  }
35
39
 
36
40
  export function Preview({ value }) {
37
- var name = value.$name;
38
- var src = value.$blob_url || value.$src;
41
+ const name = value.$name;
42
+ const src = value.$blob_url || value.$src;
39
43
 
40
44
  if (is_photo(name)) {
41
45
  return <div className="mt-2">
@@ -1,15 +1,15 @@
1
1
 
2
2
  import React, { useCallback } from 'react';
3
- import SingleFilePicker from './SingleFilePicker';
3
+ import SingleFilePicker, { SingleFilePickerProps } from './SingleFilePicker';
4
4
 
5
- type ImagePickerProps = {
5
+ interface ImagePickerProps extends SingleFilePickerProps {
6
6
  width: number;
7
7
  height: number;
8
8
  type: string;
9
9
  exact?: boolean;
10
- };
10
+ }
11
11
 
12
- export default function ImagePicker(props) {
12
+ export default function ImagePicker(props: ImagePickerProps) {
13
13
  const { width, height, type, exact } = props;
14
14
 
15
15
  const transform = useCallback(async function(file) {
@@ -20,7 +20,14 @@ export function useLanguage() {
20
20
  return useContext(LanguageContext);
21
21
  }
22
22
 
23
- export default function LanguageProvider({ defaultLanguage, languages, loader, children }) {
23
+ type LanguageProviderProps = {
24
+ defaultLanguage: string;
25
+ languages: any;
26
+ loader?: (language: any) => any;
27
+ children: React.ReactNode;
28
+ };
29
+
30
+ export default function LanguageProvider({ defaultLanguage, languages, loader, children }: LanguageProviderProps) {
24
31
  const app = useApp();
25
32
 
26
33
  const preferredLanguage = (navigator.languages && navigator.languages[0]) || navigator.language;
@@ -1,7 +1,7 @@
1
1
 
2
2
  import React from 'react';
3
- import { Button } from 'reactstrap';
3
+ import { Button, ButtonProps } from 'reactstrap';
4
4
 
5
- export default function LoadingButton(props) {
5
+ export default function LoadingButton(props: ButtonProps) {
6
6
  return props.loading ? <Button {...props} loading={undefined} disabled={true}><i className="fas fa-spin fa-circle-notch" /></Button> : <Button {...props} loading={undefined} />;
7
7
  }
@@ -1,9 +1,9 @@
1
1
 
2
- import React, { useCallback, useMemo } from 'react';
3
- import { useUploadController } from "react-admin-base";
4
- import FilePickerCore from "./FilePickerCore";
2
+ import React, { useCallback, useMemo } from 'react';
3
+ import { useUploadController } from "react-admin-base";
4
+ import FilePickerCore from "./FilePickerCore";
5
5
 
6
- type SingleFilePickerProps = {
6
+ export interface SingleFilePickerProps {
7
7
  disabled?: boolean;
8
8
  className?: string;
9
9
  accepts?: string;
@@ -4,7 +4,13 @@ import { FormattedMessage } from "react-intl";
4
4
  const IndexContext = React.createContext(0);
5
5
  const OnClickDataContext = React.createContext<[number, (a: Number) => void]>(null as any);
6
6
 
7
- export default function StepList({ active, setActive, children }: any) {
7
+ type StepListProps = {
8
+ active: number;
9
+ setActive: (active: number) => {};
10
+ children: React.ReactNode;
11
+ }
12
+
13
+ export default function StepList({ active, setActive, children }: StepListProps) {
8
14
  const onClickData = useMemo<[number, (a: Number) => void]>(() => [active, setActive], [active, setActive]);
9
15
 
10
16
  return <ul className="step step-sm step-icon-sm step step-inline step-item-between mb-3">
@@ -18,7 +24,13 @@ export default function StepList({ active, setActive, children }: any) {
18
24
  </ul>;
19
25
  }
20
26
 
21
- export function StepItem({ title, translate, disabled }: any) {
27
+ type StepItemProps = {
28
+ title?: string;
29
+ translate?: string;
30
+ disabled?: boolean;
31
+ }
32
+
33
+ export function StepItem({ title, translate, disabled }: StepItemProps) {
22
34
  const index = useContext(IndexContext);
23
35
  const [ activeStep, onClickParent ] = useContext(OnClickDataContext);
24
36
 
@@ -1,8 +1,12 @@
1
1
  import NProgress from 'nprogress';
2
- import { useEffect } from 'react';
2
+ import React, { useEffect } from 'react';
3
3
  import { useAuth } from "react-admin-base";
4
4
 
5
- export default function TopProgressBar({ children }) {
5
+ type TopProgressBarProps = {
6
+ children: React.ReactNode;
7
+ };
8
+
9
+ export default function TopProgressBar({ children }: TopProgressBarProps): React.ReactNode {
6
10
  const [ api ] = useAuth();
7
11
 
8
12
  useEffect(function() {
@@ -1,8 +1,8 @@
1
1
 
2
- import React from 'react';
3
- import { useValidate, useValidator } from 'react-admin-base';
4
- import { FormattedMessage } from "react-intl";
5
- import { Alert, FormFeedback } from "reactstrap";
2
+ import React from 'react';
3
+ import { useValidate, useValidator } from 'react-admin-base';
4
+ import { FormattedMessage } from "react-intl";
5
+ import { Alert, FormFeedback } from "reactstrap";
6
6
 
7
7
  function ValidatorCore(name: string, value: any, type: any, children: any) {
8
8
  const error = useValidate(name || '', value, type);
@@ -17,7 +17,7 @@ function ValidatorCore(name: string, value: any, type: any, children: any) {
17
17
  type ValidatorProps = {
18
18
  name: string;
19
19
  type: any;
20
- children: any;
20
+ children: JSX.Element;
21
21
  };
22
22
 
23
23
  export function Validator({ name, type, children }: ValidatorProps) {
package/src/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- import BootstrapTable, { Actions, ActionsColumn, Column, default as BootstrapDataTable, IdColumn, useDataTableContext } from './Components/BootstrapDataTable';
2
+ import BootstrapTable, { RowRenderer, Actions, ActionsColumn, Column, default as BootstrapDataTable, IdColumn, useDataTableContext } from './Components/BootstrapDataTable';
3
3
  import CRUD, { CRUDActions, ModalEntityEditor } from './Components/CRUD';
4
4
  import EntityEditor from "./Components/EntityEditor";
5
5
  import ExcelExportButton from './Components/ExcelExportButton';
@@ -44,6 +44,7 @@ export {
44
44
  Validator, ValueValidator, ValidationErrors,
45
45
  LoadingButton,
46
46
  BootstrapDataTable, IdColumn, Column, ActionsColumn, Actions, useDataTableContext,
47
+ RowRenderer,
47
48
  LanguageProvider, useLanguage, LanguageSwitcher,
48
49
  ErrorBoundary,
49
50
  CheckBox