react-admin-base-bootstrap 0.8.3 → 0.8.5

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.
@@ -0,0 +1,2 @@
1
+ import { ModalProps } from "reactstrap";
2
+ export default function BootstrapModal(props: ModalProps): JSX.Element;
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import { Modal } from "reactstrap";
3
+ import { useBootstrapOptions } from "./BootstrapOptions";
4
+ export default function BootstrapModal(props) {
5
+ const bsOptions = useBootstrapOptions();
6
+ return React.createElement(Modal, Object.assign({}, props, { toggle: bsOptions.noCloseModal ? undefined : props.toggle }));
7
+ }
@@ -0,0 +1,11 @@
1
+ import { ReactNode } from "react";
2
+ import BootstrapOptions from "./BootstrapOptions";
3
+ interface BootstrapOptions {
4
+ noCloseModal: boolean;
5
+ }
6
+ interface BootstrapOptionsProviderProps extends BootstrapOptions {
7
+ children: ReactNode;
8
+ }
9
+ export declare function useBootstrapOptions(): BootstrapOptions;
10
+ export default function BootstrapOptionsProvider({ children, noCloseModal }: BootstrapOptionsProviderProps): JSX.Element;
11
+ export {};
@@ -0,0 +1,11 @@
1
+ import React, { createContext, useContext, useMemo } from "react";
2
+ const BootstrapOptionsContext = createContext({
3
+ noCloseModal: false
4
+ });
5
+ export function useBootstrapOptions() {
6
+ return useContext(BootstrapOptionsContext);
7
+ }
8
+ export default function BootstrapOptionsProvider({ children, noCloseModal }) {
9
+ const options = useMemo(() => ({ noCloseModal }), [noCloseModal]);
10
+ return React.createElement(BootstrapOptionsContext.Provider, { value: options }, children);
11
+ }
@@ -22,9 +22,10 @@ import React, { useCallback, useContext, useRef, useState } from 'react';
22
22
  import { ValidatorProvider } from "react-admin-base";
23
23
  import { FormattedMessage } from 'react-intl';
24
24
  import { Navigate, Routes, useParams, Route } from 'react-router-dom';
25
- import { Alert, Button, Col, Form, Modal, ModalFooter, ModalHeader, Row } from "reactstrap";
25
+ import { Alert, Button, Col, Form, ModalFooter, ModalHeader, Row } from "reactstrap";
26
26
  import LoadingButton from '../Components/LoadingButton';
27
27
  import BootstrapDataTable, { Actions } from './BootstrapDataTable';
28
+ import BootstrapModal from './BootstrapModal';
28
29
  export function ModalEntityEditor({ entity, title, size, url, onReload, disabled, children }) {
29
30
  const [, , save, loading] = entity;
30
31
  const [open, setOpen] = useState(true);
@@ -59,7 +60,7 @@ export function ModalEntityEditor({ entity, title, size, url, onReload, disabled
59
60
  }, [save, saved, error, onReload, url]);
60
61
  return React.createElement(React.Fragment, null,
61
62
  (saved || !open) && url && React.createElement(Navigate, { to: url, replace: true }),
62
- React.createElement(Modal, { isOpen: true, size: size, toggle: () => url ? setOpen(false) : onReload(null), fade: false },
63
+ React.createElement(BootstrapModal, { isOpen: true, size: size, toggle: () => url ? setOpen(false) : onReload(null), fade: false },
63
64
  title && React.createElement(ModalHeader, { toggle: () => url ? setOpen(false) : onReload(null) },
64
65
  React.createElement("b", null, title)),
65
66
  React.createElement(ValidatorProvider, null,
@@ -103,5 +104,5 @@ export default function CRUD(props) {
103
104
  React.createElement(Routes, null,
104
105
  !noAdd && React.createElement(Route, { path: "create", element: React.createElement(ComponentWrapper, Object.assign({ Component: Component, url: url, onReload: reload }, (defaultParams || {}))) }),
105
106
  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") || undefined }, props, { url: apiUrl || url })));
107
+ React.createElement(BootstrapDataTable, Object.assign({ innerRef: ref, add: (!noAdd && "create") || undefined }, props, { url: apiUrl || url }), props.children));
107
108
  }
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
2
  import { InputProps } from "reactstrap";
3
3
  interface CheckBoxProps extends InputProps {
4
- id: string;
4
+ id?: string;
5
5
  type?: "checkbox" | "radio";
6
6
  label?: React.ReactNode;
7
7
  children?: React.ReactNode;
@@ -1,7 +1,8 @@
1
- import React from "react";
1
+ import React, { useId } from "react";
2
2
  import { FormGroup, Input, Label } from "reactstrap";
3
3
  export default function CheckBox(props) {
4
+ const id = useId();
4
5
  return React.createElement(FormGroup, { check: true },
5
- React.createElement(Input, Object.assign({ type: props.type || "checkbox" }, props, { children: undefined, label: undefined })),
6
- React.createElement(Label, { check: true, for: props.id }, props.children || props.label));
6
+ React.createElement(Input, Object.assign({ id: props.id || id, type: props.type || "checkbox" }, props, { children: undefined, label: undefined })),
7
+ React.createElement(Label, { check: true, for: props.id || id }, props.children || props.label));
7
8
  }
@@ -0,0 +1,2 @@
1
+ import { ButtonProps } from "reactstrap";
2
+ export default function DragAndDropArrow(props: ButtonProps): JSX.Element | null;
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ import { Button } from "reactstrap";
3
+ import { useDragContext } from "react-admin-base";
4
+ export default function DragAndDropArrow(props) {
5
+ const [ref, isDragging] = useDragContext();
6
+ if (!ref)
7
+ return null;
8
+ return React.createElement(Button, Object.assign({ type: "button", innerRef: ref, outline: true, size: "sm", color: "primary" }, props),
9
+ React.createElement("i", { className: "fas fa-" + (isDragging ? "circle-dot" : "arrows-up-down-left-right") }),
10
+ props.children);
11
+ }
@@ -0,0 +1,2 @@
1
+ import { ButtonProps } from "reactstrap";
2
+ export declare function DragAndDropArrow(props: ButtonProps): JSX.Element | null;
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ import { Button } from "reactstrap";
3
+ import { useDragContext } from "react-admin-base";
4
+ export function DragAndDropArrow(props) {
5
+ const [ref, isDragging] = useDragContext();
6
+ if (!ref)
7
+ return null;
8
+ return React.createElement(Button, Object.assign({ type: "button", innerRef: ref, outline: true, size: "sm", color: "primary" }, props),
9
+ React.createElement("i", { className: "fas fa-arrows-up-down-left-right" }),
10
+ props.children);
11
+ }
@@ -6,8 +6,10 @@ export declare function Relative({ children }: RelativeProps): React.FunctionCom
6
6
  export declare function Preview({ value }: {
7
7
  value: any;
8
8
  }): JSX.Element | null;
9
- export default function FilePickerCore({ disabled, className, accepts, value, onNotify, children, transform }: {
9
+ export default function FilePickerCore({ disabled, index, move, className, accepts, value, onNotify, children, transform }: {
10
10
  disabled?: any;
11
+ index?: number;
12
+ move?: any;
11
13
  className?: any;
12
14
  accepts?: any;
13
15
  value?: any;
@@ -1,11 +1,13 @@
1
1
  import React, { useCallback } from 'react';
2
2
  import prettysize from 'prettysize';
3
3
  import { Button } from "reactstrap";
4
- import { useApp, useFilePicker, usePreviewComponent } from "react-admin-base";
4
+ import { useApp, useFilePicker, usePreviewComponent, DragAndDropItem } from "react-admin-base";
5
5
  import { FormattedMessage } from "react-intl";
6
+ import DragAndDropArrow from './DragAndDropArrow';
6
7
  const photo_ext = ["png", "jpg", "jpeg", "svg"];
7
8
  function is_photo(name) {
8
- return photo_ext.indexOf(name.split('.')[1]) !== -1;
9
+ const sp = (name || '').split('.');
10
+ return photo_ext.indexOf((sp[sp.length - 1] || '').toLowerCase()) !== -1;
9
11
  }
10
12
  function is_absolute(url) {
11
13
  if (url.indexOf("blob:") === 0)
@@ -24,7 +26,7 @@ export function Relative({ children }) {
24
26
  });
25
27
  }
26
28
  export function Preview({ value }) {
27
- const name = value.$name;
29
+ const name = value.$name || value.name;
28
30
  const src = value.$blob_url || value.$src;
29
31
  if (is_photo(name)) {
30
32
  return React.createElement("div", { className: "mt-2" },
@@ -33,7 +35,7 @@ export function Preview({ value }) {
33
35
  }
34
36
  return null;
35
37
  }
36
- export default function FilePickerCore({ disabled, className, accepts, value, onNotify, children, transform }) {
38
+ export default function FilePickerCore({ disabled, index, move, className, accepts, value, onNotify, children, transform }) {
37
39
  const [uc, cancel, pick] = useFilePicker(value, onNotify);
38
40
  const CustomPreview = usePreviewComponent() || Preview;
39
41
  const chooseFile = useCallback(function (e) {
@@ -62,21 +64,23 @@ export default function FilePickerCore({ disabled, className, accepts, value, on
62
64
  children && children(uc));
63
65
  }
64
66
  else if (uc.$state === 3) { // yuklendi
65
- return React.createElement("div", { className: className },
66
- !disabled && React.createElement(Button, { color: "danger", outline: true, size: "sm", onClick: cancel },
67
- React.createElement("i", { className: "fa fa-trash" })),
68
- "\u00A0",
69
- React.createElement(Relative, null,
70
- React.createElement("a", { href: uc.$src, target: "_blank", className: "btn btn-sm btn-outline-primary" },
71
- React.createElement("i", { className: "fa fa-download" }),
72
- " ",
73
- uc.name)),
74
- React.createElement("span", null,
75
- "\u00A0(",
76
- prettysize(uc.$size),
77
- ")"),
78
- React.createElement(CustomPreview, { value: uc }),
79
- children && children(uc));
67
+ return React.createElement(DragAndDropItem, { item: index },
68
+ React.createElement("div", { className: className },
69
+ React.createElement(DragAndDropArrow, { className: "me-1" }),
70
+ !disabled && React.createElement(Button, { color: "danger", outline: true, size: "sm", onClick: cancel },
71
+ React.createElement("i", { className: "fa fa-trash" })),
72
+ "\u00A0",
73
+ React.createElement(Relative, null,
74
+ React.createElement("a", { href: uc.$src, target: "_blank", className: "btn btn-sm btn-outline-primary" },
75
+ React.createElement("i", { className: "fa fa-download" }),
76
+ " ",
77
+ uc.name)),
78
+ React.createElement("span", null,
79
+ "\u00A0(",
80
+ prettysize(uc.$size),
81
+ ")"),
82
+ React.createElement(CustomPreview, { value: uc }),
83
+ children && children(uc)));
80
84
  }
81
85
  return null;
82
86
  }
@@ -10,7 +10,7 @@ export default class GoToTop extends React.Component {
10
10
  window.scrollTo(0, 0);
11
11
  }
12
12
  handleScroll(e) {
13
- var newShow = window.scrollY > 100;
13
+ const newShow = window.scrollY > 100;
14
14
  if (newShow !== this.state.show) {
15
15
  this.setState({ show: newShow });
16
16
  }
@@ -5,7 +5,8 @@ declare type MultiFilePickerProps = {
5
5
  accepts?: string;
6
6
  value: any;
7
7
  onChange: (value: any) => void;
8
+ noMove?: boolean;
8
9
  children?: (value: any) => React.ReactNode;
9
10
  };
10
- export default function MultiFilePicker({ disabled, className, accepts, value, onChange, children }: MultiFilePickerProps): JSX.Element;
11
+ export default function MultiFilePicker({ disabled, className, noMove, accepts, value, onChange, children }: MultiFilePickerProps): JSX.Element;
11
12
  export {};
@@ -1,11 +1,11 @@
1
1
  import React, { useMemo } from 'react';
2
- import { useMultiFilePicker } from "react-admin-base";
2
+ import { useMultiFilePicker, DragAndDropProvider } from "react-admin-base";
3
3
  import { FormattedMessage } from "react-intl";
4
4
  import { Button } from "reactstrap";
5
5
  import FilePickerCore from "./FilePickerCore";
6
- export default function MultiFilePicker({ disabled, className, accepts, value, onChange, children }) {
6
+ export default function MultiFilePicker({ disabled, className, noMove, accepts, value, onChange, children }) {
7
7
  const uniqueIdList = useMemo(() => [], []);
8
- const [controllers, _onChange, chooseFile] = useMultiFilePicker(value, onChange);
8
+ const [controllers, _onChange, chooseFile, onMove] = useMultiFilePicker(value, onChange);
9
9
  function getConstantUniqueIdFor(element) {
10
10
  if (uniqueIdList.indexOf(element) < 0) {
11
11
  uniqueIdList.push(element);
@@ -18,5 +18,5 @@ export default function MultiFilePicker({ disabled, className, accepts, value, o
18
18
  " ",
19
19
  React.createElement(FormattedMessage, { id: "CHOOSE_FILE" })),
20
20
  children && children(null),
21
- controllers.map((a, i) => React.createElement(FilePickerCore, { key: getConstantUniqueIdFor(a), disabled: !!disabled, className: "mt-2", accepts: accepts, value: a, onNotify: _onChange.bind(null, a) }, children)));
21
+ React.createElement(DragAndDropProvider, { onMove: !noMove && onMove }, controllers.map((a, i) => React.createElement(FilePickerCore, { key: getConstantUniqueIdFor(a), disabled: !!disabled, className: "mt-2", accepts: accepts, value: a, index: i, onNotify: _onChange.bind(null, a) }, children))));
22
22
  }
@@ -20,4 +20,7 @@ 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, RowRenderer, LanguageProvider, useLanguage, LanguageSwitcher, ErrorBoundary, CheckBox };
23
+ import DragAndDropArrow from './Components/DragAndDropArrow';
24
+ import BootstrapOptionsProvider, { useBootstrapOptions } from './Components/BootstrapOptions';
25
+ import BootstrapModal from './Components/BootstrapModal';
26
+ 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, DragAndDropArrow, useBootstrapOptions, BootstrapOptionsProvider, BootstrapModal };
package/lib/esm/index.js CHANGED
@@ -20,4 +20,7 @@ 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, RowRenderer, LanguageProvider, useLanguage, LanguageSwitcher, ErrorBoundary, CheckBox };
23
+ import DragAndDropArrow from './Components/DragAndDropArrow';
24
+ import BootstrapOptionsProvider, { useBootstrapOptions } from './Components/BootstrapOptions';
25
+ import BootstrapModal from './Components/BootstrapModal';
26
+ 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, DragAndDropArrow, useBootstrapOptions, BootstrapOptionsProvider, BootstrapModal };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-admin-base-bootstrap",
3
- "version": "0.8.3",
3
+ "version": "0.8.5",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",
@@ -31,26 +31,28 @@
31
31
  "react-router-dom": "^6.4.2"
32
32
  },
33
33
  "dependencies": {
34
- "@emotion/react": "^11.10.4",
34
+ "@emotion/react": "^11.10.5",
35
35
  "@fortawesome/fontawesome-free": "^6.2.0",
36
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
- "react-admin-base": "^0.8.0",
41
+ "react-admin-base": "^0.8.3",
42
+ "react-dnd": "^16.0.1",
43
+ "react-dnd-html5-backend": "^16.0.1",
42
44
  "react-password-strength-bar": "^0.4.1",
43
45
  "react-responsive": "^9.0.0",
44
- "react-select": "^5.4.0",
45
- "reactstrap": "^9.1.4",
46
+ "react-select": "^5.5.7",
47
+ "reactstrap": "^9.1.5",
46
48
  "rewire": "^6.0.0",
47
- "sweetalert2": "^11.5.1"
49
+ "sweetalert2": "^11.6.4"
48
50
  },
49
51
  "devDependencies": {
50
- "@types/react": "^18.0.21",
52
+ "@types/react": "^18.0.24",
51
53
  "cross-env": "^7.0.3",
52
54
  "nodemon": "^2.0.20",
53
- "react-intl": "^6.1.2",
55
+ "react-intl": "^6.2.1",
54
56
  "typescript": "^4.8.4"
55
57
  }
56
58
  }
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import {Modal, ModalProps} from "reactstrap";
3
+ import { useBootstrapOptions } from "./BootstrapOptions";
4
+
5
+ export default function BootstrapModal(props: ModalProps) {
6
+ const bsOptions = useBootstrapOptions();
7
+
8
+ return <Modal {...props} toggle={bsOptions.noCloseModal ? undefined : props.toggle} />;
9
+ }
@@ -0,0 +1,25 @@
1
+ import React, {createContext, ReactNode, useContext, useMemo} from "react";
2
+ import BootstrapOptions from "./BootstrapOptions";
3
+
4
+ interface BootstrapOptions {
5
+ noCloseModal: boolean;
6
+ }
7
+
8
+ interface BootstrapOptionsProviderProps extends BootstrapOptions {
9
+ children: ReactNode;
10
+ }
11
+
12
+ const BootstrapOptionsContext = createContext<BootstrapOptions>({
13
+ noCloseModal: false
14
+ });
15
+
16
+ export function useBootstrapOptions() {
17
+ return useContext(BootstrapOptionsContext);
18
+ }
19
+
20
+ export default function BootstrapOptionsProvider({children,noCloseModal}: BootstrapOptionsProviderProps) {
21
+ const options = useMemo(() => ({noCloseModal}), [noCloseModal]);
22
+ return <BootstrapOptionsContext.Provider value={options}>
23
+ { children }
24
+ </BootstrapOptionsContext.Provider>;
25
+ }
@@ -5,6 +5,8 @@ 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
7
  import BootstrapDataTable, { Actions, BootstrapTableProps } from './BootstrapDataTable';
8
+ import BootstrapModal from './BootstrapModal';
9
+ import {useBootstrapOptions} from "./BootstrapOptions";
8
10
 
9
11
  type ModalEntityEditorParams = {
10
12
  entity: any;
@@ -57,7 +59,7 @@ export function ModalEntityEditor({ entity, title, size, url, onReload, disabled
57
59
 
58
60
  return <>
59
61
  { (saved || !open) && url && <Navigate to={url} replace />}
60
- <Modal isOpen size={size} toggle={() => url ? setOpen(false) : onReload(null)} fade={false}>
62
+ <BootstrapModal isOpen size={size} toggle={() => url ? setOpen(false) : onReload(null)} fade={false}>
61
63
  { title && <ModalHeader toggle={() => url ? setOpen(false) : onReload(null)}>
62
64
  <b>{ title }</b>
63
65
  </ModalHeader> }
@@ -83,7 +85,7 @@ export function ModalEntityEditor({ entity, title, size, url, onReload, disabled
83
85
  </ModalFooter>
84
86
  </Form>
85
87
  </ValidatorProvider>
86
- </Modal>
88
+ </BootstrapModal>
87
89
  </>;
88
90
  }
89
91
 
@@ -130,6 +132,8 @@ export default function CRUD(props: CRUDProps) {
130
132
  { !noAdd && <Route path="create" element={<ComponentWrapper Component={Component} url={url} onReload={reload} {...(defaultParams || {})} />} /> }
131
133
  <Route path=":id/edit" element={<ComponentWrapper Component={Component} url={url} onReload={reload} {...(defaultParams || {})} />} />
132
134
  </Routes>
133
- <BootstrapDataTable innerRef={ref} add={(!noAdd && "create") || undefined} {...props} url={apiUrl || url} />
135
+ <BootstrapDataTable innerRef={ref} add={(!noAdd && "create") || undefined} {...props} url={apiUrl || url}>
136
+ {props.children}
137
+ </BootstrapDataTable>
134
138
  </UrlContext.Provider>;
135
139
  }
@@ -1,16 +1,18 @@
1
- import React from "react";
1
+ import React, {useId} from "react";
2
2
  import { FormGroup, Input, InputProps, Label } from "reactstrap";
3
3
 
4
4
  interface CheckBoxProps extends InputProps {
5
- id: string;
5
+ id?: string;
6
6
  type?: "checkbox"|"radio";
7
7
  label?: React.ReactNode;
8
8
  children?: React.ReactNode;
9
9
  }
10
10
 
11
11
  export default function CheckBox(props: CheckBoxProps) {
12
+ const id = useId();
13
+
12
14
  return <FormGroup check>
13
- <Input type={props.type || "checkbox"} {...props} children={undefined} label={undefined} />
14
- <Label check for={props.id}>{props.children || props.label}</Label>
15
+ <Input id={props.id || id} type={props.type || "checkbox"} {...props} children={undefined} label={undefined} />
16
+ <Label check for={props.id || id}>{props.children || props.label}</Label>
15
17
  </FormGroup>;
16
18
  }
@@ -0,0 +1,14 @@
1
+ import React from "react";
2
+ import {Button, ButtonProps} from "reactstrap";
3
+ import { useDragContext } from "react-admin-base";
4
+
5
+ export default function DragAndDropArrow(props: ButtonProps) {
6
+ const [ ref, isDragging ] = useDragContext();
7
+
8
+ if (!ref)
9
+ return null;
10
+
11
+ return <Button type="button" innerRef={ref} outline size="sm" color="primary" {...props}>
12
+ <i className={"fas fa-" + (isDragging ? "circle-dot" : "arrows-up-down-left-right")} />{props.children}
13
+ </Button>;
14
+ }
@@ -4,7 +4,6 @@ import { FormattedMessage } from "react-intl";
4
4
  import { Alert, Form } from 'reactstrap';
5
5
  import LoadingButton from "../Components/LoadingButton";
6
6
  import { ValidationErrors } from './Validator';
7
- import { Navigate } from 'react-router-dom';
8
7
 
9
8
  type EntityEditorParams = {
10
9
  entity: any;
@@ -2,13 +2,15 @@
2
2
  import React, { useCallback } from 'react';
3
3
  import prettysize from 'prettysize';
4
4
  import {Button} from "reactstrap";
5
- import { useApp, useFilePicker, usePreviewComponent } from "react-admin-base";
5
+ import { useApp, useFilePicker, usePreviewComponent, DragAndDropItem } from "react-admin-base";
6
6
  import {FormattedMessage} from "react-intl";
7
+ import DragAndDropArrow from './DragAndDropArrow';
7
8
 
8
9
  const photo_ext = ["png", "jpg", "jpeg", "svg"];
9
10
 
10
11
  function is_photo(name) {
11
- return photo_ext.indexOf(name.split('.')[1]) !== -1;
12
+ const sp = (name || '').split('.');
13
+ return photo_ext.indexOf((sp[sp.length - 1] || '').toLowerCase()) !== -1;
12
14
  }
13
15
 
14
16
  function is_absolute(url) {
@@ -38,7 +40,7 @@ export function Relative({ children }: RelativeProps) {
38
40
  }
39
41
 
40
42
  export function Preview({ value }) {
41
- const name = value.$name;
43
+ const name = value.$name || value.name;
42
44
  const src = value.$blob_url || value.$src;
43
45
 
44
46
  if (is_photo(name)) {
@@ -52,7 +54,7 @@ export function Preview({ value }) {
52
54
  return null;
53
55
  }
54
56
 
55
- export default function FilePickerCore({ disabled, className, accepts, value, onNotify, children, transform } : { disabled?: any, className?: any, accepts?: any, value?:any, onNotify?:any, children?:any, transform?:any }) {
57
+ export default function FilePickerCore({ disabled, index, move, className, accepts, value, onNotify, children, transform } : { disabled?: any, index?: number, move?: any, className?: any, accepts?: any, value?:any, onNotify?:any, children?:any, transform?:any }) {
56
58
  const [ uc, cancel, pick ] = useFilePicker(value, onNotify);
57
59
  const CustomPreview = usePreviewComponent() || Preview;
58
60
 
@@ -78,13 +80,16 @@ export default function FilePickerCore({ disabled, className, accepts, value, on
78
80
  { children && children(uc) }
79
81
  </div>;
80
82
  } else if(uc.$state === 3) { // yuklendi
81
- return <div className={className}>
82
- { !disabled && <Button color="danger" outline size="sm" onClick={cancel}><i className="fa fa-trash" /></Button> }
83
- &nbsp;<Relative><a href={uc.$src} target="_blank" className="btn btn-sm btn-outline-primary"><i className="fa fa-download" /> { uc.name }</a></Relative>
84
- <span>&nbsp;({ prettysize(uc.$size) })</span>
85
- { <CustomPreview value={uc} /> }
86
- { children && children(uc) }
87
- </div>;
83
+ return <DragAndDropItem item={index}>
84
+ <div className={className}>
85
+ <DragAndDropArrow className="me-1" />
86
+ { !disabled && <Button color="danger" outline size="sm" onClick={cancel}><i className="fa fa-trash" /></Button> }
87
+ &nbsp;<Relative><a href={uc.$src} target="_blank" className="btn btn-sm btn-outline-primary"><i className="fa fa-download" /> { uc.name }</a></Relative>
88
+ <span>&nbsp;({ prettysize(uc.$size) })</span>
89
+ { <CustomPreview value={uc} /> }
90
+ { children && children(uc) }
91
+ </div>
92
+ </DragAndDropItem>;
88
93
  }
89
94
 
90
95
  return null;
@@ -2,7 +2,6 @@ import React from 'react';
2
2
  import {FormattedMessage} from "react-intl";
3
3
 
4
4
  export default class GoToTop extends React.Component {
5
-
6
5
  state = {show: false};
7
6
 
8
7
  scrollTop(e) {
@@ -12,7 +11,7 @@ export default class GoToTop extends React.Component {
12
11
  }
13
12
 
14
13
  handleScroll(e) {
15
- var newShow = window.scrollY > 100;
14
+ const newShow = window.scrollY > 100;
16
15
  if (newShow !== this.state.show) {
17
16
  this.setState({show: newShow});
18
17
  }
@@ -1,9 +1,9 @@
1
1
 
2
- import React, { useMemo } from 'react';
3
- import { useMultiFilePicker } from "react-admin-base";
4
- import { FormattedMessage } from "react-intl";
5
- import { Button } from "reactstrap";
6
- import FilePickerCore from "./FilePickerCore";
2
+ import React, { useMemo } from 'react';
3
+ import { useMultiFilePicker, DragAndDropProvider } from "react-admin-base";
4
+ import { FormattedMessage } from "react-intl";
5
+ import { Button } from "reactstrap";
6
+ import FilePickerCore from "./FilePickerCore";
7
7
 
8
8
  type MultiFilePickerProps = {
9
9
  disabled?: boolean;
@@ -11,12 +11,13 @@ type MultiFilePickerProps = {
11
11
  accepts?: string;
12
12
  value: any;
13
13
  onChange: (value: any) => void;
14
+ noMove?: boolean;
14
15
  children?: (value: any) => React.ReactNode;
15
16
  }
16
17
 
17
- export default function MultiFilePicker({ disabled, className, accepts, value, onChange, children }: MultiFilePickerProps) {
18
+ export default function MultiFilePicker({ disabled, className, noMove, accepts, value, onChange, children }: MultiFilePickerProps) {
18
19
  const uniqueIdList = useMemo(() => [] as any, []);
19
- const [ controllers, _onChange, chooseFile ] = useMultiFilePicker(value, onChange);
20
+ const [ controllers, _onChange, chooseFile, onMove ] = useMultiFilePicker(value, onChange);
20
21
 
21
22
  function getConstantUniqueIdFor(element) {
22
23
  if (uniqueIdList.indexOf(element) < 0) {
@@ -31,13 +32,16 @@ export default function MultiFilePicker({ disabled, className, accepts, value, o
31
32
  </Button>
32
33
  { children && children(null) }
33
34
 
34
- { controllers.map((a,i) => <FilePickerCore
35
- key={getConstantUniqueIdFor(a)}
36
- disabled={!!disabled}
37
- className="mt-2"
38
- accepts={accepts}
39
- value={a}
40
- onNotify={_onChange.bind(null, a)}
41
- >{children}</FilePickerCore>) }
35
+ <DragAndDropProvider onMove={!noMove && onMove}>
36
+ { controllers.map((a,i) => <FilePickerCore
37
+ key={getConstantUniqueIdFor(a)}
38
+ disabled={!!disabled}
39
+ className="mt-2"
40
+ accepts={accepts}
41
+ value={a}
42
+ index={i}
43
+ onNotify={_onChange.bind(null, a)}
44
+ >{children}</FilePickerCore>) }
45
+ </DragAndDropProvider>
42
46
  </div>;
43
47
  }
@@ -1,5 +1,5 @@
1
1
  import React, { createContext, Dispatch, useContext, useEffect, useMemo, useReducer, useRef } from "react";
2
- import { useApp, useLocalStorage } from "react-admin-base";
2
+ import { useLocalStorage } from "react-admin-base";
3
3
 
4
4
  const ThemeContext = createContext(null as any);
5
5
  const AllThemesContext = createContext(null as any);
package/src/index.ts CHANGED
@@ -21,6 +21,9 @@ import ThemeProvider, { useTheme, useAllThemes } from './Components/ThemeProvide
21
21
  import StepList, { StepItem } from './Components/StepList';
22
22
  import PasswordInput from './Components/PasswordInput';
23
23
  import DefaultValidatorOptions from './Components/DefaultValidatorOptions';
24
+ import DragAndDropArrow from './Components/DragAndDropArrow';
25
+ import BootstrapOptionsProvider, { useBootstrapOptions } from './Components/BootstrapOptions';
26
+ import BootstrapModal from './Components/BootstrapModal';
24
27
 
25
28
  export {
26
29
  ThemeProvider, useTheme, useAllThemes,
@@ -47,5 +50,9 @@ export {
47
50
  RowRenderer,
48
51
  LanguageProvider, useLanguage, LanguageSwitcher,
49
52
  ErrorBoundary,
50
- CheckBox
53
+ CheckBox,
54
+ DragAndDropArrow,
55
+ useBootstrapOptions,
56
+ BootstrapOptionsProvider,
57
+ BootstrapModal
51
58
  };