react-admin-base-bootstrap 0.9.4 → 0.9.6

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.
package/bun.lockb CHANGED
Binary file
@@ -14,6 +14,7 @@ export interface ApiSelectProps<Option = any> {
14
14
  disabled?: boolean;
15
15
  placeholder?: string;
16
16
  staticOptions?: any[];
17
+ sortable?: boolean;
17
18
  onAddOrEdit?: (item: any) => void;
18
19
  getNewOptionData?: (name: string, elem: React.ReactNode) => any | null;
19
20
  }
@@ -12,6 +12,12 @@ import { RefreshScope, useFetch, useRefresh } from 'react-admin-base';
12
12
  import { FormattedMessage, useIntl } from 'react-intl';
13
13
  import Select, { components } from "react-select";
14
14
  import CreatableSelect from 'react-select/creatable';
15
+ import { SortableContainer, SortableElement, SortableHandle, } from 'react-sortable-hoc';
16
+ function arrayMove(array, from, to) {
17
+ const slicedArray = array.slice();
18
+ slicedArray.splice(to < 0 ? array.length + to : to, 0, slicedArray.splice(from, 1)[0]);
19
+ return slicedArray;
20
+ }
15
21
  function Option(props) {
16
22
  return React.createElement(components.Option, Object.assign({}, props), (props.selectProps.children && props.selectProps.children(props.data)) || (props.data.__isNew__ ? React.createElement(FormattedMessage, { id: "CREATE_VALUE", values: { text: props.children } }) : props.children));
17
23
  }
@@ -47,8 +53,20 @@ function MultiValueRemove(props) {
47
53
  React.createElement(components.MultiValueRemove, Object.assign({}, props)));
48
54
  }
49
55
  const Components = { Option, SingleValue, MultiValue, IndicatorsContainer, MultiValueRemove };
56
+ const SortableMultiValue = SortableElement((props) => {
57
+ const onMouseDown = (e) => {
58
+ e.preventDefault();
59
+ e.stopPropagation();
60
+ };
61
+ const innerProps = Object.assign(Object.assign({}, props.innerProps), { onMouseDown });
62
+ return React.createElement(MultiValue, Object.assign({}, props, { innerProps: innerProps }));
63
+ });
64
+ const SortableMultiValueLabel = SortableHandle((props) => React.createElement(components.MultiValueLabel, Object.assign({}, props)));
65
+ const SortableComponents = { Option, SingleValue, MultiValue: SortableMultiValue, MultiValueLabel: SortableMultiValueLabel, IndicatorsContainer, MultiValueRemove };
66
+ const SortableSelect = SortableContainer(Select);
67
+ const SortableCreateableSelect = SortableContainer(CreatableSelect);
50
68
  export default function ApiSelect(props) {
51
- const { disabled, url, getOptionLabel, getOptionValue, idKey, nameKey, filter, group, onCreateOption, getNewOptionData, isMulti, onChange, value, placeholder, staticOptions } = props;
69
+ const { disabled, url, getOptionLabel, sortable, getOptionValue, idKey, nameKey, filter, group, onCreateOption, getNewOptionData, isMulti, onChange, value, placeholder, staticOptions } = props;
52
70
  const intl = useIntl();
53
71
  const [search, setSearch] = useState('');
54
72
  const params = useMemo(() => ({ query: search }), [search]);
@@ -86,9 +104,13 @@ export default function ApiSelect(props) {
86
104
  const onMenuClose = useCallback(function () {
87
105
  setIsMenuOpen(false);
88
106
  }, [setIsMenuOpen]);
89
- const Component = onCreateOption ? CreatableSelect : Select;
107
+ const onSortEnd = useCallback(({ oldIndex, newIndex }) => {
108
+ const newValue = arrayMove(value, oldIndex, newIndex);
109
+ onChange(newValue);
110
+ }, [value, onChange]);
111
+ const Component = (onCreateOption ? (sortable && isMulti ? SortableCreateableSelect : CreatableSelect) : (sortable && isMulti ? SortableSelect : Select));
90
112
  return React.createElement(RefreshScope, { update: update },
91
- React.createElement(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 })));
113
+ React.createElement(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: (isMulti && sortable ? SortableComponents : 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, axis: "xy", onSortEnd: onSortEnd, distance: 4, getHelperDimensions: ({ node }) => node.getBoundingClientRect() })));
92
114
  }
93
115
  export function CreateSelect(props) {
94
116
  const { Component, onChange, value, isMulti, idKey } = props;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-admin-base-bootstrap",
3
- "version": "0.9.4",
3
+ "version": "0.9.6",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",
@@ -44,6 +44,7 @@
44
44
  "react-password-strength-bar": "^0.4.1",
45
45
  "react-responsive": "^9.0.2",
46
46
  "react-select": "^5.8.0",
47
+ "react-sortable-hoc": "1.11.0",
47
48
  "reactstrap": "^9.2.2",
48
49
  "sweetalert2": "^11.10.4"
49
50
  },
@@ -5,6 +5,24 @@ import { FormattedMessage, useIntl } from 'react-intl';
5
5
  import Select, { components } from "react-select";
6
6
  import CreatableSelect from 'react-select/creatable';
7
7
 
8
+ import {
9
+ SortableContainer,
10
+ SortableElement,
11
+ SortEndHandler,
12
+ SortableHandle,
13
+ } from 'react-sortable-hoc';
14
+
15
+ function arrayMove<T>(array: readonly T[], from: number, to: number) {
16
+ const slicedArray = array.slice();
17
+ slicedArray.splice(
18
+ to < 0 ? array.length + to : to,
19
+ 0,
20
+ slicedArray.splice(from, 1)[0]
21
+ );
22
+ return slicedArray;
23
+ }
24
+
25
+
8
26
  function Option(props) {
9
27
  return <components.Option {...props}>
10
28
  { (props.selectProps.children && props.selectProps.children(props.data)) || (props.data.__isNew__ ? <FormattedMessage
@@ -42,7 +60,7 @@ function EditOrAddIndicator(props) {
42
60
  className
43
61
  )}
44
62
  css={getStyles('clearIndicator', props)}
45
- onMouseDown={e => {
63
+ onMouseDown={e => {
46
64
  e.stopPropagation();
47
65
  e.preventDefault();
48
66
  props.selectProps.onAddOrEdit();
@@ -73,6 +91,26 @@ function MultiValueRemove(props) {
73
91
 
74
92
  const Components = { Option, SingleValue, MultiValue, IndicatorsContainer, MultiValueRemove };
75
93
 
94
+ const SortableMultiValue = SortableElement(
95
+ (props) => {
96
+ const onMouseDown = (e) => {
97
+ e.preventDefault();
98
+ e.stopPropagation();
99
+ };
100
+ const innerProps = { ...props.innerProps, onMouseDown };
101
+ return <MultiValue {...props} innerProps={innerProps} />;
102
+ }
103
+ );
104
+
105
+ const SortableMultiValueLabel = SortableHandle(
106
+ (props) => <components.MultiValueLabel {...props} />
107
+ );
108
+
109
+ const SortableComponents = { Option, SingleValue, MultiValue: SortableMultiValue, MultiValueLabel: SortableMultiValueLabel, IndicatorsContainer, MultiValueRemove };
110
+
111
+ const SortableSelect = SortableContainer(Select);
112
+ const SortableCreateableSelect = SortableContainer(CreatableSelect);
113
+
76
114
  export interface ApiSelectProps<Option = any> {
77
115
  url?: string;
78
116
  value: Option|Option[];
@@ -88,12 +126,14 @@ export interface ApiSelectProps<Option = any> {
88
126
  disabled?: boolean;
89
127
  placeholder?: string;
90
128
  staticOptions?: any[];
129
+ sortable?: boolean;
91
130
  onAddOrEdit?: (item: any) => void;
92
131
  getNewOptionData?: (name: string, elem: React.ReactNode) => any|null;
93
132
  }
94
133
 
134
+
95
135
  export default function ApiSelect<Option = any>(props: ApiSelectProps<Option>) {
96
- const { disabled, url, getOptionLabel, getOptionValue, idKey, nameKey, filter, group, onCreateOption, getNewOptionData, isMulti, onChange, value, placeholder, staticOptions } = props;
136
+ const { disabled, url, getOptionLabel, sortable, getOptionValue, idKey, nameKey, filter, group, onCreateOption, getNewOptionData, isMulti, onChange, value, placeholder, staticOptions } = props;
97
137
  const intl = useIntl();
98
138
  const [ search, setSearch ] = useState('');
99
139
  const params = useMemo(() => ({ query: search }), [search]);
@@ -133,18 +173,23 @@ export default function ApiSelect<Option = any>(props: ApiSelectProps<Option>) {
133
173
  setIsMenuOpen(false);
134
174
  }, [ setIsMenuOpen ]);
135
175
 
136
- const Component = onCreateOption ? CreatableSelect : Select;
176
+ const onSortEnd: SortEndHandler = useCallback(({ oldIndex, newIndex }) => {
177
+ const newValue = arrayMove(value as any, oldIndex, newIndex);
178
+ onChange(newValue as any);
179
+ }, [ value, onChange ]);
180
+
181
+ const Component = (onCreateOption ? (sortable && isMulti ? SortableCreateableSelect : CreatableSelect) : (sortable && isMulti ? SortableSelect : Select)) as any;
137
182
 
138
183
  return <RefreshScope update={update}>
139
184
  <Component
140
185
  {...props}
141
186
  className='react-select-container'
142
187
  classNamePrefix="react-select"
143
- onCreateOption={onCreateOption && handleCreateOption}
188
+ onCreateOption={(onCreateOption && handleCreateOption) as any}
144
189
  getNewOptionData={(onCreateOption && (getNewOptionData || ((inputValue) =>( { [nameKey || 'name']: inputValue, __isNew__: true })))) || undefined}
145
190
  inputValue={search}
146
191
  onInputChange={a => setSearch(a)}
147
- components={Components}
192
+ components={(isMulti && sortable ? SortableComponents : Components) as any}
148
193
  isLoading={!!loading || creating}
149
194
  getOptionLabel={getOptionLabel || ((row:any) => row[nameKey || 'name'])}
150
195
  getOptionValue={getOptionValue || ((row:any) => row[idKey || 'id'])}
@@ -155,6 +200,11 @@ export default function ApiSelect<Option = any>(props: ApiSelectProps<Option>) {
155
200
  options={!options ? [] : ((filter && options.filter(filter)) || options)}
156
201
  onMenuOpen={onMenuOpen}
157
202
  onMenuClose={onMenuClose}
203
+
204
+ axis="xy"
205
+ onSortEnd={onSortEnd}
206
+ distance={4}
207
+ getHelperDimensions={({ node }) => node.getBoundingClientRect()}
158
208
  />
159
209
  </RefreshScope>;
160
210
  }