forstok-ui-lib 6.20.2 → 6.21.2
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/dist/index.d.ts +10 -49
- package/dist/index.js +571 -1167
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +569 -1165
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/assets/javascripts/function.ts +21 -0
- package/src/assets/javascripts/helper.ts +11 -2
- package/src/components/index.ts +0 -1
- package/src/components/link/index.tsx +4 -1
- package/src/components/link/styles.ts +152 -144
- package/src/components/link/typed.ts +10 -0
- package/src/typeds/shares.typed.ts +26 -26
- package/src/components/masterTable/index.tsx +0 -649
- package/src/components/masterTable/partials/datas/confirm.tsx +0 -92
- package/src/components/masterTable/partials/datas/index.tsx +0 -81
- package/src/components/masterTable/partials/editors/date.bare.tsx +0 -39
- package/src/components/masterTable/partials/editors/date.tsx +0 -123
- package/src/components/masterTable/partials/editors/image.tsx +0 -61
- package/src/components/masterTable/partials/editors/input.bare.tsx +0 -127
- package/src/components/masterTable/partials/editors/input.tsx +0 -140
- package/src/components/masterTable/partials/editors/label.tsx +0 -128
- package/src/components/masterTable/partials/editors/select.bare.tsx +0 -104
- package/src/components/masterTable/partials/editors/select.tsx +0 -142
- package/src/components/masterTable/partials/editors/switch.tsx +0 -56
- package/src/components/masterTable/partials/editors/tag.tsx +0 -49
- package/src/components/masterTable/partials/editors/textarea.tsx +0 -7
- package/src/components/masterTable/styles.tsx +0 -1011
- package/src/components/masterTable/typed.ts +0 -87
|
@@ -1,649 +0,0 @@
|
|
|
1
|
-
import { useEffect, useState, useCallback } from 'react';
|
|
2
|
-
import IconComponent from '../icon';
|
|
3
|
-
import ButtonComponent from '../button';
|
|
4
|
-
import { pageMasterTable } from '../../assets/javascripts/helper';
|
|
5
|
-
import { BulkActionWrapper, InitialContainer, MasterTableActionWrapper } from '../../assets/stylesheets/shares.styles';
|
|
6
|
-
import { MasterTable, MasterTableWrapper, MasterTableViewport, MasterTableCanvas, MasterTableHeaderWrapper, MasterTableHeaderContainer, MasterTableBodyWrapper, IsMassContainer } from './styles';
|
|
7
|
-
import type { THeadProps, TMasterProps } from '../../typeds/shares.typed';
|
|
8
|
-
import type { TMouseEvent, TObject } from '../../typeds/base.typed';
|
|
9
|
-
import type { TReloadField } from './typed';
|
|
10
|
-
import ConfirmDataPartial from './partials/datas/confirm';
|
|
11
|
-
import DataPartial from './partials/datas';
|
|
12
|
-
import ImageComponent from '../image';
|
|
13
|
-
import TextComponent from '../text';
|
|
14
|
-
import CheckboxComponent from '../checkbox';
|
|
15
|
-
import LinkComponent from '../link';
|
|
16
|
-
import { evGenerateValueMatch, generateMessage, generateMessageQuestion, generateValue, validateByApproveJs } from '../../assets/javascripts/function';
|
|
17
|
-
|
|
18
|
-
import DateEditors from './partials/editors/date';
|
|
19
|
-
import DateBareEditors from './partials/editors/date.bare';
|
|
20
|
-
import InputEditors from './partials/editors/input';
|
|
21
|
-
import InputBareEditors from './partials/editors/input.bare';
|
|
22
|
-
import ImageEditors from './partials/editors/image';
|
|
23
|
-
import LabelEditors from './partials/editors/label';
|
|
24
|
-
import SelectEditors from './partials/editors/select';
|
|
25
|
-
import SelectBareEditors from './partials/editors/select.bare';
|
|
26
|
-
import SwitchEditors from './partials/editors/switch';
|
|
27
|
-
import TagEditors from './partials/editors/tag';
|
|
28
|
-
import TextareaEditors from './partials/editors/textarea';
|
|
29
|
-
|
|
30
|
-
const MasterTableComponent = (props: TMasterProps) => {
|
|
31
|
-
const {
|
|
32
|
-
evOpenPopup,
|
|
33
|
-
headerColumns,
|
|
34
|
-
data,
|
|
35
|
-
setData,
|
|
36
|
-
resultPopup,
|
|
37
|
-
setResultPopup,
|
|
38
|
-
type,
|
|
39
|
-
evCreateMessageQuestion,
|
|
40
|
-
evCreateMessage,
|
|
41
|
-
autoCopy,
|
|
42
|
-
setAutoCopy,
|
|
43
|
-
isRemovable = true,
|
|
44
|
-
isForceUpdate,
|
|
45
|
-
setForceUpdate
|
|
46
|
-
} = props;
|
|
47
|
-
|
|
48
|
-
const [isOpenBulk, setOpenBulk] = useState<boolean>(false);
|
|
49
|
-
const [isReloadField, setReloadField] = useState<TReloadField>();
|
|
50
|
-
|
|
51
|
-
useEffect(() => {
|
|
52
|
-
const evResize = () => {
|
|
53
|
-
const resizeEl = document.querySelector('._refResizeContainer') as HTMLElement;
|
|
54
|
-
if (resizeEl) {
|
|
55
|
-
const desEl = document.querySelector('._refMasterTableViewport') as HTMLElement;
|
|
56
|
-
const height = resizeEl.offsetHeight;
|
|
57
|
-
const headerEl = document.querySelector('._refHeaderContainer') as HTMLElement;
|
|
58
|
-
const headerHeight = headerEl ? headerEl.offsetHeight : 0
|
|
59
|
-
desEl && (desEl.style.height = `calc(100vh - ${height + headerHeight + 12}px)`);
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
evResize();
|
|
63
|
-
window.addEventListener('resize', evResize, true);
|
|
64
|
-
return () => {
|
|
65
|
-
window.removeEventListener('resize', evResize, true);
|
|
66
|
-
}
|
|
67
|
-
}, [])
|
|
68
|
-
|
|
69
|
-
const page = pageMasterTable(type||'');
|
|
70
|
-
|
|
71
|
-
useEffect(() => {
|
|
72
|
-
const isCloneEl = document.querySelector('#master-clone') as HTMLDivElement;
|
|
73
|
-
const isCloneVal = isCloneEl ? isCloneEl.innerHTML : '';
|
|
74
|
-
if (data?.length && !isCloneVal) {
|
|
75
|
-
const masterTableViewPortyEl = document.querySelector('._refMasterTableViewport') as HTMLElement;
|
|
76
|
-
const masterTableHeaderCloneEl = document.querySelector('._refMasterTableHeaderClone') as HTMLElement;
|
|
77
|
-
let lastKnowX = 0;
|
|
78
|
-
let lastKnowScrollWidth = 0;
|
|
79
|
-
let ticking = false;
|
|
80
|
-
if (masterTableViewPortyEl) {
|
|
81
|
-
masterTableViewPortyEl.addEventListener("scroll", e => {
|
|
82
|
-
const scrollbarWidth = masterTableViewPortyEl.offsetWidth - masterTableViewPortyEl.clientWidth;
|
|
83
|
-
const left = masterTableViewPortyEl.scrollLeft;
|
|
84
|
-
lastKnowScrollWidth !== scrollbarWidth && (masterTableHeaderCloneEl.style.width = parseInt(masterTableHeaderCloneEl.style.width) + scrollbarWidth + 'px');
|
|
85
|
-
if (!ticking) {
|
|
86
|
-
window.requestAnimationFrame(() => {
|
|
87
|
-
lastKnowX !== left && (masterTableHeaderCloneEl.style.left = '-' + left + 'px')
|
|
88
|
-
ticking = false
|
|
89
|
-
lastKnowX = left
|
|
90
|
-
});
|
|
91
|
-
ticking = true;
|
|
92
|
-
}
|
|
93
|
-
lastKnowScrollWidth = scrollbarWidth;
|
|
94
|
-
}, { passive: true });
|
|
95
|
-
}
|
|
96
|
-
isCloneEl.innerHTML = 'true';
|
|
97
|
-
}
|
|
98
|
-
}, [data])
|
|
99
|
-
|
|
100
|
-
const firstHeaderColumnsWidth: number = 55;
|
|
101
|
-
const lastHeaderColumnsWidth: number = isRemovable ? 55 : 0;
|
|
102
|
-
const borderWidth = 1;
|
|
103
|
-
let totalHeaderColumnsWidth = 0;
|
|
104
|
-
let totalColGroupWidth = 0;
|
|
105
|
-
for (const head of headerColumns.filter(header => !header?.isHidden)) {
|
|
106
|
-
head.type === 'colGroup' && (totalColGroupWidth = totalColGroupWidth + head.width);
|
|
107
|
-
totalHeaderColumnsWidth = totalHeaderColumnsWidth + head.width ;
|
|
108
|
-
}
|
|
109
|
-
totalHeaderColumnsWidth += firstHeaderColumnsWidth + lastHeaderColumnsWidth + borderWidth;
|
|
110
|
-
totalColGroupWidth += firstHeaderColumnsWidth;
|
|
111
|
-
|
|
112
|
-
const evChange = (head: THeadProps, value: any, idx: number, variantIdx?: number) => {
|
|
113
|
-
const _type = (head?.condition === 'category') ? 'Array' : (head.typeData || 'String');
|
|
114
|
-
const _value = generateValue(_type, value);
|
|
115
|
-
const valid = head?.condition === 'category' ? validateByApproveJs(head, _value, (head?.condition[0].toUpperCase() + head?.condition.substring(1))) : validateByApproveJs(head, _value, undefined, evGenerateValueMatch(head.validations, data?.[idx]));
|
|
116
|
-
if (idx >= 0) {
|
|
117
|
-
let newData = [...data];
|
|
118
|
-
let newDataByIdx = newData[idx];
|
|
119
|
-
if (variantIdx && variantIdx >= 0) {
|
|
120
|
-
if(type === 'putaway-inbound') {
|
|
121
|
-
let newDataLocationByVariandIdx = newDataByIdx.locations[variantIdx]
|
|
122
|
-
const mainKey = head.key.replace('locations-', '');
|
|
123
|
-
newDataLocationByVariandIdx[mainKey] = _value;
|
|
124
|
-
if(!valid.approved) newDataLocationByVariandIdx[mainKey+'_error'] = valid.errors[0];
|
|
125
|
-
else delete newDataLocationByVariandIdx[mainKey+'_error']
|
|
126
|
-
newDataByIdx.locations.splice(variantIdx, 1, newDataLocationByVariandIdx);
|
|
127
|
-
} else {
|
|
128
|
-
let newDataVariantByVariandIdx = newDataByIdx.variants[variantIdx];
|
|
129
|
-
const mainKey = head.key.replace('variants-', '');
|
|
130
|
-
const variantsLength = newDataByIdx.variants.length;
|
|
131
|
-
if (mainKey === 'options-option' || mainKey === 'options-type') {
|
|
132
|
-
const optionIdx = (head.name.indexOf('1') !== -1) ? 0 : 1;
|
|
133
|
-
const optionName = mainKey === 'options-option' ? 'option' : 'type';
|
|
134
|
-
if (optionName === 'type') {
|
|
135
|
-
let newDataVariants = [];
|
|
136
|
-
for (let i = 0; i < variantsLength; i++) {
|
|
137
|
-
let newDataVariant = newDataByIdx.variants[i];
|
|
138
|
-
newDataVariant.options[optionIdx][optionName] = _value;
|
|
139
|
-
(`${optionName}_error` in newDataVariant.options[optionIdx]) && delete newDataVariant.options[optionIdx][`${optionName}_error`];
|
|
140
|
-
if (newDataVariant.options.length > 1) {
|
|
141
|
-
const oppositeOptionsIdx: number = optionIdx === 0 ? 1 : 0;
|
|
142
|
-
(`${optionName}_error` in newDataVariant.options[oppositeOptionsIdx]) && delete newDataVariant.options[oppositeOptionsIdx][`${optionName}_error`];
|
|
143
|
-
(_value.toLowerCase() === newDataVariant.options[oppositeOptionsIdx].type.toLowerCase()) && (newDataVariant.options[optionIdx][`${optionName}_error`] = 'Variant type is duplicate');
|
|
144
|
-
}
|
|
145
|
-
newDataVariants.push(newDataVariant);
|
|
146
|
-
}
|
|
147
|
-
newDataByIdx.variants = newDataVariants;
|
|
148
|
-
}
|
|
149
|
-
else {
|
|
150
|
-
newDataVariantByVariandIdx.options[optionIdx][optionName] = _value;
|
|
151
|
-
!valid.approved ? (newDataVariantByVariandIdx.options[optionIdx][optionName+'_error'] = valid.errors[0]) : delete newDataVariantByVariandIdx.options[optionIdx][optionName+'_error'];
|
|
152
|
-
newDataByIdx.variants.splice(variantIdx, 1, newDataVariantByVariandIdx);
|
|
153
|
-
}
|
|
154
|
-
} else {
|
|
155
|
-
newDataVariantByVariandIdx[mainKey] = _value;
|
|
156
|
-
!valid.approved ? (newDataVariantByVariandIdx[mainKey+'_error'] = valid.errors[0]) : delete newDataVariantByVariandIdx[mainKey+'_error'];
|
|
157
|
-
newDataByIdx.variants.splice(variantIdx, 1, newDataVariantByVariandIdx);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
} else {
|
|
161
|
-
if (head?.condition === 'category' ) {
|
|
162
|
-
if (head.key.indexOf('listing') !== -1 && newDataByIdx.listing) {
|
|
163
|
-
const listingIdx = newDataByIdx.listing.findIndex((listing: any) => listing.accountId === head.value);
|
|
164
|
-
if (listingIdx >= 0) {
|
|
165
|
-
let newListing = [...newDataByIdx.listing];
|
|
166
|
-
let newDataListingByIdx = newListing[listingIdx];
|
|
167
|
-
newDataListingByIdx[head.condition] = _value;
|
|
168
|
-
!valid.approved ? (newDataListingByIdx[head.condition+'_error'] = valid.errors[0]) : delete newDataListingByIdx[head.condition+'_error'];
|
|
169
|
-
newListing.splice(listingIdx, 1, newDataListingByIdx);
|
|
170
|
-
newDataByIdx.listing = newListing;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
} else {
|
|
174
|
-
newDataByIdx[head.key] = _value;
|
|
175
|
-
!valid.approved ? (newDataByIdx[head.key+'_error'] = valid.errors[0]) : delete newDataByIdx[head.key+'_error'];
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
newData.splice(idx, 1, newDataByIdx);
|
|
179
|
-
setData(newData);
|
|
180
|
-
if (head.bare && valid.approved) {
|
|
181
|
-
setForceUpdate && setForceUpdate(true);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
const evRemove: TMouseEvent = e => {
|
|
187
|
-
const el = e.target as HTMLButtonElement | HTMLDivElement
|
|
188
|
-
const callback = () => {
|
|
189
|
-
let newData = [...data]
|
|
190
|
-
const evRemoveAutoCopy = (idxs: number[]) => {
|
|
191
|
-
if (!autoCopy) {
|
|
192
|
-
return false
|
|
193
|
-
}
|
|
194
|
-
let newAutoCopyArr = [...autoCopy]
|
|
195
|
-
for (const _idx of idxs) {
|
|
196
|
-
const newDataCopy = {...newData[_idx]}
|
|
197
|
-
const category: string = newDataCopy.category
|
|
198
|
-
const autoCopyIdxs: number[] = newAutoCopyArr.reduce((r: number[], v, i) => r.concat((v.category === category) ? i : []), [])
|
|
199
|
-
if (autoCopyIdxs.length) {
|
|
200
|
-
for (const autoCopyIdx of autoCopyIdxs) {
|
|
201
|
-
if (autoCopyIdx >= 0) {
|
|
202
|
-
let newAutoCopyCop = newAutoCopyArr[autoCopyIdx]?.copy
|
|
203
|
-
if (newAutoCopyCop) {
|
|
204
|
-
const newAutoCopyCopIdx = newAutoCopyCop.findIndex((copy: TObject) => copy.id === newDataCopy.id)
|
|
205
|
-
newAutoCopyCopIdx >= 0 && newAutoCopyCop.splice(newAutoCopyCopIdx, 1)
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
setAutoCopy && setAutoCopy(newAutoCopyArr)
|
|
212
|
-
isReloadField && setReloadField(undefined)
|
|
213
|
-
}
|
|
214
|
-
const evSetCurrentListing = (_data: any) => {
|
|
215
|
-
const currentListingEl = document.getElementById('listing-data') as HTMLDivElement
|
|
216
|
-
(currentListingEl && !currentListingEl.innerHTML) && (currentListingEl.innerText = JSON.stringify(_data))
|
|
217
|
-
}
|
|
218
|
-
const group = el.dataset.type || ''
|
|
219
|
-
if (group === 'bulk') {
|
|
220
|
-
let isSelectedEl = document.querySelectorAll("[name='checkbox-list']:checked") as NodeListOf<HTMLInputElement>
|
|
221
|
-
let removeValFrom: number[] = []
|
|
222
|
-
for (let x = 0; x < isSelectedEl.length; x++) {
|
|
223
|
-
const el = isSelectedEl[x]
|
|
224
|
-
const idxEl = el.dataset.key ? parseInt(el.dataset.key) : 0
|
|
225
|
-
removeValFrom.push(idxEl)
|
|
226
|
-
}
|
|
227
|
-
const ex = newData.filter((_value, index) => removeValFrom.indexOf(index) === -1)
|
|
228
|
-
if (page === 'listing') {
|
|
229
|
-
evRemoveAutoCopy(removeValFrom)
|
|
230
|
-
setData(ex, (_data: any) => evSetCurrentListing(_data) )
|
|
231
|
-
}
|
|
232
|
-
else setData(ex)
|
|
233
|
-
evRemoveBulk()
|
|
234
|
-
} else {
|
|
235
|
-
const cellEl = el.closest('.cell-trash') as HTMLDivElement
|
|
236
|
-
const idx = cellEl.dataset.idx ? parseInt(cellEl.dataset.idx) : null
|
|
237
|
-
const variantIdx = cellEl.dataset.row ? parseInt(cellEl.dataset.row) : null
|
|
238
|
-
if (idx !== null) {
|
|
239
|
-
if (page === 'listing') {
|
|
240
|
-
evRemoveAutoCopy([idx])
|
|
241
|
-
newData.splice(idx, 1)
|
|
242
|
-
setData(newData, (_data: any) => evSetCurrentListing(_data))
|
|
243
|
-
}
|
|
244
|
-
else if (page === 'master') {
|
|
245
|
-
let contentData = {...newData[idx]}
|
|
246
|
-
if (contentData?.variants) {
|
|
247
|
-
if (contentData.variants.length === 1) {
|
|
248
|
-
newData.splice(idx, 1)
|
|
249
|
-
} else {
|
|
250
|
-
let newDataVariant = [...contentData.variants]
|
|
251
|
-
variantIdx && newDataVariant.splice(variantIdx, 1)
|
|
252
|
-
contentData.variants = newDataVariant
|
|
253
|
-
newData.splice(idx, 1, contentData)
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
else {
|
|
257
|
-
newData.splice(idx, 1)
|
|
258
|
-
}
|
|
259
|
-
setData(newData)
|
|
260
|
-
} else if(type === 'putaway-inbound') {
|
|
261
|
-
let contentData = Object.assign({}, newData[idx])
|
|
262
|
-
if(contentData?.locations) {
|
|
263
|
-
if(contentData.locations.length === 1) {
|
|
264
|
-
newData.splice(idx, 1)
|
|
265
|
-
}else {
|
|
266
|
-
let newDataLocation = [...contentData.locations]
|
|
267
|
-
variantIdx && newDataLocation.splice(variantIdx, 1)
|
|
268
|
-
contentData.locations = newDataLocation
|
|
269
|
-
newData.splice(idx, 1, contentData)
|
|
270
|
-
}
|
|
271
|
-
}else newData.splice(idx, 1)
|
|
272
|
-
setData(newData)
|
|
273
|
-
} else {
|
|
274
|
-
newData.splice(idx, 1)
|
|
275
|
-
setData(newData)
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
const _confirm_props = generateMessageQuestion('confirm', `Are you sure you want to remove ${type === 'create-paymentreceive' ? 'invoice' : 'product'}?`, '', callback)
|
|
281
|
-
evCreateMessageQuestion && evCreateMessageQuestion(_confirm_props)
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
const evCallbackBulk = (isChecked?: boolean) => {
|
|
285
|
-
const checkboxCheckedEls = document.querySelectorAll("[name='checkbox-list']:checked") as NodeListOf<HTMLInputElement>;
|
|
286
|
-
const isSelectedLength = checkboxCheckedEls.length;
|
|
287
|
-
const bulkEl = document.querySelector('._refMasterTableBulkWrapper') as HTMLElement;
|
|
288
|
-
const bulkSpanEl = bulkEl.getElementsByTagName("span") as HTMLCollectionOf<HTMLSpanElement>;
|
|
289
|
-
bulkSpanEl && (bulkSpanEl[0].innerHTML = `${isSelectedLength} selected`);
|
|
290
|
-
isSelectedLength > 0 ? bulkEl.classList.add('is-active') : bulkEl.classList.remove('is-active');
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
const evCheckboxAll: TMouseEvent = e => {
|
|
294
|
-
const isChecked = (e.target as HTMLInputElement).checked;
|
|
295
|
-
const checkboxEls = document.querySelectorAll("[name='checkbox-list']") as NodeListOf<HTMLInputElement>;
|
|
296
|
-
if (checkboxEls?.length) {
|
|
297
|
-
for (let x = 0; x < checkboxEls.length; x++) {
|
|
298
|
-
const checkboxEl = checkboxEls[x];
|
|
299
|
-
const checkboxParentEl = checkboxEl.closest('.cell-checkbox') as HTMLDivElement;
|
|
300
|
-
const checkboxRowEl = checkboxEl.closest('._refMasterTableBodyContent') as HTMLElement;
|
|
301
|
-
if (isChecked) {
|
|
302
|
-
checkboxParentEl && checkboxParentEl.classList.add('isChecked');
|
|
303
|
-
checkboxRowEl && checkboxRowEl.classList.add('is-highlighted');
|
|
304
|
-
}
|
|
305
|
-
else {
|
|
306
|
-
checkboxParentEl && checkboxParentEl.classList.remove('isChecked');
|
|
307
|
-
checkboxRowEl && checkboxRowEl.classList.remove('is-highlighted');
|
|
308
|
-
}
|
|
309
|
-
checkboxEl.checked = isChecked;
|
|
310
|
-
}
|
|
311
|
-
}else {
|
|
312
|
-
const msg = generateMessage('warning', 'No Products Selected');
|
|
313
|
-
evCreateMessage && evCreateMessage(msg);
|
|
314
|
-
(e.target as HTMLInputElement).checked = false;
|
|
315
|
-
setOpenBulk(false);
|
|
316
|
-
}
|
|
317
|
-
evCallbackBulk(isChecked)
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
const evCheckbox: TMouseEvent = e => {
|
|
321
|
-
const checkboxEl = e.target as HTMLInputElement;
|
|
322
|
-
const isChecked = checkboxEl.checked;
|
|
323
|
-
const checkboxAllEls = document.querySelectorAll("[name='checkbox-selectAll']") as NodeListOf<HTMLInputElement>;
|
|
324
|
-
const checkboxParentEl = checkboxEl.closest('.cell-checkbox') as HTMLDivElement;
|
|
325
|
-
const checkboxRowEl = checkboxEl.closest('._refMasterTableBodyContent') as HTMLElement;
|
|
326
|
-
if (!isChecked && checkboxAllEls?.length) {
|
|
327
|
-
checkboxAllEls.forEach(checkboxAllEl => checkboxAllEl.checked && (checkboxAllEl.checked = false));
|
|
328
|
-
}
|
|
329
|
-
if (isChecked) {
|
|
330
|
-
checkboxParentEl && checkboxParentEl.classList.add('isChecked');
|
|
331
|
-
checkboxRowEl && checkboxRowEl.classList.add('is-highlighted');
|
|
332
|
-
}
|
|
333
|
-
else {
|
|
334
|
-
checkboxParentEl && checkboxParentEl.classList.remove('isChecked');
|
|
335
|
-
checkboxRowEl && checkboxRowEl.classList.remove('is-highlighted');
|
|
336
|
-
}
|
|
337
|
-
evCallbackBulk();
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
const heightContent: number = page === 'stock' ? 66 : 82;
|
|
341
|
-
|
|
342
|
-
const switchEditor = (idx: number, head: THeadProps, valueKey: any, error: string, variantIdx?: number, height?: number | string, content?: any) => {
|
|
343
|
-
const _height = height || heightContent;
|
|
344
|
-
const evCloseEditor = (callback?: () => void) => {
|
|
345
|
-
const keyEl = document.getElementById('cur-key') as HTMLDivElement;
|
|
346
|
-
const cellEls = document.querySelectorAll('.cell-editing') as NodeListOf<HTMLDivElement>;
|
|
347
|
-
cellEls.forEach(cell => cell.classList.remove('cell-editing'))
|
|
348
|
-
keyEl && (keyEl.innerHTML = '');
|
|
349
|
-
callback && callback();
|
|
350
|
-
}
|
|
351
|
-
let editorEl
|
|
352
|
-
switch(head.fieldType) {
|
|
353
|
-
case 'image':
|
|
354
|
-
editorEl = <ImageEditors head={head} value={valueKey} height={_height} evOpenPopup={evOpenPopup} idx={idx} variantIdx={variantIdx} evChange={evChange} resultPopup={resultPopup} setResultPopup={setResultPopup} error={error} evCloseEditor={evCloseEditor} />
|
|
355
|
-
break
|
|
356
|
-
case 'textarea':
|
|
357
|
-
editorEl = <TextareaEditors head={head} value={valueKey} height={_height} idx={idx} variantIdx={variantIdx} />
|
|
358
|
-
break;
|
|
359
|
-
case 'select':
|
|
360
|
-
editorEl = head.bare ? <SelectBareEditors head={head} value={valueKey} idx={idx} variantIdx={variantIdx} evChange={evChange} error={error} content={content} isForceUpdate={isForceUpdate} setForceUpdate={setForceUpdate} /> : <SelectEditors head={head} value={valueKey} height={_height} idx={idx} variantIdx={variantIdx} evChange={evChange} error={error} evCloseEditor={evCloseEditor} />
|
|
361
|
-
break;
|
|
362
|
-
case 'tag':
|
|
363
|
-
editorEl = <TagEditors head={head} value={valueKey} height={_height} evOpenPopup={evOpenPopup} idx={idx} variantIdx={variantIdx} evChange={evChange} resultPopup={resultPopup} setResultPopup={setResultPopup} evCloseEditor={evCloseEditor} />
|
|
364
|
-
break;
|
|
365
|
-
case 'label':
|
|
366
|
-
editorEl = <LabelEditors head={head} value={valueKey} height={_height} idx={idx} evOpenPopup={evOpenPopup} content={content} type={type} variantIdx={variantIdx} />
|
|
367
|
-
break;
|
|
368
|
-
case 'switch':
|
|
369
|
-
editorEl = <SwitchEditors head={head} value={valueKey} idx={idx} variantIdx={variantIdx} evChange={evChange} evCloseEditor={evCloseEditor} />
|
|
370
|
-
break
|
|
371
|
-
case 'date':
|
|
372
|
-
editorEl = head.bare ? <DateBareEditors head={head} value={valueKey} idx={idx} variantIdx={variantIdx} evChange={evChange} error={error} isForceUpdate={isForceUpdate} setForceUpdate={setForceUpdate} /> : <DateEditors head={head} value={valueKey} height={_height} idx={idx} variantIdx={variantIdx} evChange={evChange} error={error} evCloseEditor={evCloseEditor} />
|
|
373
|
-
break;
|
|
374
|
-
default:
|
|
375
|
-
editorEl = head.bare ?
|
|
376
|
-
<InputBareEditors head={head} content={content} value={valueKey} height={_height} idx={idx} variantIdx={variantIdx} evChange={evChange} error={error} type={type} isForceUpdate={isForceUpdate} setForceUpdate={setForceUpdate} /> :
|
|
377
|
-
<InputEditors head={head} value={valueKey} height={_height} idx={idx} variantIdx={variantIdx} evChange={evChange} error={error} evCloseEditor={evCloseEditor} content={content} />
|
|
378
|
-
break;
|
|
379
|
-
}
|
|
380
|
-
return editorEl;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
const evMassClear: TMouseEvent = e => {
|
|
384
|
-
const key = (e.target as HTMLSpanElement).dataset.key || '';
|
|
385
|
-
const keyIdx = headerColumns.findIndex(column => column.key === key);
|
|
386
|
-
if (keyIdx >= 0) {
|
|
387
|
-
const head = headerColumns[keyIdx];
|
|
388
|
-
const checkboxAllEl = document.querySelector("[name='checkbox-selectAll']") as HTMLInputElement;
|
|
389
|
-
const checkedCheckboxEl = document.querySelectorAll("[name='checkbox-list']:checked") as NodeListOf<HTMLInputElement>;
|
|
390
|
-
const confirmButton = (!checkboxAllEl.checked && checkedCheckboxEl.length) ? `Clear to selected products (${checkedCheckboxEl.length})` : 'Clear all products';
|
|
391
|
-
const callback = () => {
|
|
392
|
-
const valid = ('validations' in head) ? validateByApproveJs(head, '') : { approved: true };
|
|
393
|
-
const modifiedMainKey = key.split('-');
|
|
394
|
-
const firstKey = modifiedMainKey[0];
|
|
395
|
-
const secondKey = modifiedMainKey[1];
|
|
396
|
-
const clearValue = head.typeData === "Boolean" ? false : '';
|
|
397
|
-
let newData = [...data];
|
|
398
|
-
if (page === 'stock') {
|
|
399
|
-
const _newData = newData.map(item => {
|
|
400
|
-
let _item = item
|
|
401
|
-
if(key) {
|
|
402
|
-
_item[key] = clearValue;
|
|
403
|
-
if(!valid.approved) _item[key+'_error'] = valid.errors[0];
|
|
404
|
-
else delete _item[key+'_error'];
|
|
405
|
-
}
|
|
406
|
-
return _item;
|
|
407
|
-
});
|
|
408
|
-
setData(_newData);
|
|
409
|
-
} else {
|
|
410
|
-
if (!checkboxAllEl.checked && checkedCheckboxEl.length) {
|
|
411
|
-
for (let z = 0; z < checkedCheckboxEl.length; z++) {
|
|
412
|
-
const checkboxEl = checkedCheckboxEl[z];
|
|
413
|
-
const idx = checkboxEl.dataset.key ? parseInt(checkboxEl.dataset.key) : null;
|
|
414
|
-
if (idx !== null) {
|
|
415
|
-
let _item = newData[idx];
|
|
416
|
-
if (secondKey) {
|
|
417
|
-
const newSeconds = _item[firstKey].map((second:any) => {
|
|
418
|
-
const _second = second;
|
|
419
|
-
_second[secondKey] = clearValue;
|
|
420
|
-
if(!valid.approved) {
|
|
421
|
-
_second[secondKey+'_error'] = valid.errors[0];
|
|
422
|
-
} else {
|
|
423
|
-
delete _second[secondKey+'_error'];
|
|
424
|
-
}
|
|
425
|
-
return _second;
|
|
426
|
-
})
|
|
427
|
-
_item[firstKey] = newSeconds;
|
|
428
|
-
} else {
|
|
429
|
-
_item[firstKey] = clearValue;
|
|
430
|
-
if (!valid.approved) {
|
|
431
|
-
_item[firstKey+'_error'] = valid.errors[0];
|
|
432
|
-
}
|
|
433
|
-
else {
|
|
434
|
-
delete _item[firstKey+'_error'];
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
newData.splice(idx, 1, _item);
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
setData(newData);
|
|
441
|
-
} else {
|
|
442
|
-
const _newData = newData.map(item => {
|
|
443
|
-
let _item = item;
|
|
444
|
-
if (secondKey) {
|
|
445
|
-
const newSeconds = _item[firstKey].map((second:any) => {
|
|
446
|
-
const _second = second;
|
|
447
|
-
_second[secondKey] = clearValue;
|
|
448
|
-
if(!valid.approved) _second[secondKey+'_error'] = valid.errors[0];
|
|
449
|
-
else delete _second[secondKey+'_error'];
|
|
450
|
-
return _second;
|
|
451
|
-
});
|
|
452
|
-
_item[firstKey] = newSeconds;
|
|
453
|
-
} else {
|
|
454
|
-
_item[firstKey] = clearValue;
|
|
455
|
-
if (!valid.approved) {
|
|
456
|
-
_item[firstKey+'_error'] = valid.errors[0];
|
|
457
|
-
}
|
|
458
|
-
else {
|
|
459
|
-
delete _item[firstKey+'_error'];
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
return _item;
|
|
463
|
-
})
|
|
464
|
-
setData(_newData);
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
};
|
|
468
|
-
const _confirm_props = generateMessageQuestion('confirm', `Are you sure you want to clear this column?`, "By clearing data, you can't undo this action.", callback, confirmButton);
|
|
469
|
-
evCreateMessageQuestion && evCreateMessageQuestion(_confirm_props);
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
const evClickCloseSelectAll: TMouseEvent = e => {
|
|
474
|
-
e.persist();
|
|
475
|
-
evRemoveBulk();
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
const evCloseDropdownMaster: TMouseEvent = () => {
|
|
479
|
-
const overlay = document.querySelector(`._refDropdownOverlay`) as HTMLDivElement;
|
|
480
|
-
overlay.style.display = 'none';
|
|
481
|
-
const bodyEl = document.getElementsByTagName("BODY")[0] as HTMLBodyElement;
|
|
482
|
-
bodyEl.classList.remove("is-immuned");
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
const evRemoveBulk = useCallback(() => {
|
|
486
|
-
const checkboxAllEls = document.querySelectorAll("[name='checkbox-selectAll']") as NodeListOf<HTMLInputElement>;
|
|
487
|
-
setTimeout(() => {
|
|
488
|
-
checkboxAllEls.forEach(checkboxAllEl => checkboxAllEl.checked && (checkboxAllEl.checked = false));
|
|
489
|
-
}, 10);
|
|
490
|
-
const checkedCheckboxEl = document.querySelectorAll("[name='checkbox-list']:checked") as NodeListOf<HTMLInputElement>;
|
|
491
|
-
if (checkedCheckboxEl?.length) {
|
|
492
|
-
for (let x = 0; x < checkedCheckboxEl.length; x++) {
|
|
493
|
-
const checkboxEl = checkedCheckboxEl[x];
|
|
494
|
-
const checkboxParentEl = checkboxEl.closest('.cell-checkbox') as HTMLDivElement;
|
|
495
|
-
const checkboxRowEl = checkboxEl.closest('._refMasterTableBodyContent') as HTMLElement;
|
|
496
|
-
checkboxParentEl && checkboxParentEl.classList.remove('isChecked');
|
|
497
|
-
checkboxRowEl && checkboxRowEl.classList.remove('is-highlighted');
|
|
498
|
-
checkboxEl.checked = false;
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
isOpenBulk && setOpenBulk(false);
|
|
502
|
-
}, [isOpenBulk])
|
|
503
|
-
|
|
504
|
-
useEffect(()=> {
|
|
505
|
-
if (resultPopup && ('edit' in resultPopup)) {
|
|
506
|
-
const key: string = resultPopup.edit.key;
|
|
507
|
-
const value = resultPopup.edit.value;
|
|
508
|
-
const modifiedMainKey = key.split('-');
|
|
509
|
-
const firstKey = modifiedMainKey[0];
|
|
510
|
-
const secondKey = modifiedMainKey[1];
|
|
511
|
-
const checkboxAllEl = document.querySelector("[name='checkbox-selectAll']") as HTMLInputElement;
|
|
512
|
-
const checkedCheckboxEl = document.querySelectorAll("[name='checkbox-list']:checked") as NodeListOf<HTMLInputElement>;
|
|
513
|
-
let newData = [...data];
|
|
514
|
-
if (!checkboxAllEl.checked && checkedCheckboxEl.length) {
|
|
515
|
-
for (let z = 0; z < checkedCheckboxEl.length; z++) {
|
|
516
|
-
const checkboxEl = checkedCheckboxEl[z];
|
|
517
|
-
const idx = checkboxEl.dataset.key ? parseInt(checkboxEl.dataset.key) : null;
|
|
518
|
-
if (idx !== null) {
|
|
519
|
-
let _item = newData[idx];
|
|
520
|
-
if (secondKey) {
|
|
521
|
-
const newSeconds = _item[firstKey].map((second: any) => {
|
|
522
|
-
const _second = second;
|
|
523
|
-
_second[secondKey] = value;
|
|
524
|
-
delete _second[secondKey+'_error'];
|
|
525
|
-
return _second;
|
|
526
|
-
});
|
|
527
|
-
_item[firstKey] = newSeconds;
|
|
528
|
-
} else {
|
|
529
|
-
_item[firstKey] = '';
|
|
530
|
-
delete _item[firstKey+'_error'];
|
|
531
|
-
}
|
|
532
|
-
newData.splice(idx, 1, _item);
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
setData(newData);
|
|
536
|
-
} else {
|
|
537
|
-
const _newData = newData.map(item => {
|
|
538
|
-
let _item = item;
|
|
539
|
-
if (secondKey) {
|
|
540
|
-
const newSeconds = _item[firstKey].map((second: any) => {
|
|
541
|
-
const _second = second;
|
|
542
|
-
_second[secondKey] = value;
|
|
543
|
-
delete _second[secondKey+'_error'];
|
|
544
|
-
return _second;
|
|
545
|
-
});
|
|
546
|
-
_item[firstKey] = newSeconds;
|
|
547
|
-
} else {
|
|
548
|
-
_item[firstKey] = ''
|
|
549
|
-
delete _item[firstKey+'_error']
|
|
550
|
-
}
|
|
551
|
-
return _item
|
|
552
|
-
});
|
|
553
|
-
setData(_newData);
|
|
554
|
-
}
|
|
555
|
-
setResultPopup && setResultPopup(null);
|
|
556
|
-
}
|
|
557
|
-
}, [resultPopup, setResultPopup, data, setData, page, type, headerColumns])
|
|
558
|
-
|
|
559
|
-
const isMass = headerColumns.filter(header => header.isMassEditable || header.isMassClearable).length > 0;
|
|
560
|
-
|
|
561
|
-
const createHeadEl = (headerColumns: THeadProps[], firstHeaderColumnsWidth: number, lastHeaderColumnsWidth: number, type?: string, totalHeaderColumnsWidth?: number, clone?: boolean) => {
|
|
562
|
-
return (
|
|
563
|
-
headerColumns?.length ?
|
|
564
|
-
<MasterTableHeaderWrapper className={`${clone ? '_refMasterTableHeaderClone' : '_refMasterTableHeader'}`} style={{ width: clone ? (totalHeaderColumnsWidth || '100%') : '100%' }}>
|
|
565
|
-
<MasterTableHeaderContainer>
|
|
566
|
-
<div key={0} className='headerCell headerCell-Checkbox' style={{ width: firstHeaderColumnsWidth }}>
|
|
567
|
-
{isRemovable ? <CheckboxComponent onClick={evCheckboxAll} name='checkbox-selectAll' id={`${clone ? 'checkbox-selectAll-clone' : 'checkbox-selectAll'}`}></CheckboxComponent> : null}
|
|
568
|
-
</div>
|
|
569
|
-
|
|
570
|
-
{
|
|
571
|
-
headerColumns.filter(header => !header?.isHidden).map((head, idx)=> {
|
|
572
|
-
return (
|
|
573
|
-
<div key={idx+1} className={`headerCell ${(head.icon || head.initial) ? 'headerCell-img' : ''}`} data-key={head.key} style={{ width: head.width }}>
|
|
574
|
-
{ head.icon ? <ImageComponent width='24px' src={head.icon} alt={head.name} /> : (head.initial ? <InitialContainer className='initial-wrapper' style={{ width: '24px', height: '24px', backgroundColor: head?.color || '#000000', fontSize: '10px' }}>{head.initial}</InitialContainer> : null) }
|
|
575
|
-
<header className='multi-elipsis' title={head.name}>
|
|
576
|
-
{head.name}
|
|
577
|
-
{head?.validations?.required && <TextComponent $color='red' style={{ display: 'inline', lineHeight: 'normal' }}>*</TextComponent>}
|
|
578
|
-
{head?.tip && <IconComponent $name='question' $width='12px' data-tip={head.tip} data-place='top' data-multiline={true} />}
|
|
579
|
-
</header>
|
|
580
|
-
</div>
|
|
581
|
-
)
|
|
582
|
-
})
|
|
583
|
-
}
|
|
584
|
-
{isRemovable ? <div key={headerColumns.length+(page === 'picklist' ? 2 : 1)} className='headerCell headerCell-trash' style={{ width: lastHeaderColumnsWidth }}></div> : null}
|
|
585
|
-
</MasterTableHeaderContainer>
|
|
586
|
-
|
|
587
|
-
{
|
|
588
|
-
(isMass && data?.length) ? (
|
|
589
|
-
<MasterTableActionWrapper>
|
|
590
|
-
<div className='actionCell' style={{ width: firstHeaderColumnsWidth }}>
|
|
591
|
-
</div>
|
|
592
|
-
{
|
|
593
|
-
headerColumns.filter(header => !header?.isHidden).map((head, idx)=> {
|
|
594
|
-
return (
|
|
595
|
-
<div key={idx+1} className='actionCell' style={{ width: head.width }}>
|
|
596
|
-
<IsMassContainer>
|
|
597
|
-
{head.isMassEditable && <LinkComponent mode='clear' title="Bulk Edit" data-popup='table-mass-edit' data-detail={JSON.stringify({ title:`Bulk Edit`, head: head })} onClick={evOpenPopup}>Edit</LinkComponent>}
|
|
598
|
-
{head.isMassClearable && <LinkComponent mode='clear' title="Bulk Clear" data-key={head.key} onClick={evMassClear}>Clear</LinkComponent>}
|
|
599
|
-
</IsMassContainer>
|
|
600
|
-
</div>
|
|
601
|
-
)
|
|
602
|
-
})
|
|
603
|
-
}
|
|
604
|
-
{isRemovable ? <div key={headerColumns.length+(page === 'picklist' ? 2 : 1)} className='actionCell' style={{ width: lastHeaderColumnsWidth }}></div> : null}
|
|
605
|
-
</MasterTableActionWrapper>
|
|
606
|
-
) : null
|
|
607
|
-
}
|
|
608
|
-
</MasterTableHeaderWrapper>
|
|
609
|
-
: null
|
|
610
|
-
);
|
|
611
|
-
};
|
|
612
|
-
|
|
613
|
-
console.log(data, "dataTable");
|
|
614
|
-
|
|
615
|
-
return (
|
|
616
|
-
<>
|
|
617
|
-
{createHeadEl(headerColumns, firstHeaderColumnsWidth, lastHeaderColumnsWidth, type, totalHeaderColumnsWidth, true)}
|
|
618
|
-
<MasterTable>
|
|
619
|
-
<MasterTableWrapper>
|
|
620
|
-
<MasterTableViewport className='_refMasterTableViewport' $mode={type || 'create-master'}>
|
|
621
|
-
<MasterTableCanvas className='_refMasterTableCanvas' style={{ width: totalHeaderColumnsWidth }}>
|
|
622
|
-
{createHeadEl(headerColumns, firstHeaderColumnsWidth, lastHeaderColumnsWidth, type)}
|
|
623
|
-
<MasterTableBodyWrapper className='_refMasterTableBody'>
|
|
624
|
-
{
|
|
625
|
-
data?.length ?
|
|
626
|
-
(type === 'putaway-inbound' ?
|
|
627
|
-
<ConfirmDataPartial data={data} heightContent={heightContent} firstHeaderColumnsWidth={firstHeaderColumnsWidth} evCheckbox={evCheckbox} headerColumns={headerColumns} switchEditor={switchEditor} totalColGroupWidth={totalColGroupWidth} lastHeaderColumnsWidth={lastHeaderColumnsWidth} evRemove={evRemove} type={type} isRemovable={isRemovable} /> :
|
|
628
|
-
<DataPartial data={data} firstHeaderColumnsWidth={firstHeaderColumnsWidth} evCheckbox={evCheckbox} headerColumns={headerColumns} switchEditor={switchEditor} lastHeaderColumnsWidth={lastHeaderColumnsWidth} evRemove={evRemove} type={type} isRemovable={isRemovable} />)
|
|
629
|
-
: null
|
|
630
|
-
}
|
|
631
|
-
</MasterTableBodyWrapper>
|
|
632
|
-
</MasterTableCanvas>
|
|
633
|
-
</MasterTableViewport>
|
|
634
|
-
</MasterTableWrapper>
|
|
635
|
-
<section className='_refContainer'>
|
|
636
|
-
<BulkActionWrapper className='_refMasterTableBulkWrapper'>
|
|
637
|
-
<IconComponent className='_refBulkCloseButton' $name='cross' $width='16px' onClick={evClickCloseSelectAll} />
|
|
638
|
-
<span>0 Selected</span>
|
|
639
|
-
<ButtonComponent $mode='red' data-type='bulk' onClick={evRemove}>Remove {type === 'create-paymentreceive' ? 'Invoice' : 'Product'}</ButtonComponent>
|
|
640
|
-
</BulkActionWrapper>
|
|
641
|
-
<div className='_refDropdownOverlay' onClick={evCloseDropdownMaster}></div>
|
|
642
|
-
</section>
|
|
643
|
-
</MasterTable>
|
|
644
|
-
<div id='master-clone' className='hidden'></div>
|
|
645
|
-
</>
|
|
646
|
-
);
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
export default MasterTableComponent;
|