ordering-ui-admin-external 1.44.100 → 1.45.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.
@@ -1,4 +1,4 @@
1
- import React, { useState, useEffect } from 'react'
1
+ import React, { useState, useEffect, useRef } from 'react'
2
2
  import {
3
3
  useLanguage,
4
4
  useConfig,
@@ -59,7 +59,8 @@ const ScheduleUI = (props) => {
59
59
  const [alertState, setAlertState] = useState({ open: false, content: [] })
60
60
  const [confirm, setConfirm] = useState({ open: false, content: null, handleOnAccept: null })
61
61
 
62
- const [scheduleOptions, setScheduleOptions] = useState([])
62
+ const minuteOptions = useRef([])
63
+ const hourOptions = useRef([])
63
64
  const [isOpenCopytimes, setIsOpenCopytimes] = useState(null)
64
65
 
65
66
  const daysOfWeek = [
@@ -115,53 +116,24 @@ const ScheduleUI = (props) => {
115
116
  }, [isConflict])
116
117
 
117
118
  useEffect(() => {
118
- const _scheduleOptions = []
119
- for (let hour = 0; hour < 24; hour++) {
120
- let hh = ''
121
- let meridian = ''
122
- if (!is12Hours) hh = hour < 10 ? `0${hour}` : hour
123
- else {
124
- if (hour === 0) {
125
- hh = '12'
126
- meridian = ' ' + t('AM', 'AM')
127
- } else if (hour > 0 && hour < 12) {
128
- hh = (hour < 10 ? '0' + hour : hour)
129
- meridian = ' ' + t('AM', 'AM')
130
- } else if (hour === 12) {
131
- hh = '12'
132
- meridian = ' ' + t('PM', 'PM')
133
- } else {
134
- hh = ((hour - 12 < 10) ? '0' + (hour - 12) : (hour - 12))
135
- meridian = ' ' + t('PM', 'PM')
136
- }
137
- }
138
- for (let min = 0; min < 4; min++) {
139
- _scheduleOptions.push({
140
- value: hour + ':' + min * 15,
141
- content: (
142
- <Option>
143
- {is12Hours ? (
144
- <>
145
- {hh}:{min === 0 ? '00' : min * 15} {meridian}
146
- </>
147
- ) : (
148
- <>
149
- {hh} : {min === 0 ? '00' : min * 15}
150
- </>
151
- )}
152
- </Option>
153
- )
154
- })
155
- }
119
+ const generateOptions = (count, formatFn) => {
120
+ return Array.from({ length: count }, (_, i) => ({
121
+ value: i,
122
+ content: <Option>{formatFn(i)}</Option>
123
+ }))
156
124
  }
157
- _scheduleOptions.push({
158
- value: '23:59',
159
- content: (
160
- <Option>{is12Hours ? '11:59 PM' : '23 : 59'}</Option>
161
- )
162
- })
163
- setScheduleOptions(_scheduleOptions)
164
- }, [])
125
+
126
+ const formatMinute = (i) => (i < 10 ? `0${i}` : i)
127
+ const formatHour = (hour) => {
128
+ if (!is12Hours) return hour < 10 ? `0${hour}` : hour
129
+ if (hour === 0) return `12 ${t('AM', 'AM')}`
130
+ if (hour < 12) return `${hour} ${t('AM', 'AM')}`
131
+ if (hour === 12) return `12 ${t('PM', 'PM')}`
132
+ return `${hour - 12} ${t('PM', 'PM')}`
133
+ }
134
+ minuteOptions.current = generateOptions(60, formatMinute)
135
+ hourOptions.current = generateOptions(24, formatHour)
136
+ }, [is12Hours])
165
137
 
166
138
  return (
167
139
  <>
@@ -184,95 +156,117 @@ const ScheduleUI = (props) => {
184
156
  )}
185
157
  </DateWrapper>
186
158
  </div>
187
- {schedule?.enabled ? (
188
- <div>
189
- {schedule?.lapses.map((lapse, index) => (
190
- <div
191
- key={index}
192
- >
193
- <SelectWrapper>
194
- <DefaultSelect
195
- noSelected
196
- options={scheduleOptions}
197
- defaultValue={
198
- lapse?.open?.hour === 23 && lapse?.open?.minute === 59
199
- ? `${lapse?.open?.hour}:${lapse?.open?.minute}`
200
- : `${lapse?.open?.hour}:${parseInt(lapse?.open?.minute / 15) * 15}`
201
- }
202
- onChange={val => handleChangeScheduleTime(val, daysOfWeekIndex, index, true)}
203
- optionInnerMaxHeight='300px'
204
- />
205
- </SelectWrapper>
206
- <SplitLine />
207
- <SelectWrapper>
208
- <DefaultSelect
209
- noSelected
210
- options={scheduleOptions}
211
- defaultValue={
212
- lapse?.close?.hour === 23 && lapse?.close?.minute === 59
213
- ? `${lapse?.close?.hour}:${lapse?.close?.minute}`
214
- : `${lapse?.close?.hour}:${parseInt(lapse?.close?.minute / 15) * 15}`
215
- }
216
- onChange={val => handleChangeScheduleTime(val, daysOfWeekIndex, index, false)}
217
- optionInnerMaxHeight='300px'
218
- />
219
- </SelectWrapper>
220
- <TrashIconWrapper
221
- isHide={schedule?.lapses.length <= 1}
159
+ {schedule?.enabled
160
+ ? (
161
+ <div>
162
+ {schedule?.lapses.map((lapse, index) => (
163
+ <div
164
+ key={index}
222
165
  >
223
- {!disableSchedule && (
224
- <Trash
225
- onClick={() => onClickDelete(daysOfWeekIndex, index)}
166
+ <SelectWrapper>
167
+ <DefaultSelect
168
+ noSelected
169
+ options={hourOptions.current}
170
+ defaultValue={lapse?.open?.hour}
171
+ onChange={val => handleChangeScheduleTime(val, daysOfWeekIndex, index, true, 'hour')}
172
+ optionInnerMaxHeight='300px'
226
173
  />
227
- )}
228
- </TrashIconWrapper>
229
- </div>
230
- ))}
231
- {openAddSchedule[daysOfWeekIndex] && (
232
- <div>
233
- <SelectWrapper>
234
- <DefaultSelect
235
- noSelected
236
- options={scheduleOptions}
237
- defaultValue={
238
- addScheduleTime?.open?.hour === 23 && addScheduleTime?.open?.minute === 59
239
- ? `${addScheduleTime?.open?.hour}:${addScheduleTime?.open?.minute}`
240
- : `${addScheduleTime?.open?.hour}:${parseInt(addScheduleTime?.open?.minute / 15) * 15}`
241
- }
242
- optionInnerMaxHeight='300px'
243
- onChange={val => handleChangeAddScheduleTime(val, true)}
244
- />
245
- </SelectWrapper>
246
- <SplitLine />
247
- <SelectWrapper>
248
- <DefaultSelect
249
- noSelected
250
- options={scheduleOptions}
251
- defaultValue={
252
- addScheduleTime?.close?.hour === 23 && addScheduleTime?.close?.minute === 59
253
- ? `${addScheduleTime?.close?.hour}:${addScheduleTime?.close?.minute}`
254
- : `${addScheduleTime?.close?.hour}:${parseInt(addScheduleTime?.close?.minute / 15) * 15}`
255
- }
256
- optionInnerMaxHeight='300px'
257
- onChange={val => handleChangeAddScheduleTime(val, false)}
258
- />
259
- </SelectWrapper>
260
- <AddScheduleIconWrapper>
261
- <PlusCircleFill
262
- onClick={() => handleAddSchedule(daysOfWeekIndex)}
263
- />
264
- <DashCircleFill
265
- onClick={() => handleOpenAddSchedule(null)}
266
- />
267
- </AddScheduleIconWrapper>
268
- </div>
269
- )}
270
- </div>
271
- ) : (
272
- <div>
273
- <p>{t('UNAVAILABLE', 'Unavailable')}</p>
274
- </div>
275
- )}
174
+ </SelectWrapper>
175
+ <SelectWrapper>
176
+ <DefaultSelect
177
+ noSelected
178
+ options={minuteOptions.current}
179
+ defaultValue={lapse?.open?.minute}
180
+ onChange={val => handleChangeScheduleTime(val, daysOfWeekIndex, index, true, 'minute')}
181
+ optionInnerMaxHeight='300px'
182
+ />
183
+ </SelectWrapper>
184
+ <SplitLine />
185
+ <SelectWrapper>
186
+ <DefaultSelect
187
+ noSelected
188
+ options={hourOptions.current}
189
+ defaultValue={lapse?.close?.hour}
190
+ onChange={val => handleChangeScheduleTime(val, daysOfWeekIndex, index, false, 'hour')}
191
+ optionInnerMaxHeight='300px'
192
+ />
193
+ </SelectWrapper>
194
+ <SelectWrapper>
195
+ <DefaultSelect
196
+ noSelected
197
+ options={minuteOptions.current}
198
+ defaultValue={lapse?.close?.minute}
199
+ onChange={val => handleChangeScheduleTime(val, daysOfWeekIndex, index, false, 'minute')}
200
+ optionInnerMaxHeight='300px'
201
+ />
202
+ </SelectWrapper>
203
+ <TrashIconWrapper
204
+ isHide={schedule?.lapses.length <= 1}
205
+ >
206
+ {!disableSchedule && (
207
+ <Trash
208
+ onClick={() => onClickDelete(daysOfWeekIndex, index)}
209
+ />
210
+ )}
211
+ </TrashIconWrapper>
212
+ </div>
213
+ ))}
214
+ {openAddSchedule[daysOfWeekIndex] && (
215
+ <div>
216
+ <SelectWrapper>
217
+ <DefaultSelect
218
+ noSelected
219
+ options={hourOptions.current}
220
+ defaultValue={addScheduleTime?.open?.hour}
221
+ onChange={val => handleChangeAddScheduleTime(val, true, 'hour')}
222
+ optionInnerMaxHeight='300px'
223
+ />
224
+ </SelectWrapper>
225
+ <SelectWrapper>
226
+ <DefaultSelect
227
+ noSelected
228
+ options={minuteOptions.current}
229
+ defaultValue={addScheduleTime?.open?.minute}
230
+ onChange={val => handleChangeAddScheduleTime(val, true, 'minute')}
231
+ optionInnerMaxHeight='300px'
232
+ />
233
+ </SelectWrapper>
234
+ <SplitLine />
235
+ <SelectWrapper>
236
+ <DefaultSelect
237
+ noSelected
238
+ options={hourOptions.current}
239
+ defaultValue={addScheduleTime?.close?.hour}
240
+ onChange={val => handleChangeAddScheduleTime(val, false, 'hour')}
241
+ optionInnerMaxHeight='300px'
242
+ />
243
+ </SelectWrapper>
244
+ <SelectWrapper>
245
+ <DefaultSelect
246
+ noSelected
247
+ options={minuteOptions.current}
248
+ defaultValue={addScheduleTime?.close?.minute}
249
+ onChange={val => handleChangeAddScheduleTime(val, false, 'minute')}
250
+ optionInnerMaxHeight='300px'
251
+ />
252
+ </SelectWrapper>
253
+ <AddScheduleIconWrapper>
254
+ <PlusCircleFill
255
+ onClick={() => handleAddSchedule(daysOfWeekIndex)}
256
+ />
257
+ <DashCircleFill
258
+ onClick={() => handleOpenAddSchedule(null)}
259
+ />
260
+ </AddScheduleIconWrapper>
261
+ </div>
262
+ )}
263
+ </div>
264
+ )
265
+ : (
266
+ <div>
267
+ <p>{t('UNAVAILABLE', 'Unavailable')}</p>
268
+ </div>
269
+ )}
276
270
  {!disableSchedule && (
277
271
  <div>
278
272
  <IconWrapper
@@ -22,17 +22,12 @@ export const TimeScheduleItemContainer = styled.div`
22
22
  }
23
23
 
24
24
  &:first-child {
25
- min-width: 95px;
25
+ min-width: 70px;
26
26
  }
27
27
 
28
28
  &:nth-child(2) {
29
29
  flex-direction: column;
30
30
  flex: 1;
31
- ${props => props.theme?.rtl ? css`
32
- padding-right: 8px;
33
- ` : css`
34
- padding-left: 8px;
35
- `}
36
31
  > div {
37
32
  display: flex;
38
33
  justify-content: center;
@@ -40,7 +35,6 @@ export const TimeScheduleItemContainer = styled.div`
40
35
  &:not(:last-child) {
41
36
  margin-bottom: 10px;
42
37
  }
43
-
44
38
  svg {
45
39
  font-size: 18px;
46
40
  cursor: pointer;
@@ -58,9 +52,11 @@ export const TimeScheduleItemContainer = styled.div`
58
52
  cursor: pointer;
59
53
  font-size: 18px;
60
54
  color: ${props => props.theme.colors.primary};
61
- ${props => props.theme?.rtl ? css`
55
+ ${props => props.theme?.rtl
56
+ ? css`
62
57
  margin-left: 10px;
63
- ` : css`
58
+ `
59
+ : css`
64
60
  margin-right: 10px;
65
61
  `}
66
62
  }
@@ -125,7 +121,8 @@ export const SelectWrapper = styled.div`
125
121
  }
126
122
 
127
123
  @media (min-width: 450px) {
128
- width: 95px;
124
+ width: 70px;
125
+ margin: 0px 5px;
129
126
  .select {
130
127
  > div {
131
128
  font-size: 16px;
@@ -146,10 +143,12 @@ export const SplitLine = styled.div`
146
143
  background-color: ${props => props.theme.colors.disabled};
147
144
  `
148
145
  export const IconWrapper = styled.span`
149
- ${({ isHide }) => isHide ? css`
146
+ ${({ isHide }) => isHide
147
+ ? css`
150
148
  opacity: 0;
151
149
  pointer-events: none;
152
- ` : css`
150
+ `
151
+ : css`
153
152
  opacity: 1;
154
153
  `}
155
154
  `
@@ -157,10 +156,12 @@ export const TrashIconWrapper = styled.div`
157
156
  display: flex;
158
157
  justify-content: center;
159
158
  width: 50px;
160
- ${({ isHide }) => isHide ? css`
159
+ ${({ isHide }) => isHide
160
+ ? css`
161
161
  opacity: 0;
162
162
  pointer-events: none;
163
- ` : css`
163
+ `
164
+ : css`
164
165
  opacity: 1;
165
166
  `}
166
167
  @media (min-width: 450px) {
@@ -174,9 +175,11 @@ export const AddScheduleIconWrapper = styled.div`
174
175
  width: 50px;
175
176
  > svg {
176
177
  color: ${props => props.theme.colors.primary};
177
- ${props => props.theme?.rtl ? css`
178
+ ${props => props.theme?.rtl
179
+ ? css`
178
180
  margin-right: 8px;
179
- ` : css`
181
+ `
182
+ : css`
180
183
  margin-left: 8px;
181
184
  `}
182
185
  &:last-child {
@@ -4,7 +4,9 @@ import RiCheckboxFill from '@meronex/icons/ri/RiCheckboxFill'
4
4
  import { useLanguage } from 'ordering-components-admin-external'
5
5
  import MdcContentCopy from '@meronex/icons/mdc/MdcContentCopy'
6
6
  import { Button } from '../../../styles'
7
-
7
+ import {
8
+ X as CloseIcon
9
+ } from 'react-bootstrap-icons'
8
10
  import {
9
11
  HeaderItem,
10
12
  PopoverBody,
@@ -37,15 +39,6 @@ export const ScheduleCopyTimes = (props) => {
37
39
  { value: 6, content: t('DAY6', 'Saturday') }
38
40
  ]
39
41
 
40
- const handleClickOutside = (e) => {
41
- if (!open) return
42
- const outsidePopover = !popperElement.current?.contains(e.target)
43
- const outsidePopoverMenu = !referenceElement.current?.contains(e.target)
44
- if (outsidePopover && outsidePopoverMenu) {
45
- props.onClose && props.onClose()
46
- }
47
- }
48
-
49
42
  const handleKeyDown = (e) => {
50
43
  if (e.keyCode === 27) {
51
44
  props.onClose && props.onClose()
@@ -53,10 +46,8 @@ export const ScheduleCopyTimes = (props) => {
53
46
  }
54
47
 
55
48
  useEffect(() => {
56
- window.addEventListener('mouseup', handleClickOutside)
57
49
  window.addEventListener('keydown', handleKeyDown)
58
50
  return () => {
59
- window.removeEventListener('mouseup', handleClickOutside)
60
51
  window.removeEventListener('keydown', handleKeyDown)
61
52
  }
62
53
  }, [open])
@@ -77,6 +68,7 @@ export const ScheduleCopyTimes = (props) => {
77
68
  </HeaderItem>
78
69
  {open && (
79
70
  <PopoverBody ref={popperElement}>
71
+ <CloseIcon className='close-icon' onClick={() => props.onClose && props.onClose()} />
80
72
  <Title>{t('COPY_TIMES_TO', 'Copy times to')}</Title>
81
73
  <PopoverList>
82
74
  {daysOptions.map(option => (
@@ -30,15 +30,24 @@ export const PopoverBody = styled.div`
30
30
  border-radius: 6px;
31
31
 
32
32
  ${props => props.theme?.rtl ? css`
33
- left: 0px;
33
+ left: 60px;
34
34
  ` : css`
35
- right: 0px;
35
+ right: 60px;
36
36
  `}
37
37
 
38
38
  > button {
39
39
  width: calc(100% - 20px);
40
40
  margin: 5px 10px 0 10px;
41
41
  }
42
+ .close-icon {
43
+ position: absolute;
44
+ width: 28px;
45
+ height: 28px;
46
+ z-index: 100;
47
+ right: 0px;
48
+ top: 0px;
49
+ cursor: pointer;
50
+ }
42
51
  `
43
52
 
44
53
  export const Title = styled.div`
@@ -89,4 +98,4 @@ export const CopyItem = styled.div`
89
98
  color: ${props => props.theme.colors?.primary};
90
99
  }
91
100
  `}
92
- `
101
+ `
@@ -21,7 +21,7 @@ import {
21
21
  } from './styles'
22
22
  import { PaginationWrapper } from '../MultiSelect/styles'
23
23
 
24
- export const Select = (props) => {
24
+ export const Select = React.memo((props) => {
25
25
  const {
26
26
  placeholder,
27
27
  options,
@@ -237,4 +237,11 @@ export const Select = (props) => {
237
237
  </PopoverBody>
238
238
  </div>
239
239
  )
240
- }
240
+ }, (prevProps, nextProps) => {
241
+ return prevProps.defaultValue === nextProps.defaultValue &&
242
+ prevProps.options === nextProps.options &&
243
+ prevProps.searchValue === nextProps.searchValue &&
244
+ prevProps.pagination === nextProps.pagination
245
+ })
246
+
247
+ Select.displayName = 'Select'