@mixd-id/web-scaffold 0.1.2301231369 → 0.2.240702
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/LICENSE +1 -0
- package/docs/components/Header2.md +16 -0
- package/docs/components/TreeView.md +0 -0
- package/package.json +22 -5
- package/src/App.vue +9 -1
- package/src/components/Ahref.vue +175 -9
- package/src/components/Alert.vue +181 -75
- package/src/components/Article.vue +393 -0
- package/src/components/Block.vue +31 -0
- package/src/components/Box.vue +34 -0
- package/src/components/Button.vue +208 -129
- package/src/components/Carousel.vue +194 -124
- package/src/components/Chart.vue +485 -0
- package/src/components/ChartBar.vue +193 -0
- package/src/components/Checkbox.vue +95 -55
- package/src/components/CodeEditor.vue +61 -0
- package/src/components/ColorPicker.vue +158 -0
- package/src/components/ColorPicker2.vue +164 -0
- package/src/components/Confirm.vue +178 -0
- package/src/components/ContextMenu.vue +164 -76
- package/src/components/ConversationBuilder.vue +161 -0
- package/src/components/CopyToClipboard.vue +6 -31
- package/src/components/Countdown.vue +104 -53
- package/src/components/DGrid.vue +21 -0
- package/src/components/DGridItem.vue +263 -0
- package/src/components/DataList.vue +92 -0
- package/src/components/Datepicker.vue +65 -41
- package/src/components/DayTimeRange.vue +125 -0
- package/src/components/Dropdown.vue +32 -9
- package/src/components/ErrorText.vue +30 -9
- package/src/components/FBLogin.vue +194 -0
- package/src/components/Flex.vue +70 -0
- package/src/components/GSignIn.vue +166 -0
- package/src/components/Gmaps.vue +35 -11
- package/src/components/Grid.vue +24 -20
- package/src/components/HTMLEditor.vue +258 -79
- package/src/components/IconMenu.vue +95 -0
- package/src/components/IconMenu2.vue +89 -0
- package/src/components/IconPlus.vue +89 -0
- package/src/components/Image.vue +161 -59
- package/src/components/Image360.vue +2 -2
- package/src/components/ImagePreview.vue +23 -11
- package/src/components/ImportModal.vue +27 -14
- package/src/components/Link.vue +39 -0
- package/src/components/List.vue +1177 -0
- package/src/components/ListItem.vue +32 -21
- package/src/components/ListPage1.vue +88 -17
- package/src/components/ListPage1Filter.vue +2 -2
- package/src/components/ListView.vue +962 -0
- package/src/components/ListViewBarSummary.vue +81 -0
- package/src/components/ListViewLineSummary.vue +75 -0
- package/src/components/ListViewLiveBarSummary.vue +52 -0
- package/src/components/ListViewMapSummary.vue +56 -0
- package/src/components/ListViewSettings.vue +514 -0
- package/src/components/ListViewTableSummary.vue +77 -0
- package/src/components/LogViewerItem.vue +116 -0
- package/src/components/Modal.vue +274 -122
- package/src/components/MultilineText.vue +177 -0
- package/src/components/OTPField.vue +5 -6
- package/src/components/ObjectTree.vue +105 -0
- package/src/components/PageBuilder.vue +449 -0
- package/src/components/Paragraph.vue +41 -0
- package/src/components/PresetSelectorFilterItem.vue +178 -0
- package/src/components/Radio.vue +62 -87
- package/src/components/SearchButton.vue +1 -1
- package/src/components/Slider.vue +107 -75
- package/src/components/Svg.vue +33 -0
- package/src/components/Switch.vue +15 -5
- package/src/components/TabView.vue +0 -1
- package/src/components/Table.vue +56 -0
- package/src/components/TableViewHead.vue +2 -2
- package/src/components/Tabs.vue +68 -11
- package/src/components/Test.vue +23 -0
- package/src/components/Testimonial.vue +86 -0
- package/src/components/Text.vue +49 -0
- package/src/components/TextBlock.vue +50 -0
- package/src/components/TextWithTag.vue +225 -0
- package/src/components/Textarea.vue +22 -16
- package/src/components/Textbox.vue +83 -62
- package/src/components/Thumbnail.vue +27 -0
- package/src/components/Timepicker.vue +15 -8
- package/src/components/Toast.vue +60 -38
- package/src/components/TreeView.vue +101 -0
- package/src/components/TreeViewItem.vue +424 -0
- package/src/components/TreeViewItem1.vue +282 -0
- package/src/components/VirtualGrid.vue +284 -0
- package/src/components/VirtualScroll.vue +88 -21
- package/src/components/VirtualTable.vue +277 -71
- package/src/components/YoutubeVideo.vue +196 -0
- package/src/configs/icons-fa.json +12 -0
- package/src/events/event.js +2 -0
- package/src/index.js +477 -53
- package/src/main.js +0 -9
- package/src/middleware/http/trim-string.js +20 -0
- package/src/mixin/component.js +222 -0
- package/src/mixin/website.js +121 -0
- package/src/stores/components.js +36 -0
- package/src/themes/default/index.js +178 -34
- package/src/utils/helpers.js +378 -7
- package/src/utils/helpers.mjs +274 -16
- package/src/utils/importer.js +60 -26
- package/src/utils/listpage1.js +403 -267
- package/src/utils/listview.js +1287 -0
- package/src/utils/preset-selector.js +1055 -0
- package/src/utils/preset-selector.mjs +185 -0
- package/src/utils/selection.js +15 -36
- package/src/utils/web.js +50 -0
- package/src/utils/wss.js +294 -0
- package/src/utils/wss.mjs +280 -0
- package/src/widgets/AhrefSetting.vue +94 -0
- package/src/widgets/ArticleSetting.vue +469 -0
- package/src/widgets/BackgroundSetting.vue +132 -0
- package/src/widgets/BlockSetting.vue +49 -0
- package/src/widgets/BorderSetting.vue +201 -0
- package/src/widgets/BoxSetting.vue +53 -0
- package/src/widgets/ButtonSetting.vue +114 -0
- package/src/widgets/CarouselSetting.vue +193 -0
- package/src/widgets/ColumnSelector.vue +80 -0
- package/src/widgets/ComponentPropertyLabel.vue +35 -0
- package/src/widgets/ComponentPropertySelector.vue +115 -0
- package/src/widgets/ComponentSetting.vue +2220 -0
- package/src/widgets/ComponentSetting2.vue +1018 -0
- package/src/widgets/ComponentSetting3.vue +231 -0
- package/src/widgets/ContactForm.vue +193 -0
- package/src/widgets/ContactFormSetting.vue +384 -0
- package/src/widgets/CountdownSetting.vue +76 -0
- package/src/widgets/DataListSetting.vue +102 -0
- package/src/widgets/EffectSetting.vue +94 -0
- package/src/widgets/EmbeddedVideo.vue +60 -0
- package/src/widgets/EmbeddedVideoSetting.vue +48 -0
- package/src/widgets/FAQ.vue +85 -0
- package/src/widgets/FAQSetting.vue +88 -0
- package/src/widgets/FeatureList.vue +128 -0
- package/src/widgets/FeatureListSetting.vue +223 -0
- package/src/widgets/FiltersSetting.vue +88 -0
- package/src/widgets/FlexSetting.vue +197 -0
- package/src/widgets/GridSetting.vue +290 -0
- package/src/widgets/Header.vue +15 -0
- package/src/widgets/Header1.vue +41 -0
- package/src/widgets/Header1Setting.vue +75 -0
- package/src/widgets/Header2.vue +102 -0
- package/src/widgets/Header2Setting.vue +277 -0
- package/src/widgets/HeaderSetting.vue +104 -0
- package/src/widgets/IconList.vue +51 -0
- package/src/widgets/IconListSetting.vue +184 -0
- package/src/widgets/ImageSetting.vue +146 -0
- package/src/widgets/LayoutSetting.vue +251 -0
- package/src/widgets/LinkSetting.vue +186 -0
- package/src/widgets/LogViewer.vue +85 -0
- package/src/widgets/MarginPaddingSetting.vue +58 -0
- package/src/widgets/MarginSetting.vue +142 -0
- package/src/widgets/MenuEditor.vue +256 -0
- package/src/widgets/MobileMenu.vue +182 -0
- package/src/widgets/ModalSetting.vue +96 -0
- package/src/widgets/MultiValueSetting.vue +121 -0
- package/src/widgets/MultiValueSetting2.vue +114 -0
- package/src/widgets/PaddingSetting.vue +142 -0
- package/src/widgets/ParagraphSetting.vue +86 -0
- package/src/widgets/PresetBar.vue +880 -0
- package/src/widgets/PresetBarPivotColumnEdit.vue +197 -0
- package/src/widgets/PresetSelector.vue +673 -0
- package/src/widgets/Review.vue +131 -0
- package/src/widgets/ReviewSetting.vue +201 -0
- package/src/widgets/Share.vue +165 -0
- package/src/widgets/ShareSetting.vue +92 -0
- package/src/widgets/SizingSetting.vue +306 -0
- package/src/widgets/SpacingSetting.vue +77 -0
- package/src/widgets/StyleSetting.vue +328 -0
- package/src/widgets/StyleSetting2.vue +90 -0
- package/src/widgets/SvgSetting.vue +133 -0
- package/src/widgets/TableSetting.vue +172 -0
- package/src/widgets/TestimonialSetting.vue +152 -0
- package/src/widgets/TextBlockSetting.vue +78 -0
- package/src/widgets/ThumbnailSetting.vue +49 -0
- package/src/widgets/TransitionSetting.vue +64 -0
- package/src/widgets/TypographySetting.vue +334 -0
- package/src/widgets/UserActionBuilder/UserActionItem.vue +165 -0
- package/src/widgets/UserActionBuilder/UserActionOutput.vue +126 -0
- package/src/widgets/UserActionBuilder.vue +457 -0
- package/src/widgets/WebComponentSelector.vue +201 -0
- package/src/widgets/WebDatasourceSelector.vue +153 -0
- package/src/widgets/WebLayoutSelector.vue +376 -0
- package/src/widgets/WebPageBuilder.vue +1849 -0
- package/src/widgets/WebPageBuilder2.vue +1091 -0
- package/src/widgets/WebPageBuilder3.vue +411 -0
- package/src/widgets/WebPageBuilder4/ActionSetting.vue +158 -0
- package/src/widgets/WebPageBuilder4/BackgroundColorSetting.vue +54 -0
- package/src/widgets/WebPageBuilder4/BackgroundPositionSetting.vue +75 -0
- package/src/widgets/WebPageBuilder4/BackgroundRepeatSetting.vue +72 -0
- package/src/widgets/WebPageBuilder4/BackgroundSizeSetting.vue +72 -0
- package/src/widgets/WebPageBuilder4/BlurSetting.vue +72 -0
- package/src/widgets/WebPageBuilder4/BorderColorSetting.vue +64 -0
- package/src/widgets/WebPageBuilder4/BorderRadiusSetting.vue +75 -0
- package/src/widgets/WebPageBuilder4/BorderSizeSetting.vue +69 -0
- package/src/widgets/WebPageBuilder4/BorderStyleSetting.vue +72 -0
- package/src/widgets/WebPageBuilder4/BoxShadowSetting.vue +73 -0
- package/src/widgets/WebPageBuilder4/ButtonSetting.vue +73 -0
- package/src/widgets/WebPageBuilder4/CarouselSetting.vue +122 -0
- package/src/widgets/WebPageBuilder4/ColorSetting.vue +63 -0
- package/src/widgets/WebPageBuilder4/DataSetting.vue +92 -0
- package/src/widgets/WebPageBuilder4/DisplaySetting.vue +76 -0
- package/src/widgets/WebPageBuilder4/FlexAlignSetting.vue +71 -0
- package/src/widgets/WebPageBuilder4/FlexDirectionSetting.vue +70 -0
- package/src/widgets/WebPageBuilder4/FlexJustifySetting.vue +74 -0
- package/src/widgets/WebPageBuilder4/FlexPropertySetting.vue +71 -0
- package/src/widgets/WebPageBuilder4/FlexSetting.vue +105 -0
- package/src/widgets/WebPageBuilder4/FlexWrapSetting.vue +69 -0
- package/src/widgets/WebPageBuilder4/FontSizeSetting.vue +76 -0
- package/src/widgets/WebPageBuilder4/GapSetting.vue +75 -0
- package/src/widgets/WebPageBuilder4/GrayscaleSetting.vue +68 -0
- package/src/widgets/WebPageBuilder4/GridSetting.vue +166 -0
- package/src/widgets/WebPageBuilder4/HeightSetting.vue +95 -0
- package/src/widgets/WebPageBuilder4/ImageSetting.vue +102 -0
- package/src/widgets/WebPageBuilder4/LinkSetting.vue +68 -0
- package/src/widgets/WebPageBuilder4/MarginSetting.vue +70 -0
- package/src/widgets/WebPageBuilder4/MaxHeightSetting.vue +82 -0
- package/src/widgets/WebPageBuilder4/MaxWidthSetting.vue +90 -0
- package/src/widgets/WebPageBuilder4/MinHeightSetting.vue +81 -0
- package/src/widgets/WebPageBuilder4/MinWidthSetting.vue +101 -0
- package/src/widgets/WebPageBuilder4/MobileMenuSetting.vue +106 -0
- package/src/widgets/WebPageBuilder4/MultiValueSetting.vue +155 -0
- package/src/widgets/WebPageBuilder4/OpacitySetting.vue +77 -0
- package/src/widgets/WebPageBuilder4/OverflowSetting.vue +81 -0
- package/src/widgets/WebPageBuilder4/PaddingSetting.vue +53 -0
- package/src/widgets/WebPageBuilder4/PositionSetting.vue +191 -0
- package/src/widgets/WebPageBuilder4/PropertySetting.vue +183 -0
- package/src/widgets/WebPageBuilder4/Setting.vue +73 -0
- package/src/widgets/WebPageBuilder4/StyleSetting.vue +77 -0
- package/src/widgets/WebPageBuilder4/SvgSetting.vue +207 -0
- package/src/widgets/WebPageBuilder4/TextSetting.vue +72 -0
- package/src/widgets/WebPageBuilder4/TextTransformSetting.vue +70 -0
- package/src/widgets/WebPageBuilder4/TreeView.vue +43 -0
- package/src/widgets/WebPageBuilder4/TreeViewItem.vue +329 -0
- package/src/widgets/WebPageBuilder4/WebPageComponentSelector.vue +147 -0
- package/src/widgets/WebPageBuilder4/WebPageDataEdit.vue +121 -0
- package/src/widgets/WebPageBuilder4/WebPagePropertySelector.vue +172 -0
- package/src/widgets/WebPageBuilder4/WidthSetting.vue +105 -0
- package/src/widgets/WebPageBuilder4/ZIndexSetting.vue +72 -0
- package/src/widgets/WebPageBuilder4.vue +1084 -0
- package/src/widgets/WebPagePreview.vue +295 -0
- package/src/widgets/WebPageSelector.vue +173 -0
- package/src/widgets/WebTemplateCreator.vue +156 -0
- package/src/widgets/YoutubeVideoSetting.vue +65 -0
- package/tailwind.config.js +513 -0
- package/test.json +22 -0
- package/public/images/mixd-logo2.png +0 -0
- package/src/components/ButtonGroup.vue +0 -101
- package/src/components/DynamicTemplate.vue +0 -44
- package/src/components/GridColumn.vue +0 -31
package/src/utils/helpers.mjs
CHANGED
|
@@ -30,9 +30,9 @@ const csvToArray = (str, delimiter = null) => {
|
|
|
30
30
|
const downsizeImage = async (url, targetWidth, imageType, quality, opt = {}) => {
|
|
31
31
|
|
|
32
32
|
let defaultImageType = 'image/jpeg'
|
|
33
|
+
targetWidth = isNaN(parseInt(targetWidth)) ? 2048 : parseInt(targetWidth)
|
|
33
34
|
|
|
34
35
|
if(url instanceof File){
|
|
35
|
-
|
|
36
36
|
defaultImageType = url.type
|
|
37
37
|
|
|
38
38
|
await (new Promise((resolve, reject) => {
|
|
@@ -84,11 +84,11 @@ const parseBoolean = function(exp){
|
|
|
84
84
|
exp.toLowerCase() : exp)
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
const strVars = function(text, vars){
|
|
87
|
+
const strVars = function(text, vars, opt = { emptyUndefined:true }){
|
|
88
88
|
|
|
89
89
|
(text.match(/\{.*?(?=\})\}/gi) ?? []).forEach((match) => {
|
|
90
90
|
const key = match.substring(1, match.length - 1)
|
|
91
|
-
const value = vars[key] ?? ''
|
|
91
|
+
const value = vars[key] ?? (opt?.emptyUndefined ? '' : `{${key}}`)
|
|
92
92
|
text = text.replace(match, value)
|
|
93
93
|
})
|
|
94
94
|
|
|
@@ -125,14 +125,264 @@ const uid = function(prefix){
|
|
|
125
125
|
return (prefix ?? '') + __uid++;
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
+
const accessNestedObject = function(obj, path) {
|
|
129
|
+
if(!obj || typeof path !== 'string') return undefined
|
|
130
|
+
|
|
131
|
+
const keys = path.split('.');
|
|
132
|
+
let nestedObj = obj;
|
|
133
|
+
|
|
134
|
+
for (let key of keys) {
|
|
135
|
+
if (nestedObj && nestedObj.hasOwnProperty(key)) {
|
|
136
|
+
nestedObj = nestedObj[key];
|
|
137
|
+
} else {
|
|
138
|
+
// Return undefined if any key in the path is missing
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return nestedObj;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const mediaPrefixes = [
|
|
147
|
+
'',
|
|
148
|
+
'md:'
|
|
149
|
+
]
|
|
150
|
+
const calcUnit = (prefix, midfix, value) => {
|
|
151
|
+
|
|
152
|
+
const values = (value ?? '').split(',')
|
|
153
|
+
|
|
154
|
+
if(value === 'mx-auto'){
|
|
155
|
+
return prefix + value
|
|
156
|
+
}
|
|
157
|
+
else if(values.length === 1){
|
|
158
|
+
return prefix + midfix + '-' + values[0]
|
|
159
|
+
}
|
|
160
|
+
else if(values.length === 2){
|
|
161
|
+
return prefix + midfix + 'x-' + values[0] +
|
|
162
|
+
' ' +
|
|
163
|
+
prefix + midfix + 'y-' + values[1]
|
|
164
|
+
}
|
|
165
|
+
else if(values.length === 4){
|
|
166
|
+
return prefix + midfix + 'l-' + values[0] +
|
|
167
|
+
' ' +
|
|
168
|
+
prefix + midfix + 't-' + values[1] +
|
|
169
|
+
' ' +
|
|
170
|
+
prefix + midfix + 'r-' + values[2] +
|
|
171
|
+
' ' +
|
|
172
|
+
prefix + midfix + 'b-' + values[3]
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const _applyClass = function(props, defaultClass = {}){
|
|
177
|
+
return []
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const fallbackCopyTextToClipboard = function(obj){
|
|
181
|
+
return new Promise((resolve, reject) => {
|
|
182
|
+
try{
|
|
183
|
+
var textArea = document.createElement("textarea");
|
|
184
|
+
textArea.value = obj;
|
|
185
|
+
textArea.style.left = "-100vw";
|
|
186
|
+
textArea.style.position = "fixed";
|
|
187
|
+
document.body.appendChild(textArea);
|
|
188
|
+
textArea.focus();
|
|
189
|
+
textArea.select();
|
|
190
|
+
|
|
191
|
+
document.execCommand('copy')
|
|
192
|
+
document.body.removeChild(textArea);
|
|
193
|
+
|
|
194
|
+
resolve()
|
|
195
|
+
}
|
|
196
|
+
catch(e){
|
|
197
|
+
reject(e)
|
|
198
|
+
}
|
|
199
|
+
})
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const fallbackGetClipboardData = function(obj){
|
|
203
|
+
return new Promise((resolve, reject) => {
|
|
204
|
+
try{
|
|
205
|
+
var textArea = document.createElement("textarea");
|
|
206
|
+
textArea.style.left = "-100vw";
|
|
207
|
+
textArea.style.position = "fixed";
|
|
208
|
+
document.body.appendChild(textArea);
|
|
209
|
+
textArea.focus();
|
|
210
|
+
document.execCommand('paste');
|
|
211
|
+
|
|
212
|
+
window.setTimeout(() => {
|
|
213
|
+
const text = textArea.value;
|
|
214
|
+
document.body.removeChild(textArea);
|
|
215
|
+
resolve(text)
|
|
216
|
+
}, 100)
|
|
217
|
+
}
|
|
218
|
+
catch(e){
|
|
219
|
+
reject(e)
|
|
220
|
+
}
|
|
221
|
+
})
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const copyToClipboard = function(obj){
|
|
225
|
+
if (!navigator.clipboard) {
|
|
226
|
+
return fallbackCopyTextToClipboard(obj);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return new Promise((resolve, reject) => {
|
|
230
|
+
navigator.clipboard.writeText(obj).then(() => {
|
|
231
|
+
resolve()
|
|
232
|
+
}, (err) => {
|
|
233
|
+
reject(err)
|
|
234
|
+
});
|
|
235
|
+
})
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const getClipboardData = function(){
|
|
239
|
+
if (!navigator.clipboard) {
|
|
240
|
+
return fallbackGetClipboardData();
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return new Promise((resolve, reject) => {
|
|
244
|
+
navigator.clipboard.readText().then((text) => {
|
|
245
|
+
resolve(text)
|
|
246
|
+
}, (err) => {
|
|
247
|
+
reject(err)
|
|
248
|
+
});
|
|
249
|
+
})
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const getComponentUids = function(components, excepts = []){
|
|
253
|
+
|
|
254
|
+
const arr = []
|
|
255
|
+
|
|
256
|
+
for(let comp of components){
|
|
257
|
+
if(!excepts.includes(comp.uid)){
|
|
258
|
+
arr.push({
|
|
259
|
+
uid: comp.uid,
|
|
260
|
+
name: comp.props.name ?? comp.type
|
|
261
|
+
})
|
|
262
|
+
|
|
263
|
+
if(Array.isArray(comp.items)){
|
|
264
|
+
arr.push(...getComponentUids(comp.items))
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
return arr
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
const unPascalCase = function(str){
|
|
273
|
+
return str.replace(/([A-Z])/g, ' $1').trim()
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
const sleep = ms => new Promise(r => setTimeout(r, ms))
|
|
277
|
+
|
|
278
|
+
const removeStyleFromTag = (html) => {
|
|
279
|
+
const regex = /<[^>]+style="[^"]*"[^>]*>/g;
|
|
280
|
+
|
|
281
|
+
return html.replace(regex, (match) => {
|
|
282
|
+
return match.replace(/style="[^"]*"/, '');
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
const createFormData = (obj) => {
|
|
287
|
+
|
|
288
|
+
const form = new FormData()
|
|
289
|
+
|
|
290
|
+
const iterateObject = (obj, parentKey = '') => {
|
|
291
|
+
|
|
292
|
+
for (let key in obj) {
|
|
293
|
+
if (obj.hasOwnProperty(key)) {
|
|
294
|
+
const value = obj[key];
|
|
295
|
+
const propName = parentKey ? `${parentKey}[${key}]` : key;
|
|
296
|
+
|
|
297
|
+
if (value instanceof File || value instanceof Blob) {
|
|
298
|
+
form.append(propName, value);
|
|
299
|
+
}
|
|
300
|
+
else if (typeof value === 'object' && value !== null) {
|
|
301
|
+
iterateObject(value, propName);
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
form.append(propName, value);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
iterateObject(obj)
|
|
311
|
+
|
|
312
|
+
return form
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
function unslugAndCapitalize(slug) {
|
|
316
|
+
return (slug ?? '')
|
|
317
|
+
.split('-') // Replace '-' with '_' if that's your separator
|
|
318
|
+
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
|
|
319
|
+
.join(' ');
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
const hexToRgb = (hex) => {
|
|
323
|
+
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
|
324
|
+
return result ? {
|
|
325
|
+
r: parseInt(result[1], 16),
|
|
326
|
+
g: parseInt(result[2], 16),
|
|
327
|
+
b: parseInt(result[3], 16)
|
|
328
|
+
} : null;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
function rgbToHex(r, g, b) {
|
|
332
|
+
|
|
333
|
+
r = parseInt(r)
|
|
334
|
+
g = parseInt(g)
|
|
335
|
+
b = parseInt(b)
|
|
336
|
+
if(isNaN(r) || isNaN(g) || isNaN(b))
|
|
337
|
+
return
|
|
338
|
+
|
|
339
|
+
r = Math.max(0, Math.min(255, r));
|
|
340
|
+
g = Math.max(0, Math.min(255, g));
|
|
341
|
+
b = Math.max(0, Math.min(255, b));
|
|
342
|
+
|
|
343
|
+
const hexR = r.toString(16).padStart(2, '0');
|
|
344
|
+
const hexG = g.toString(16).padStart(2, '0');
|
|
345
|
+
const hexB = b.toString(16).padStart(2, '0');
|
|
346
|
+
|
|
347
|
+
return "#" + hexR + hexG + hexB;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
function applyDatasourceReplacer(value, datasource){
|
|
351
|
+
if(typeof value !== 'string') return value
|
|
352
|
+
|
|
353
|
+
let matches = value.match(/\{\{([^}]+)\}\}/g);
|
|
354
|
+
(matches ?? []).forEach(matchKey => {
|
|
355
|
+
matchKey = matchKey.slice(2, -2)
|
|
356
|
+
const matchValue = accessNestedObject(datasource, matchKey) ?? ''
|
|
357
|
+
value = value.replace(`{{${matchKey}}}`, matchValue, 'gi')
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
return value
|
|
361
|
+
}
|
|
362
|
+
|
|
128
363
|
export {
|
|
129
364
|
downsizeImage,
|
|
365
|
+
hexToRgb,
|
|
366
|
+
rgbToHex,
|
|
130
367
|
uid,
|
|
131
368
|
observeInit,
|
|
132
369
|
csvToArray,
|
|
133
370
|
parseBoolean,
|
|
134
371
|
urlQuery,
|
|
135
|
-
getQueryString
|
|
372
|
+
getQueryString,
|
|
373
|
+
accessNestedObject,
|
|
374
|
+
mediaPrefixes,
|
|
375
|
+
_applyClass,
|
|
376
|
+
copyToClipboard,
|
|
377
|
+
getClipboardData,
|
|
378
|
+
getComponentUids,
|
|
379
|
+
unPascalCase,
|
|
380
|
+
sleep,
|
|
381
|
+
removeStyleFromTag,
|
|
382
|
+
createFormData,
|
|
383
|
+
unslugAndCapitalize,
|
|
384
|
+
applyDatasourceReplacer,
|
|
385
|
+
strVars
|
|
136
386
|
}
|
|
137
387
|
|
|
138
388
|
function observeInit(){
|
|
@@ -154,22 +404,24 @@ function observeInit(){
|
|
|
154
404
|
|
|
155
405
|
const item = entry.target
|
|
156
406
|
const key = item.__observeKey
|
|
157
|
-
const { type, callback } = observeCols[key]
|
|
158
407
|
|
|
159
|
-
if(
|
|
160
|
-
callback
|
|
408
|
+
if(observeCols[key]){
|
|
409
|
+
const { type, callback } = observeCols[key]
|
|
161
410
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
411
|
+
if(typeof callback === 'function')
|
|
412
|
+
callback.apply(item)
|
|
413
|
+
|
|
414
|
+
if(type === 'once'){
|
|
415
|
+
observer.unobserve(item)
|
|
416
|
+
delete observeCols[key]
|
|
417
|
+
}
|
|
165
418
|
}
|
|
166
419
|
})
|
|
167
420
|
}
|
|
168
421
|
|
|
169
422
|
const observeCols = {}
|
|
170
423
|
|
|
171
|
-
const once = function(el, callback)
|
|
172
|
-
{
|
|
424
|
+
const once = function(el, callback){
|
|
173
425
|
if(typeof el.__observeKey !== 'undefined') return
|
|
174
426
|
|
|
175
427
|
intersectionObserver.observe(el)
|
|
@@ -179,8 +431,7 @@ function observeInit(){
|
|
|
179
431
|
el.__observeKey = key
|
|
180
432
|
}
|
|
181
433
|
|
|
182
|
-
const always = function(el, callback)
|
|
183
|
-
{
|
|
434
|
+
const always = function(el, callback){
|
|
184
435
|
if(typeof el.__observeKey !== 'undefined') return
|
|
185
436
|
|
|
186
437
|
intersectionObserver.observe(el)
|
|
@@ -190,8 +441,15 @@ function observeInit(){
|
|
|
190
441
|
el.__observeKey = key
|
|
191
442
|
}
|
|
192
443
|
|
|
444
|
+
const unregister = function(el){
|
|
445
|
+
if(el && el.__observeKey && observeCols[el.__observeKey]){
|
|
446
|
+
delete observeCols[el.__observeKey]
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
193
450
|
return {
|
|
194
451
|
once,
|
|
195
|
-
always
|
|
452
|
+
always,
|
|
453
|
+
unregister
|
|
196
454
|
}
|
|
197
|
-
}
|
|
455
|
+
}
|
package/src/utils/importer.js
CHANGED
|
@@ -3,7 +3,7 @@ const fs = require("fs");
|
|
|
3
3
|
const AdmZip = require("adm-zip");
|
|
4
4
|
const glob = require("glob");
|
|
5
5
|
const Exceljs = require("exceljs")
|
|
6
|
-
const { saveBuffer } = require('./helpers.js')
|
|
6
|
+
const { saveBuffer, unflatten } = require('./helpers.js')
|
|
7
7
|
|
|
8
8
|
const analyseRequest = async(req) => {
|
|
9
9
|
|
|
@@ -64,10 +64,17 @@ const analyseRequest = async(req) => {
|
|
|
64
64
|
|
|
65
65
|
const columns = []
|
|
66
66
|
const header = worksheet.getRow(1)
|
|
67
|
+
|
|
67
68
|
if(!header)
|
|
68
69
|
throw new Error('Invalid file')
|
|
69
70
|
header.eachCell((cell) => {
|
|
70
|
-
|
|
71
|
+
if(cell.isMerged){
|
|
72
|
+
const sub = worksheet.getCell(cell.address.replace(/\d/g, '') + '2').value
|
|
73
|
+
columns.push(cell.value + '>' + sub)
|
|
74
|
+
}
|
|
75
|
+
else{
|
|
76
|
+
columns.push(cell.value)
|
|
77
|
+
}
|
|
71
78
|
})
|
|
72
79
|
|
|
73
80
|
return {
|
|
@@ -87,8 +94,7 @@ const importRequest = async(req) => {
|
|
|
87
94
|
throw new Error({name: ['Kolom ' + key.text + ' harus diisi']})
|
|
88
95
|
})
|
|
89
96
|
|
|
90
|
-
|
|
91
|
-
const cols = {}
|
|
97
|
+
let rows = []
|
|
92
98
|
const workbook = new Exceljs.Workbook();
|
|
93
99
|
switch(xlsxFileType){
|
|
94
100
|
|
|
@@ -106,37 +112,65 @@ const importRequest = async(req) => {
|
|
|
106
112
|
}
|
|
107
113
|
|
|
108
114
|
const worksheet = workbook.worksheets[0]
|
|
109
|
-
worksheet.eachRow((row, index) => {
|
|
110
|
-
if(index === 1){
|
|
111
|
-
row.eachCell((cell, index) => {
|
|
112
|
-
|
|
113
|
-
let mapped = false
|
|
114
|
-
keys.forEach((key) => {
|
|
115
|
-
if(key.value === cell.value){
|
|
116
|
-
cols[key.key] = index
|
|
117
|
-
mapped = true
|
|
118
|
-
}
|
|
119
|
-
})
|
|
120
115
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
116
|
+
const row = worksheet.getRow(2)
|
|
117
|
+
let isInfoRow = false
|
|
118
|
+
row.eachCell(cell => {
|
|
119
|
+
if((cell.value ?? '').toString().trim().startsWith('***')){
|
|
120
|
+
isInfoRow = true
|
|
121
|
+
}
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
let rowStart = isInfoRow ? 3 : 2
|
|
125
|
+
const header = worksheet.getRow(1)
|
|
126
|
+
const columnAddress = {}
|
|
127
|
+
header.eachCell((cell, index) => {
|
|
128
|
+
if(cell.isMerged){
|
|
129
|
+
const sub = worksheet.getCell(cell.address.replace(/\d/g, '') + '2').value
|
|
130
|
+
columnAddress[cell.value + '>' + sub] = index
|
|
131
|
+
rowStart = 3
|
|
125
132
|
}
|
|
126
133
|
else{
|
|
134
|
+
columnAddress[cell.value] = index
|
|
135
|
+
}
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
worksheet.eachRow((row, index) => {
|
|
139
|
+
if(index >= rowStart){
|
|
127
140
|
const obj = {}
|
|
128
141
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
142
|
+
// Check if cells in row 2 and 3 is notes in italic
|
|
143
|
+
if(index <= 3){
|
|
144
|
+
let isItalic = false
|
|
145
|
+
for(let idx in keys){
|
|
146
|
+
const key = keys[idx]
|
|
147
|
+
if(key.value && columnAddress[key.value]){
|
|
148
|
+
const cell = row.getCell(columnAddress[key.value])
|
|
149
|
+
if(cell.font && cell.font.italic){
|
|
150
|
+
isItalic = true
|
|
151
|
+
break
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if(isItalic)
|
|
157
|
+
return
|
|
132
158
|
}
|
|
133
159
|
|
|
134
|
-
|
|
160
|
+
for(let idx in keys){
|
|
161
|
+
const key = keys[idx]
|
|
162
|
+
if(key.value && columnAddress[key.value]){
|
|
163
|
+
const cell = row.getCell(columnAddress[key.value])
|
|
164
|
+
let value = cell.formulaType === 1 ? cell.result : cell.value
|
|
165
|
+
if(value && value.error) value = ''
|
|
166
|
+
obj[key.key] = value
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
rows.push(unflatten(obj))
|
|
135
171
|
}
|
|
136
172
|
})
|
|
137
173
|
|
|
138
|
-
//console.log(JSON.stringify(rows, null, 2))
|
|
139
|
-
|
|
140
174
|
const images = glob.sync(process.env.ROOT_PATH + '/storage/files/temp/' + folderName +
|
|
141
175
|
'/**/*(*.jpg|*.jpeg|*.png|*.webp)')
|
|
142
176
|
|
|
@@ -153,4 +187,4 @@ const importRequest = async(req) => {
|
|
|
153
187
|
module.exports = {
|
|
154
188
|
analyseRequest,
|
|
155
189
|
importRequest
|
|
156
|
-
}
|
|
190
|
+
}
|