@ditojs/admin 1.12.0 → 1.13.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ditojs/admin",
3
- "version": "1.12.0",
3
+ "version": "1.13.0",
4
4
  "type": "module",
5
5
  "description": "Dito.js Admin is a schema based admin interface for Dito.js Server, featuring auto-generated views and forms and built with Vue.js",
6
6
  "repository": "https://github.com/ditojs/dito/tree/master/packages/admin",
@@ -17,12 +17,14 @@
17
17
  },
18
18
  "files": [
19
19
  "src/",
20
- "dist/"
20
+ "dist/",
21
+ "types/"
21
22
  ],
22
23
  "scripts": {
23
24
  "build": "vite build",
24
25
  "watch": "yarn build --mode 'development' --watch",
25
- "prepare": "yarn build"
26
+ "prepare": "yarn build",
27
+ "types": "tsc --noEmit types/index.d.ts"
26
28
  },
27
29
  "engines": {
28
30
  "node": ">= 18.0.0",
@@ -35,8 +37,8 @@
35
37
  "not ie_mob > 0"
36
38
  ],
37
39
  "dependencies": {
38
- "@ditojs/ui": "^1.12.0",
39
- "@ditojs/utils": "^1.12.0",
40
+ "@ditojs/ui": "^1.13.0",
41
+ "@ditojs/utils": "^1.13.0",
40
42
  "codeflask": "^1.4.1",
41
43
  "filesize": "^10.0.5",
42
44
  "filesize-parser": "^1.5.0",
@@ -58,11 +60,14 @@
58
60
  "vuedraggable": "^2.24.3"
59
61
  },
60
62
  "devDependencies": {
61
- "@ditojs/build": "^1.12.0",
63
+ "@ditojs/build": "^1.13.0",
62
64
  "pug": "^3.0.2",
63
65
  "sass": "1.55.0",
66
+ "type-fest": "^3.1.0",
67
+ "typescript": "^4.8.4",
64
68
  "vite": "^3.2.2",
65
69
  "vite-plugin-vue2": "^2.0.2"
66
70
  },
67
- "gitHead": "3707045b72d84db4b5174d2efeb8cf62e2065ffa"
71
+ "types": "types",
72
+ "gitHead": "b65d7d15871b0d11579565df92780536ef2926da"
68
73
  }
package/src/DitoAdmin.js CHANGED
@@ -39,8 +39,8 @@ export default class DitoAdmin {
39
39
  api.locale ||= 'en-US'
40
40
  api.formats = merge({}, defaultFormats, api.formats)
41
41
  api.request ||= options => request(api, options)
42
- api.getApiUrl ||= path => getApiUrl(api, path)
43
- api.isApiRequest ||= url => isApiRequest(api, url)
42
+ api.getApiUrl ||= options => getApiUrl(api, options)
43
+ api.isApiUrl ||= url => isApiUrl(api, url)
44
44
  // Setting `api.normalizePaths = true (plural) sets both:
45
45
  // `api.normalizePath = hyphenate` and `api.denormalizePath = camelize`
46
46
  api.normalizePath ||= api.normalizePaths ? hyphenate : val => val
@@ -210,24 +210,16 @@ async function request(api, {
210
210
  deprecate(`request.params is deprecated. Use action.method and action.path instead.`)
211
211
  }
212
212
 
213
- const isApiRequest = api.isApiRequest(url)
214
- if (isApiRequest && !isAbsoluteUrl(url)) {
215
- url = api.getApiUrl(url)
216
- }
217
-
218
- const search = query && new URLSearchParams(query).toString()
219
- if (search) {
220
- url = `${url}?${search}`
221
- }
213
+ const isApiUrl = api.isApiUrl(url)
222
214
 
223
- const response = await fetch(url, {
215
+ const response = await fetch(api.getApiUrl({ url, query }), {
224
216
  method: method.toUpperCase(),
225
217
  ...(data && { body: JSON.stringify(data) }),
226
218
  headers: {
227
- ...(isApiRequest && api.headers),
219
+ ...(isApiUrl && api.headers),
228
220
  ...headers
229
221
  },
230
- credentials: isApiRequest && api.cors?.credentials
222
+ credentials: isApiUrl && api.cors?.credentials
231
223
  ? 'include'
232
224
  : 'same-origin'
233
225
  })
@@ -242,11 +234,16 @@ async function request(api, {
242
234
  return response
243
235
  }
244
236
 
245
- function getApiUrl(api, path) {
246
- // Use same approach as axios `combineURLs()` to join baseURL with path:
247
- return `${api.url.replace(/\/+$/, '')}/${path.replace(/^\/+/, '')}`
237
+ function getApiUrl(api, { url, query }) {
238
+ if (!isAbsoluteUrl(url)) {
239
+ // Use same approach as axios `combineURLs()` to join baseURL with path:
240
+ url = `${api.url.replace(/\/+$/, '')}/${url.replace(/^\/+/, '')}`
241
+ }
242
+ // Support optional query parameters, to be are added to the URL.
243
+ const search = query && new URLSearchParams(query).toString()
244
+ return search ? `${url}?${search}` : url
248
245
  }
249
246
 
250
- function isApiRequest(api, url) {
247
+ function isApiUrl(api, url) {
251
248
  return !isAbsoluteUrl(url) || url.startsWith(api.url)
252
249
  }
@@ -292,19 +292,14 @@ export default {
292
292
  },
293
293
 
294
294
  getResourceUrl(resource) {
295
- const path = this.getResourcePath(resource)
296
- if (!path) return null
297
- const url = this.api.getApiUrl(path)
298
- // Support optional query parameters, to be are added to the URL.
299
- const { query } = resource
300
- const search = query && new URLSearchParams(query).toString()
301
- return search ? `${url}?${search}` : url
295
+ const url = this.getResourcePath(resource)
296
+ return url ? this.api.getApiUrl({ url, query: resource.query }) : null
302
297
  },
303
298
 
304
299
  async sendRequest({ method, url, resource, query, data, internal }) {
305
300
  url ||= this.getResourcePath(resource)
306
301
  method ||= resource?.method
307
- const checkUser = !internal && this.api.isApiRequest(url)
302
+ const checkUser = !internal && this.api.isApiUrl(url)
308
303
  if (checkUser) {
309
304
  await this.rootComponent.ensureUser()
310
305
  }
@@ -385,13 +380,10 @@ export default {
385
380
  if (isString(options)) {
386
381
  options = { url: options }
387
382
  }
388
- const { url, filename } = options
389
383
  // See: https://stackoverflow.com/a/49917066/1163708
390
384
  const a = document.createElement('a')
391
- a.href = url
392
- if (filename) {
393
- a.download = filename
394
- }
385
+ a.href = this.api.getApiUrl(options)
386
+ a.download = options.filename ?? null
395
387
  const { body } = document
396
388
  body.appendChild(a)
397
389
  a.click()
@@ -135,11 +135,13 @@ export default TypeComponent.register('color', {
135
135
  default: 'hex'
136
136
  }),
137
137
 
138
+ // TODO: Rename to `showAlpha`?
138
139
  alpha: getSchemaAccessor('alpha', {
139
140
  type: Boolean,
140
141
  default: false
141
142
  }),
142
143
 
144
+ // TODO: Rename to `showInputs`?
143
145
  inputs: getSchemaAccessor('inputs', {
144
146
  type: Boolean,
145
147
  default: true
@@ -293,8 +293,8 @@ export default TypeComponent.register('multiselect', {
293
293
  placeholder() {
294
294
  const { placeholder, searchable, taggable } = this.schema
295
295
  return placeholder || (
296
- searchable && taggable ? 'Search or add a tag'
297
- : searchable ? 'Select or search entry'
296
+ searchable && taggable ? `Search or add a ${this.label}`
297
+ : searchable ? `Select or search ${this.label}`
298
298
  : undefined
299
299
  )
300
300
  }
@@ -50,6 +50,7 @@ export default TypeComponent.register('slider', {
50
50
  nativeField: true,
51
51
 
52
52
  computed: {
53
+ // TODO: Rename to `showInput`?
53
54
  input: getSchemaAccessor('input', {
54
55
  type: Boolean,
55
56
  default: true