mango-cms 0.2.22 → 0.2.24

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/cli.js CHANGED
@@ -400,8 +400,8 @@ server {
400
400
  root ${buildPath.replace('/build', '/dist')};
401
401
  index index.html;
402
402
 
403
- # Serve static files directly
404
- location ~* \.(?:js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|otf|json)$ {
403
+ # Serve static files directly if they exist
404
+ location ~* \.(?:js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|otf|json|html)$ {
405
405
  expires 1y;
406
406
  access_log off;
407
407
  add_header Cache-Control "public";
@@ -413,8 +413,9 @@ server {
413
413
  }
414
414
  ` : ''}
415
415
 
416
+ # All other routes go to the fallback unless the file exists
416
417
  location / {
417
- try_files $uri $uri/ @fallback;
418
+ try_files $uri @fallback;
418
419
  }
419
420
 
420
421
  location @fallback {
@@ -25,7 +25,7 @@
25
25
  "dayjs": "^1.10.7",
26
26
  "express": "^4.18.1",
27
27
  "google-maps": "^4.3.3",
28
- "mango-cms": "^0.2.22",
28
+ "mango-cms": "^0.2.24",
29
29
  "mapbox-gl": "^2.7.0",
30
30
  "sweetalert2": "^11.4.0",
31
31
  "vite": "^6.2.2",
@@ -32,7 +32,8 @@
32
32
  </template>
33
33
 
34
34
  <template v-else>
35
- <div class="text-2xl">Mango Login</div>
35
+ <div class="-mb-4 uppercase opacity-50 tracking-widest text-sm">Login</div>
36
+ <div class="text-2xl">{{ siteName }}</div>
36
37
  <input type="email" v-model.trim="user.email" placeholder="Email" />
37
38
  <input type="password" v-model.trim="user.password" placeholder="Password" autocomplete="current-password" />
38
39
  </template>
@@ -59,6 +60,7 @@
59
60
  import Swal from 'sweetalert2'
60
61
  import { validateEmail } from '../../helpers/email'
61
62
  import { getUser } from '../../helpers/user'
63
+ import { siteName } from '@settings'
62
64
 
63
65
  // Function for setting cookies
64
66
  let setCookie = function (cname, cvalue) {
@@ -72,6 +74,7 @@ export default {
72
74
  inject: ['store','axios'],
73
75
  data() {
74
76
  return {
77
+ siteName,
75
78
  user: {
76
79
  email: null,
77
80
  password: null,
@@ -1,5 +1,5 @@
1
1
  import axios from "axios"
2
- import Mango from "./mango"
2
+ // import Mango from "./mango"
3
3
  import Swal from "sweetalert2"
4
4
 
5
5
  // Function for setting cookies
@@ -73,7 +73,7 @@ export default class LocalDB {
73
73
 
74
74
  }
75
75
 
76
- async save(entry, syncing) {
76
+ async save(mangoSave, entry, options = {}) {
77
77
 
78
78
  if (!this.ready) return
79
79
 
@@ -102,18 +102,23 @@ export default class LocalDB {
102
102
 
103
103
  if (existingEntry) entry = { ...existingEntry, ...entry }
104
104
 
105
+ // Handle if the field is an image or array of images
106
+ let imageFields = {}
107
+ for (let key in entry) {
108
+ if (entry[key]?.type?.includes?.('image') || entry[key]?.type?.includes?.('array') && entry[key]?.[0]?.type?.includes?.('image')) {
109
+ imageFields[key] = entry[key]
110
+ delete entry[key]
111
+ }
112
+ }
113
+
105
114
  // Remove Vue Proxy stuff so indexedDB is happy
106
- let savedImage = entry.image
107
- delete entry.image
108
115
  entry = JSON.parse(JSON.stringify(entry))
109
- if (!syncing) entry.updatedLocally = new Date()
110
-
111
- // Format Address for offline
112
- // if (!entry.address?.id && entry.address?.formatted) entry.address = entry.address.formatted
116
+ if (!options.syncing) entry.updatedLocally = new Date()
113
117
 
114
- // Handle images
115
- if (savedImage?.type?.includes?.('image')) entry.image = savedImage
116
- if (savedImage?.includes?.('http')) entry.image = savedImage
118
+ // Add images back in after json formatting
119
+ for (let key in imageFields) {
120
+ entry[key] = imageFields[key]
121
+ }
117
122
 
118
123
 
119
124
  let method = entryExists ? 'put' : 'add'
@@ -152,15 +157,26 @@ export default class LocalDB {
152
157
 
153
158
  delete entry.updatedLocally
154
159
 
160
+ // // Save to Mango (timeout if already created, else no timeout)
161
+ // let response
162
+ // if (onlyLocal) {
163
+ // response = await Mango[this.collection].save(entry, { bypassLocal: true })
164
+ // // if (warnings?.length) Swal.fire('WARNING:', warnings?.join(', '), 'warning')
165
+ // // console.log('mangoResponse', mangoResponse)
166
+ // // response = mangoResponse
167
+ // }
168
+ // else response = await runWithTimeout(async () => await Mango[this.collection].save(entry, { bypassLocal: true }), 5000)
169
+
170
+
155
171
  // Save to Mango (timeout if already created, else no timeout)
156
172
  let response
157
173
  if (onlyLocal) {
158
- let { response: mangoResponse, warnings } = await Mango[this.collection].save(entry, null, true)
159
- if (warnings?.length) Swal.fire('WARNING:', warnings?.join(', '), 'warning')
160
- console.log('mangoResponse', mangoResponse)
161
- response = mangoResponse
174
+ response = await mangoSave(entry, { bypassLocal: true })
175
+ // if (warnings?.length) Swal.fire('WARNING:', warnings?.join(', '), 'warning')
176
+ // console.log('mangoResponse', mangoResponse)
177
+ // response = mangoResponse
162
178
  }
163
- else response = await runWithTimeout(async () => await Mango[this.collection].save(entry), 5000)
179
+ else response = await runWithTimeout(async () => await mangoSave(entry, { bypassLocal: true }), 5000)
164
180
 
165
181
  // If successfull, delete from local queue
166
182
  if (response?.id) {
@@ -5,6 +5,10 @@ import { algoliaAppId, algoliaSearchKey, algoliaIndex, port, mangoDomain, useDev
5
5
  import axios from "axios";
6
6
  import { ref } from 'vue'
7
7
  import algoliasearch from 'algoliasearch/dist/algoliasearch-lite.esm.browser'
8
+ import LocalDB from './localDB'
9
+
10
+ import { useRoute } from 'vue-router'
11
+ let route = useRoute()
8
12
 
9
13
  let endpoints = {
10
14
  authors: ['get'],
@@ -48,6 +52,8 @@ function getQuery(params) {
48
52
 
49
53
  const Mango = collections.reduce((a, c) => {
50
54
 
55
+ let localDB = new LocalDB(c.name, api)
56
+
51
57
  let runQuery = ({ limit, page, search, fields, id, sort, depthLimit, verbose } = {}) => {
52
58
 
53
59
  let fullQuery
@@ -121,7 +127,8 @@ const Mango = collections.reduce((a, c) => {
121
127
 
122
128
  }
123
129
 
124
- let save = (data, options = {}) => {
130
+ let mangoSave = (data, options = {}) => {
131
+
125
132
  let { id } = data
126
133
  let method = id ? 'put' : 'post'
127
134
 
@@ -152,6 +159,12 @@ const Mango = collections.reduce((a, c) => {
152
159
  })
153
160
  }
154
161
 
162
+ let save = (data, options = {}) => {
163
+ console.log('FROM SAVE:', data)
164
+ if (!options.bypassLocal) return localDB.save(save, data, options)
165
+ else return mangoSave(data, options)
166
+ }
167
+
155
168
  let deleteEntry = (data) => {
156
169
  let id = data.id || data
157
170
 
@@ -164,11 +177,65 @@ const Mango = collections.reduce((a, c) => {
164
177
  })
165
178
  }
166
179
 
180
+
181
+ let sync = () => {
182
+
183
+ let remainingEntries = ref([])
184
+ let syncedEntries = ref([])
185
+ let online = ref(navigator.onLine)
186
+ let syncing = ref(false)
187
+
188
+ setInterval(async () => {
189
+
190
+ console.log('syncing', syncing.value, route?.params?.id)
191
+ online.value = navigator.onLine
192
+
193
+ if (syncing.value) return
194
+
195
+ syncing.value = true
196
+
197
+ let entries = await localDB.getEntries()
198
+ remainingEntries.value = entries?.filter(e => (new Date() - new Date(e.updatedLocally)) > 30*1000)
199
+
200
+ for (let [index, entry] of remainingEntries.value.entries()) {
201
+
202
+ // Don't sync what we're actively working on
203
+ if (route?.params?.id == entry.id || (!isNaN(entry.id) && window.location.pathname.includes(`/${entry.id}`))) {
204
+ console.log('skipping', entry.id)
205
+ continue
206
+ }
207
+
208
+ try {
209
+ let response = await save(entry, {syncing: true})
210
+ if (response?.id) remainingEntries.value.splice(index, 1)
211
+ } catch(e) {
212
+ console.log('Error saving entry', e, entry)
213
+ }
214
+
215
+ await new Promise(resolve => setTimeout(resolve, 10*1000))
216
+
217
+ }
218
+
219
+ syncing.value = false
220
+ syncedEntries.value = []
221
+
222
+ }, 500)
223
+
224
+
225
+ return { remainingEntries, syncedEntries, online, syncing }
226
+
227
+ }
228
+
167
229
  a[c.name] = runQuery
168
230
  a[c.name]['save'] = save
169
231
  a[c.name]['delete'] = deleteEntry
170
232
  a[c.singular] = (id, query) => runQuery({ id, ...query })
171
233
 
234
+ a[c.name]['local'] = localDB.getEntries
235
+ a[c.singular]['local'] = localDB.get
236
+ a[c.singular]['local']['delete'] = localDB.delete
237
+ a[c.name]['sync'] = sync
238
+
172
239
  a[c.name]['search'] = runAlgolia
173
240
  a[c.name]['search']['init'] = (search, query, algoliaFilters) => {
174
241
  let loading = ref(true)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mango-cms",
3
- "version": "0.2.22",
3
+ "version": "0.2.24",
4
4
  "main": "./index.js",
5
5
  "exports": {
6
6
  ".": "./index.js",
package/webpack.config.js CHANGED
@@ -27,12 +27,18 @@ module.exports = {
27
27
  mode: 'production',
28
28
  resolve: {
29
29
  alias: {
30
+
31
+ '@mango$': path.resolve(mangoRoot, 'src/cms/exports'),
32
+ '@mango': path.resolve(userProjectRoot, legacyMode ? 'config' : 'mango'),
33
+
30
34
  '@cms': path.resolve(mangoRoot, 'src/cms'),
31
35
  '@config': path.resolve(userProjectRoot, legacyMode ? 'config' : 'mango'),
32
- '@mango': path.resolve(userProjectRoot, legacyMode ? 'config' : 'mango'),
36
+ '@settings': path.resolve(userProjectRoot, legacyMode ? 'config/config/settings.json' : 'mango/config/settings.json'),
33
37
  '@fields': path.resolve(mangoRoot, 'src/cms/1. build/fields'),
34
38
  '@mongo': path.resolve(mangoRoot, 'src/cms/1. build/libraries/mongo'),
39
+ '@query': path.resolve(mangoRoot, 'src/cms/1. build/libraries/mongo'),
35
40
  '@helpers': path.resolve(mangoRoot, 'src/cms/1. build/helpers'),
41
+ '@main': path.resolve(mangoRoot, 'src/cms/2. process/0. main'),
36
42
  },
37
43
  },
38
44
  devtool: 'inline-source-map',