@mixd-id/web-scaffold 0.1.230406001

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.
Files changed (62) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +3 -0
  3. package/package.json +71 -0
  4. package/public/images/mixd-logo2.png +0 -0
  5. package/src/App.vue +17 -0
  6. package/src/components/Ahref.vue +34 -0
  7. package/src/components/Alert.vue +160 -0
  8. package/src/components/Button.vue +253 -0
  9. package/src/components/ButtonGroup.vue +101 -0
  10. package/src/components/Carousel.vue +293 -0
  11. package/src/components/ChatTyping.vue +69 -0
  12. package/src/components/Checkbox.vue +152 -0
  13. package/src/components/ContextMenu.vue +261 -0
  14. package/src/components/CopyToClipboard.vue +59 -0
  15. package/src/components/Countdown.vue +213 -0
  16. package/src/components/Datepicker.vue +312 -0
  17. package/src/components/Dropdown.vue +198 -0
  18. package/src/components/DynamicTemplate.vue +44 -0
  19. package/src/components/ErrorText.vue +36 -0
  20. package/src/components/Feed.vue +118 -0
  21. package/src/components/Gmaps.vue +227 -0
  22. package/src/components/Grid.vue +29 -0
  23. package/src/components/GridColumn.vue +31 -0
  24. package/src/components/HTMLEditor.vue +396 -0
  25. package/src/components/Image.vue +207 -0
  26. package/src/components/Image360.vue +140 -0
  27. package/src/components/ImageFullScreen.vue +101 -0
  28. package/src/components/ImagePreview.vue +71 -0
  29. package/src/components/ImportModal.vue +247 -0
  30. package/src/components/ListItem.vue +147 -0
  31. package/src/components/ListPage1.vue +1331 -0
  32. package/src/components/ListPage1Filter.vue +170 -0
  33. package/src/components/Modal.vue +253 -0
  34. package/src/components/OTPField.vue +126 -0
  35. package/src/components/Radio.vue +134 -0
  36. package/src/components/SearchButton.vue +57 -0
  37. package/src/components/Slider.vue +285 -0
  38. package/src/components/SplitPane.vue +129 -0
  39. package/src/components/Switch.vue +89 -0
  40. package/src/components/TabView.vue +106 -0
  41. package/src/components/TableView.vue +201 -0
  42. package/src/components/TableViewHead.vue +159 -0
  43. package/src/components/Tabs.vue +74 -0
  44. package/src/components/TextEditor.vue +85 -0
  45. package/src/components/Textarea.vue +184 -0
  46. package/src/components/Textbox.vue +200 -0
  47. package/src/components/Timepicker.vue +108 -0
  48. package/src/components/Toast.vue +93 -0
  49. package/src/components/VirtualScroll.vue +215 -0
  50. package/src/components/VirtualTable.vue +497 -0
  51. package/src/entry-client.js +27 -0
  52. package/src/entry-server.js +73 -0
  53. package/src/index.css +3 -0
  54. package/src/index.js +255 -0
  55. package/src/main.js +38 -0
  56. package/src/router.js +57 -0
  57. package/src/themes/default/index.js +200 -0
  58. package/src/utils/helpers.js +185 -0
  59. package/src/utils/helpers.mjs +197 -0
  60. package/src/utils/importer.js +156 -0
  61. package/src/utils/listpage1.js +1371 -0
  62. package/src/utils/selection.js +64 -0
@@ -0,0 +1,185 @@
1
+ const md5 = require("md5");
2
+ const fs = require("fs");
3
+
4
+
5
+ const ceil = (num, precision = 0) => {
6
+ var p = Math.pow(10, precision)
7
+ var n = (num * p) * (1 + Number.EPSILON)
8
+ return Math.ceil(n) / p
9
+ }
10
+
11
+ const floor = (num, precision = 0) => {
12
+ var p = Math.pow(10, precision)
13
+ var n = (num * p) * (1 + Number.EPSILON)
14
+ return Math.floor(n) / p
15
+ }
16
+
17
+ const ftWildcard = (key) => {
18
+ const term = key.replace(/[\-\+\<\>\@\(\)\~]/, ' ', 'gi')
19
+
20
+ const searchTerms = []
21
+ term.split(' ').forEach((txt) => {
22
+ if(txt.length >= 3){
23
+ searchTerms.push(`+${txt}*`)
24
+ }
25
+ })
26
+ return searchTerms.join(' ')
27
+ }
28
+
29
+ const moveFile = function(oldPath, newPath, callback) {
30
+
31
+ fs.rename(oldPath, newPath, function (err) {
32
+ if (err) {
33
+ if (err.code === 'EXDEV') {
34
+ copy();
35
+ } else {
36
+ callback(err);
37
+ }
38
+ return;
39
+ }
40
+ callback();
41
+ });
42
+
43
+ function copy() {
44
+ var readStream = fs.createReadStream(oldPath);
45
+ var writeStream = fs.createWriteStream(newPath);
46
+
47
+ readStream.on('error', callback);
48
+ writeStream.on('error', callback);
49
+
50
+ readStream.on('close', function () {
51
+ fs.unlink(oldPath, callback);
52
+ });
53
+
54
+ readStream.pipe(writeStream);
55
+ }
56
+ }
57
+
58
+ const round = (num, precision = 0) => {
59
+ var p = Math.pow(10, precision)
60
+ var n = (num * p) * (1 + Number.EPSILON)
61
+ return Math.round(n) / p
62
+ }
63
+
64
+ const sanitizeMobileNumber = (mobileNumber) => {
65
+ if(typeof mobileNumber !== 'string') return mobileNumber
66
+
67
+ if(mobileNumber.length > 0){
68
+ mobileNumber = mobileNumber.replace(/[\- ]/g, '')
69
+ if(mobileNumber.substring(0, 1) === '0') mobileNumber = '+62' + mobileNumber.substring(1)
70
+ if(mobileNumber.substring(0, 1) !== '+'){
71
+ if(mobileNumber.substring(0, 2) === '62')
72
+ mobileNumber = '+' + mobileNumber
73
+ else
74
+ mobileNumber = '+62' + mobileNumber
75
+ }
76
+ if(mobileNumber.length > 0){
77
+ mobileNumber = mobileNumber[0] + mobileNumber.slice(1).replace(/\D/g, '')
78
+ }
79
+ }
80
+
81
+ return mobileNumber
82
+ }
83
+
84
+ const saveBase64 = async(data, dir = '/storage/files/images') => {
85
+ if(data.indexOf(',') >= 0){
86
+ data = data.substring(data.indexOf(',') + 1)
87
+ }
88
+ const buffer = Buffer.from(data, 'base64');
89
+ return await saveBuffer(buffer, dir)
90
+ }
91
+
92
+ const saveBuffer = async(buffer, dir = '/storage/files/images') => {
93
+
94
+ const { fileTypeFromBuffer } = await import('file-type')
95
+
96
+ const type = await fileTypeFromBuffer(buffer)
97
+
98
+ const storagePath = process.env.ROOT_PATH + (dir)
99
+ const ext = type && type.ext ? '.' + type.ext : ''
100
+ const filename = md5(buffer) + ext
101
+ const to = storagePath + '/' + filename
102
+
103
+ fs.writeFileSync(to, buffer)
104
+
105
+ return filename
106
+ }
107
+
108
+ const saveFromUrl = async(url, dir = '/storage/files/images') => {
109
+
110
+ const res = await axios({
111
+ method: 'GET',
112
+ url,
113
+ responseType: 'arraybuffer',
114
+ })
115
+ const buffer = Buffer.from(res.data)
116
+ return await saveBuffer(buffer, dir)
117
+ }
118
+
119
+ const sleep = ms => new Promise(r => setTimeout(r, ms))
120
+
121
+ const strSlug = (title, separator) => {
122
+ if (typeof separator == 'undefined') separator = '-';
123
+
124
+ // Convert all dashes/underscores into separator
125
+ var flip = separator === '-' ? '_' : '-';
126
+ title = title.replace(flip, separator);
127
+
128
+ // Remove all characters that are not the separator, letters, numbers, or whitespace.
129
+ title = title.toLowerCase()
130
+ .replace(new RegExp('[^a-z0-9' + separator + '\\s]', 'g'), '');
131
+
132
+ // Replace all separator characters and whitespace by a single separator
133
+ title = title.replace(new RegExp('[' + separator + '\\s]+', 'g'), separator);
134
+
135
+ return title.replace(new RegExp('^[' + separator + '\\s]+|[' + separator + '\\s]+$', 'g'),'');
136
+ }
137
+
138
+ const strVars = (text, vars) => {
139
+
140
+ (text.match(/\{.*?(?=\})\}/gi) ?? []).forEach((match) => {
141
+ const key = match.substring(1, match.length - 1)
142
+ const value = vars[key] ?? ''
143
+ text = text.replace(match, value)
144
+ })
145
+
146
+ return text
147
+ }
148
+
149
+ const writeStorage = (path, content, append = false) => {
150
+
151
+ if(path.startsWith('/')) path = path.substring(1)
152
+
153
+ if(append){
154
+ fs.appendFileSync(process.env.ROOT_PATH + `/storage/${path}`, content)
155
+ }
156
+ else{
157
+ fs.writeFileSync(process.env.ROOT_PATH + `/storage/${path}`, content)
158
+ }
159
+ }
160
+
161
+ const bufferToStream = (buffer) => {
162
+ const { Duplex } = require('stream')
163
+ let stream = new Duplex()
164
+ stream.push(buffer)
165
+ stream.push(null)
166
+ return stream
167
+ }
168
+
169
+
170
+ module.exports = {
171
+ ceil,
172
+ floor,
173
+ ftWildcard,
174
+ moveFile,
175
+ round,
176
+ sanitizeMobileNumber,
177
+ saveBase64,
178
+ saveBuffer,
179
+ saveFromUrl,
180
+ sleep,
181
+ strSlug,
182
+ strVars,
183
+ writeStorage,
184
+ bufferToStream
185
+ }
@@ -0,0 +1,197 @@
1
+
2
+ const csvToArray = (str, delimiter = null) => {
3
+
4
+ if(!delimiter){
5
+ delimiter = str.indexOf(';') >= 0 ? ';' : ','
6
+ }
7
+
8
+ str = str.trim()
9
+
10
+ const headers = str.slice(0, str.indexOf("\n")).split(delimiter);
11
+
12
+ const rows = str.slice(str.indexOf("\n") + 1).split("\n");
13
+
14
+ const arr = rows.map(function (row) {
15
+ const values = row.split(delimiter);
16
+ let el = {}
17
+ if(values.length === headers.length){
18
+ el = headers.reduce(function (object, header, index) {
19
+ object[header] = values[index];
20
+ return object;
21
+ }, {});
22
+ }
23
+ return el;
24
+ })
25
+ .filter((_) => Object.keys(_).length > 0);
26
+
27
+ return arr;
28
+ }
29
+
30
+ const downsizeImage = async (url, targetWidth, imageType, quality, opt = {}) => {
31
+
32
+ let defaultImageType = 'image/jpeg'
33
+
34
+ if(url instanceof File){
35
+
36
+ defaultImageType = url.type
37
+
38
+ await (new Promise((resolve, reject) => {
39
+ var reader = new FileReader();
40
+ reader.addEventListener('load', () => {
41
+ url = reader.result
42
+ resolve()
43
+ }, false)
44
+ reader.addEventListener('error', (e) => {
45
+ reject(e)
46
+ })
47
+ reader.readAsDataURL(url);
48
+ }))
49
+ }
50
+
51
+ return new Promise((resolve, reject) => {
52
+
53
+ const image = new Image()
54
+ image.addEventListener('load', () => {
55
+
56
+ const canvasWidth = image.width > targetWidth ? targetWidth : image.width
57
+ const canvasHeight = Math.round((image.height / image.width) * canvasWidth)
58
+
59
+ const canvas = document.createElement('canvas');
60
+ canvas.width = canvasWidth;
61
+ canvas.height = canvasHeight;
62
+
63
+ if(opt.constraint){
64
+ if(canvasWidth / canvasHeight !== opt.constraint)
65
+ reject(new Error('Image constraint error'))
66
+ }
67
+
68
+ const ctx = canvas.getContext("2d");
69
+ ctx.drawImage(image, 0, 0, canvasWidth, canvasHeight);
70
+
71
+ canvas.toBlob((blob) => {
72
+ resolve(blob)
73
+ }, imageType ?? defaultImageType, quality ?? .8)
74
+ })
75
+ image.addEventListener('error', (e) => {
76
+ reject(e)
77
+ })
78
+ image.src = url
79
+ })
80
+ }
81
+
82
+ const parseBoolean = function(exp){
83
+ return [ 'true', 1, true ].includes(typeof exp === 'string' ?
84
+ exp.toLowerCase() : exp)
85
+ }
86
+
87
+ const strVars = function(text, vars){
88
+
89
+ (text.match(/\{.*?(?=\})\}/gi) ?? []).forEach((match) => {
90
+ const key = match.substring(1, match.length - 1)
91
+ const value = vars[key] ?? ''
92
+ text = text.replace(match, value)
93
+ })
94
+
95
+ return text
96
+ }
97
+
98
+ let _QS
99
+ const urlQuery = function(){
100
+
101
+ if(!_QS){
102
+ _QS = new Proxy(new URLSearchParams(window.location.search), {
103
+ get: (searchParams, prop) => searchParams.get(prop),
104
+ });
105
+ }
106
+
107
+ return _QS
108
+ }
109
+
110
+ const getQueryString = function(key){
111
+ urlQuery()
112
+
113
+ if(typeof key === 'string'){
114
+ return _QS[key]
115
+ }
116
+ else if(Array.isArray(key)){
117
+ return key.map((k) => {
118
+ return _QS[k]
119
+ })
120
+ }
121
+ }
122
+
123
+ let __uid = new Date().getTime()
124
+ const uid = function(prefix){
125
+ return (prefix ?? '') + __uid++;
126
+ }
127
+
128
+ export {
129
+ downsizeImage,
130
+ uid,
131
+ observeInit,
132
+ csvToArray,
133
+ parseBoolean,
134
+ urlQuery,
135
+ getQueryString
136
+ }
137
+
138
+ function observeInit(){
139
+
140
+ const intersectionObserver = new IntersectionObserver(
141
+ onIntersection,
142
+ {
143
+ rootMargin: '50px 50px 50px 50px',
144
+ threshold: 0.01,
145
+ }
146
+ )
147
+
148
+ function onIntersection(entries, observer) {
149
+
150
+ entries.forEach((entry) => {
151
+ if (entry.intersectionRatio === 0) {
152
+ return;
153
+ }
154
+
155
+ const item = entry.target
156
+ const key = item.__observeKey
157
+ const { type, callback } = observeCols[key]
158
+
159
+ if(typeof callback === 'function')
160
+ callback.apply(item)
161
+
162
+ if(type === 'once'){
163
+ observer.unobserve(item)
164
+ delete observeCols[key]
165
+ }
166
+ })
167
+ }
168
+
169
+ const observeCols = {}
170
+
171
+ const once = function(el, callback)
172
+ {
173
+ if(typeof el.__observeKey !== 'undefined') return
174
+
175
+ intersectionObserver.observe(el)
176
+
177
+ const key = 'observe-' + uid()
178
+ observeCols[key] = { type:'once', callback }
179
+ el.__observeKey = key
180
+ }
181
+
182
+ const always = function(el, callback)
183
+ {
184
+ if(typeof el.__observeKey !== 'undefined') return
185
+
186
+ intersectionObserver.observe(el)
187
+
188
+ const key = 'observe-' + uid()
189
+ observeCols[key] = { type:'one', callback }
190
+ el.__observeKey = key
191
+ }
192
+
193
+ return {
194
+ once,
195
+ always
196
+ }
197
+ }
@@ -0,0 +1,156 @@
1
+ const md5 = require("md5");
2
+ const fs = require("fs");
3
+ const AdmZip = require("adm-zip");
4
+ const glob = require("glob");
5
+ const Exceljs = require("exceljs")
6
+ const { saveBuffer } = require('./helpers.js')
7
+
8
+ const analyseRequest = async(req) => {
9
+
10
+ const file = req.files[0]
11
+ const ext = file.originalname.split('.').slice(-1).pop()
12
+
13
+ let folderName = md5('motor-import-analyse' + new Date().getTime())
14
+ let xlsxFileType, xlsxFile
15
+
16
+ fs.mkdirSync(process.env.ROOT_PATH + '/storage/files/temp/' + folderName)
17
+
18
+ if(ext === 'zip'){
19
+
20
+ const zip = new AdmZip(file.buffer)
21
+ zip.extractAllTo(process.env.ROOT_PATH + '/storage/files/temp/' + folderName, true)
22
+
23
+ const res = glob.sync(process.env.ROOT_PATH + '/storage/files/temp/' + folderName + '/**/*(*.xlsx|*.csv)')
24
+
25
+ if(res.length < 1)
26
+ throw new Error('Invalid file')
27
+ else if(res.length > 1)
28
+ throw new Error('Invalid file')
29
+ else{
30
+ xlsxFile = res[0]
31
+ xlsxFileType = xlsxFile.split('.').slice(-1).pop()
32
+ }
33
+ }
34
+
35
+ else{
36
+ xlsxFileType = ext
37
+ const filename = await saveBuffer(file.buffer, '/storage/files/temp/' + folderName)
38
+ xlsxFile = process.env.ROOT_PATH + '/storage/files/temp/' + folderName + '/' + filename
39
+ }
40
+
41
+
42
+ const workbook = new Exceljs.Workbook();
43
+ switch(xlsxFileType){
44
+
45
+ case 'xlsx':
46
+ await workbook.xlsx.readFile(xlsxFile)
47
+ break
48
+
49
+ case 'csv':
50
+ await workbook.csv.readFile(xlsxFile, {
51
+ parserOptions: {
52
+ delimiter: ';'
53
+ }
54
+ });
55
+ break
56
+ }
57
+
58
+ if(workbook.worksheets.length > 1)
59
+ throw new Error('Number of sheet allowed within file is 1')
60
+ else if(workbook.worksheets.length < 1)
61
+ throw new Error('Unable to read worksheet')
62
+
63
+ const worksheet = workbook.worksheets[0]
64
+
65
+ const columns = []
66
+ const header = worksheet.getRow(1)
67
+ if(!header)
68
+ throw new Error('Invalid file')
69
+ header.eachCell((cell) => {
70
+ columns.push(cell.value)
71
+ })
72
+
73
+ return {
74
+ columns,
75
+ folderName,
76
+ xlsxFileType,
77
+ xlsxFile
78
+ }
79
+ }
80
+
81
+ const importRequest = async(req) => {
82
+
83
+ const { columns, folderName, xlsxFileType, xlsxFile, keys } = req.body
84
+
85
+ keys.forEach((key) => {
86
+ if (key.required && !key.value)
87
+ throw new Error({name: ['Kolom ' + key.text + ' harus diisi']})
88
+ })
89
+
90
+ const rows = []
91
+ const cols = {}
92
+ const workbook = new Exceljs.Workbook();
93
+ switch(xlsxFileType){
94
+
95
+ case 'xlsx':
96
+ await workbook.xlsx.readFile(xlsxFile)
97
+ break
98
+
99
+ case 'csv':
100
+ await workbook.csv.readFile(xlsxFile, {
101
+ parserOptions: {
102
+ delimiter: ';'
103
+ }
104
+ });
105
+ break
106
+ }
107
+
108
+ 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
+
121
+ if(!mapped){
122
+ cols[cell.value] = index
123
+ }
124
+ })
125
+ }
126
+ else{
127
+ const obj = {}
128
+
129
+ for(let key in cols){
130
+ const cell = row.getCell(cols[key])
131
+ obj[key] = cell.formulaType === 1 ? cell.result : cell.value
132
+ }
133
+
134
+ rows.push(obj)
135
+ }
136
+ })
137
+
138
+ //console.log(JSON.stringify(rows, null, 2))
139
+
140
+ const images = glob.sync(process.env.ROOT_PATH + '/storage/files/temp/' + folderName +
141
+ '/**/*(*.jpg|*.jpeg|*.png|*.webp)')
142
+
143
+ return {
144
+ ...req.body,
145
+ rows,
146
+ images,
147
+ columns,
148
+ keys
149
+ }
150
+ }
151
+
152
+
153
+ module.exports = {
154
+ analyseRequest,
155
+ importRequest
156
+ }