@kaspernj/api-maker 1.0.349 → 1.0.350
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 +2 -2
- package/src/api.mjs +9 -12
- package/src/base-model.mjs +4 -0
- package/src/commands-pool.mjs +12 -12
- package/src/devise.mjs +13 -19
- package/src/logger.mjs +1 -7
- package/src/session-status-updater.mjs +24 -73
- package/src/super-admin/model-class-table.jsx +19 -14
- package/src/use-current-user.mjs +18 -21
package/package.json
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
]
|
|
17
17
|
},
|
|
18
18
|
"name": "@kaspernj/api-maker",
|
|
19
|
-
"version": "1.0.
|
|
19
|
+
"version": "1.0.350",
|
|
20
20
|
"type": "module",
|
|
21
21
|
"description": "",
|
|
22
22
|
"main": "index.js",
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"babel-jest": "^29.0.1",
|
|
71
71
|
"eslint": "^8.2.0",
|
|
72
72
|
"eslint-find-rules": "^4.0.0",
|
|
73
|
-
"eslint-plugin-jest": "^
|
|
73
|
+
"eslint-plugin-jest": "^27.0.1",
|
|
74
74
|
"eslint-plugin-react": "^7.23.2",
|
|
75
75
|
"i18n-on-steroids": "^1.0.7",
|
|
76
76
|
"jest": "^29.0.1",
|
package/src/api.mjs
CHANGED
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
import config from "./config.mjs"
|
|
2
2
|
import CustomError from "./custom-error.mjs"
|
|
3
3
|
import FormDataObjectizer from "form-data-objectizer"
|
|
4
|
-
import Logger from "./logger.mjs"
|
|
5
4
|
import qs from "qs"
|
|
6
|
-
import SessionStatusUpdater from "./session-status-updater.mjs"
|
|
7
|
-
|
|
8
|
-
const logger = new Logger({name: "ApiMaker / Api"})
|
|
9
|
-
|
|
10
|
-
// logger.setDebug(true)
|
|
11
5
|
|
|
12
6
|
export default class Api {
|
|
13
7
|
static get(path, pathParams = null) {
|
|
@@ -68,14 +62,12 @@ export default class Api {
|
|
|
68
62
|
})
|
|
69
63
|
}
|
|
70
64
|
|
|
71
|
-
static
|
|
65
|
+
static requestLocal(args) {
|
|
72
66
|
if (!args.headers) {
|
|
73
67
|
args.headers = {}
|
|
74
68
|
}
|
|
75
69
|
|
|
76
|
-
const token =
|
|
77
|
-
|
|
78
|
-
logger.debug(() => `Got token: ${token}`)
|
|
70
|
+
const token = this._token()
|
|
79
71
|
|
|
80
72
|
if (token) {
|
|
81
73
|
args.headers["X-CSRF-Token"] = token
|
|
@@ -90,14 +82,19 @@ export default class Api {
|
|
|
90
82
|
args.data = args.rawData
|
|
91
83
|
}
|
|
92
84
|
|
|
93
|
-
return
|
|
85
|
+
return this.request(args)
|
|
94
86
|
}
|
|
95
87
|
|
|
96
88
|
static put(path, data = {}) {
|
|
97
89
|
return this.requestLocal({path, data, method: "PUT"})
|
|
98
90
|
}
|
|
99
91
|
|
|
100
|
-
static _token
|
|
92
|
+
static _token() {
|
|
93
|
+
const tokenElement = document.querySelector("meta[name='csrf-token']")
|
|
94
|
+
|
|
95
|
+
if (tokenElement)
|
|
96
|
+
return tokenElement.getAttribute("content")
|
|
97
|
+
}
|
|
101
98
|
|
|
102
99
|
static _parseResponse(xhr) {
|
|
103
100
|
const responseType = xhr.getResponseHeader("content-type")
|
package/src/base-model.mjs
CHANGED
|
@@ -107,6 +107,10 @@ export default class BaseModel {
|
|
|
107
107
|
return new Collection({modelClass: this}, {ransack: query})
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
+
static select(select) {
|
|
111
|
+
return this.ransack().select(select)
|
|
112
|
+
}
|
|
113
|
+
|
|
110
114
|
static ransackableAssociations() {
|
|
111
115
|
const relationships = digg(this.modelClassData(), "ransackable_associations")
|
|
112
116
|
const reflections = []
|
package/src/commands-pool.mjs
CHANGED
|
@@ -14,7 +14,7 @@ import {ValidationErrors} from "./validation-errors.mjs"
|
|
|
14
14
|
const shared = {}
|
|
15
15
|
|
|
16
16
|
export default class ApiMakerCommandsPool {
|
|
17
|
-
static addCommand(data, args = {}) {
|
|
17
|
+
static addCommand (data, args = {}) {
|
|
18
18
|
let pool
|
|
19
19
|
|
|
20
20
|
if (args.instant) {
|
|
@@ -34,17 +34,17 @@ export default class ApiMakerCommandsPool {
|
|
|
34
34
|
return promiseResult
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
static current() {
|
|
37
|
+
static current () {
|
|
38
38
|
if (!shared.currentApiMakerCommandsPool) shared.currentApiMakerCommandsPool = new ApiMakerCommandsPool()
|
|
39
39
|
|
|
40
40
|
return shared.currentApiMakerCommandsPool
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
static flush() {
|
|
43
|
+
static flush () {
|
|
44
44
|
ApiMakerCommandsPool.current().flush()
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
constructor() {
|
|
47
|
+
constructor () {
|
|
48
48
|
this.flushCount = 0
|
|
49
49
|
this.pool = {}
|
|
50
50
|
this.poolData = {}
|
|
@@ -52,7 +52,7 @@ export default class ApiMakerCommandsPool {
|
|
|
52
52
|
this.globalRequestData = {}
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
addCommand(data) {
|
|
55
|
+
addCommand (data) {
|
|
56
56
|
return new Promise((resolve, reject) => {
|
|
57
57
|
const id = this.currentId
|
|
58
58
|
this.currentId += 1
|
|
@@ -87,11 +87,11 @@ export default class ApiMakerCommandsPool {
|
|
|
87
87
|
})
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
commandsCount() {
|
|
90
|
+
commandsCount () {
|
|
91
91
|
return Object.keys(this.pool)
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
async sendRequest({commandSubmitData, url}) {
|
|
94
|
+
async sendRequest ({commandSubmitData, url}) {
|
|
95
95
|
let response
|
|
96
96
|
|
|
97
97
|
for (let i = 0; i < 3; i++) {
|
|
@@ -113,7 +113,7 @@ export default class ApiMakerCommandsPool {
|
|
|
113
113
|
throw new Error("Couldnt successfully execute request")
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
-
async flush() {
|
|
116
|
+
async flush () {
|
|
117
117
|
if (this.commandsCount() == 0) {
|
|
118
118
|
return
|
|
119
119
|
}
|
|
@@ -166,7 +166,7 @@ export default class ApiMakerCommandsPool {
|
|
|
166
166
|
}
|
|
167
167
|
}
|
|
168
168
|
|
|
169
|
-
handleFailedResponse(commandData, commandResponseData) {
|
|
169
|
+
handleFailedResponse (commandData, commandResponseData) {
|
|
170
170
|
let error
|
|
171
171
|
|
|
172
172
|
if (commandResponseData.error_type == "destroy_error") {
|
|
@@ -190,13 +190,13 @@ export default class ApiMakerCommandsPool {
|
|
|
190
190
|
commandData.reject(error)
|
|
191
191
|
}
|
|
192
192
|
|
|
193
|
-
clearTimeout() {
|
|
193
|
+
clearTimeout () {
|
|
194
194
|
if (this.flushTimeout) {
|
|
195
195
|
clearTimeout(this.flushTimeout)
|
|
196
196
|
}
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
-
isActive() {
|
|
199
|
+
isActive () {
|
|
200
200
|
if (this.commandsCount() > 0) {
|
|
201
201
|
return true
|
|
202
202
|
}
|
|
@@ -208,7 +208,7 @@ export default class ApiMakerCommandsPool {
|
|
|
208
208
|
return false
|
|
209
209
|
}
|
|
210
210
|
|
|
211
|
-
setFlushTimeout() {
|
|
211
|
+
setFlushTimeout () {
|
|
212
212
|
this.clearTimeout()
|
|
213
213
|
this.flushTimeout = setTimeout(() => this.flush(), 0)
|
|
214
214
|
}
|
package/src/devise.mjs
CHANGED
|
@@ -9,11 +9,11 @@ import Services from "./services.mjs"
|
|
|
9
9
|
const shared = {}
|
|
10
10
|
|
|
11
11
|
export default class ApiMakerDevise {
|
|
12
|
-
static callSignOutEvent(args) {
|
|
12
|
+
static callSignOutEvent (args) {
|
|
13
13
|
events.emit("onDeviseSignOut", {args})
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
static current() {
|
|
16
|
+
static current () {
|
|
17
17
|
if (!shared.currentApiMakerDevise) {
|
|
18
18
|
shared.currentApiMakerDevise = new ApiMakerDevise()
|
|
19
19
|
}
|
|
@@ -21,11 +21,11 @@ export default class ApiMakerDevise {
|
|
|
21
21
|
return shared.currentApiMakerDevise
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
static events() {
|
|
24
|
+
static events () {
|
|
25
25
|
return events
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
static addUserScope(scope) {
|
|
28
|
+
static addUserScope (scope) {
|
|
29
29
|
const currentMethodName = `current${inflection.camelize(scope)}`
|
|
30
30
|
|
|
31
31
|
ApiMakerDevise[currentMethodName] = () => ApiMakerDevise.current().getCurrentScope(scope)
|
|
@@ -35,7 +35,7 @@ export default class ApiMakerDevise {
|
|
|
35
35
|
ApiMakerDevise[isSignedInMethodName] = () => Boolean(ApiMakerDevise.current().getCurrentScope(scope))
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
static async signIn(username, password, args = {}) {
|
|
38
|
+
static async signIn (username, password, args = {}) {
|
|
39
39
|
if (!args.scope) args.scope = "user"
|
|
40
40
|
|
|
41
41
|
const postData = {username, password, args}
|
|
@@ -53,7 +53,7 @@ export default class ApiMakerDevise {
|
|
|
53
53
|
return {model, response}
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
static updateSession(model, args = {}) {
|
|
56
|
+
static updateSession (model, args = {}) {
|
|
57
57
|
if (!args.scope) {
|
|
58
58
|
args.scope = digg(model.modelClassData(), "name")
|
|
59
59
|
}
|
|
@@ -63,17 +63,11 @@ export default class ApiMakerDevise {
|
|
|
63
63
|
ApiMakerDevise.current().currents[camelizedScopeName] = model
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
const camelizedScopeName = inflection.camelize(scope, true)
|
|
68
|
-
|
|
69
|
-
return camelizedScopeName in ApiMakerDevise.current().currents
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
static setSignedOut(args) {
|
|
66
|
+
static setSignedOut (args) {
|
|
73
67
|
ApiMakerDevise.current().currents[inflection.camelize(args.scope, true)] = null
|
|
74
68
|
}
|
|
75
69
|
|
|
76
|
-
static async signOut(args = {}) {
|
|
70
|
+
static async signOut (args = {}) {
|
|
77
71
|
if (!args.scope) {
|
|
78
72
|
args.scope = "user"
|
|
79
73
|
}
|
|
@@ -93,11 +87,11 @@ export default class ApiMakerDevise {
|
|
|
93
87
|
return response
|
|
94
88
|
}
|
|
95
89
|
|
|
96
|
-
constructor() {
|
|
90
|
+
constructor () {
|
|
97
91
|
this.currents = {}
|
|
98
92
|
}
|
|
99
93
|
|
|
100
|
-
getCurrentScope(scope) {
|
|
94
|
+
getCurrentScope (scope) {
|
|
101
95
|
if (!(scope in this.currents)) {
|
|
102
96
|
this.currents[scope] = this.loadCurrentScope(scope)
|
|
103
97
|
}
|
|
@@ -105,7 +99,7 @@ export default class ApiMakerDevise {
|
|
|
105
99
|
return this.currents[scope]
|
|
106
100
|
}
|
|
107
101
|
|
|
108
|
-
|
|
102
|
+
hasCurrentScope(scope) {
|
|
109
103
|
if (globalThis.apiMakerDeviseCurrent && scope in globalThis.apiMakerDeviseCurrent) {
|
|
110
104
|
return true
|
|
111
105
|
}
|
|
@@ -113,8 +107,8 @@ export default class ApiMakerDevise {
|
|
|
113
107
|
return false
|
|
114
108
|
}
|
|
115
109
|
|
|
116
|
-
loadCurrentScope(scope) {
|
|
117
|
-
if (!this.
|
|
110
|
+
loadCurrentScope (scope) {
|
|
111
|
+
if (!this.hasCurrentScope(scope)) {
|
|
118
112
|
return null
|
|
119
113
|
}
|
|
120
114
|
|
package/src/logger.mjs
CHANGED
|
@@ -1,82 +1,38 @@
|
|
|
1
|
-
import config from "./config.mjs"
|
|
2
1
|
import Devise from "./devise.mjs"
|
|
3
2
|
import * as inflection from "inflection"
|
|
4
3
|
import Logger from "./logger.mjs"
|
|
5
4
|
import wakeEvent from "wake-event"
|
|
6
5
|
|
|
7
6
|
const logger = new Logger({name: "ApiMaker / SessionStatusUpdater"})
|
|
8
|
-
const shared = {}
|
|
9
|
-
|
|
10
|
-
// logger.setDebug(true)
|
|
11
7
|
|
|
12
8
|
export default class ApiMakerSessionStatusUpdater {
|
|
13
|
-
static current(
|
|
14
|
-
if (!
|
|
15
|
-
|
|
16
|
-
}
|
|
9
|
+
static current () {
|
|
10
|
+
if (!globalThis.apiMakerSessionStatusUpdater)
|
|
11
|
+
globalThis.apiMakerSessionStatusUpdater = new ApiMakerSessionStatusUpdater()
|
|
17
12
|
|
|
18
|
-
return
|
|
13
|
+
return globalThis.apiMakerSessionStatusUpdater
|
|
19
14
|
}
|
|
20
15
|
|
|
21
|
-
constructor(args = {}) {
|
|
16
|
+
constructor (args = {}) {
|
|
22
17
|
this.events = {}
|
|
23
18
|
this.timeout = args.timeout || 600000
|
|
24
|
-
this.useMetaElement = ("useMetaElement" in args) ? args.useMetaElement : true
|
|
25
19
|
|
|
26
20
|
this.connectOnlineEvent()
|
|
27
21
|
this.connectWakeEvent()
|
|
28
22
|
}
|
|
29
23
|
|
|
30
|
-
connectOnlineEvent() {
|
|
31
|
-
window.addEventListener("online", this.updateSessionStatus, false)
|
|
24
|
+
connectOnlineEvent () {
|
|
25
|
+
window.addEventListener("online", () => this.updateSessionStatus(), false)
|
|
32
26
|
}
|
|
33
27
|
|
|
34
|
-
connectWakeEvent() {
|
|
35
|
-
wakeEvent(this.updateSessionStatus)
|
|
28
|
+
connectWakeEvent () {
|
|
29
|
+
wakeEvent(() => this.updateSessionStatus())
|
|
36
30
|
}
|
|
37
31
|
|
|
38
|
-
async
|
|
39
|
-
if (this.csrfToken) {
|
|
40
|
-
logger.debug(`Get CSRF token from set variable: ${this.csrfToken}`)
|
|
41
|
-
|
|
42
|
-
return this.csrfToken
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if (this.useMetaElement) {
|
|
46
|
-
const csrfTokenElement = document.querySelector("meta[name='csrf-token']")
|
|
47
|
-
|
|
48
|
-
if (csrfTokenElement) {
|
|
49
|
-
logger.debug(() => `Get CSRF token from meta element: ${csrfTokenElement.getAttribute("content")}`)
|
|
50
|
-
|
|
51
|
-
this.csrfToken = csrfTokenElement.getAttribute("content")
|
|
52
|
-
|
|
53
|
-
return this.csrfToken
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
logger.debug("Updating session status because no CSRF token set yet")
|
|
58
|
-
await this.updateSessionStatus()
|
|
59
|
-
|
|
60
|
-
if (this.csrfToken) {
|
|
61
|
-
logger.debug(() => `Returning CSRF token after updating session status: ${this.csrfToken}`)
|
|
62
|
-
|
|
63
|
-
return this.csrfToken
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
throw new Error("CSRF token hasn't been set")
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
sessionStatus() {
|
|
32
|
+
async sessionStatus () {
|
|
70
33
|
return new Promise((resolve) => {
|
|
71
|
-
const host = config.getHost()
|
|
72
|
-
let requestPath = ""
|
|
73
|
-
|
|
74
|
-
if (host) requestPath += host
|
|
75
|
-
|
|
76
|
-
requestPath += "/api_maker/session_statuses"
|
|
77
|
-
|
|
78
34
|
const xhr = new XMLHttpRequest()
|
|
79
|
-
xhr.open("POST",
|
|
35
|
+
xhr.open("POST", "/api_maker/session_statuses", true)
|
|
80
36
|
xhr.onload = () => {
|
|
81
37
|
const response = JSON.parse(xhr.responseText)
|
|
82
38
|
resolve(response)
|
|
@@ -85,11 +41,11 @@ export default class ApiMakerSessionStatusUpdater {
|
|
|
85
41
|
})
|
|
86
42
|
}
|
|
87
43
|
|
|
88
|
-
onSignedOut(callback) {
|
|
44
|
+
onSignedOut (callback) {
|
|
89
45
|
this.addEvent("onSignedOut", callback)
|
|
90
46
|
}
|
|
91
47
|
|
|
92
|
-
startTimeout() {
|
|
48
|
+
startTimeout () {
|
|
93
49
|
logger.debug("startTimeout")
|
|
94
50
|
|
|
95
51
|
if (this.updateTimeout)
|
|
@@ -104,12 +60,12 @@ export default class ApiMakerSessionStatusUpdater {
|
|
|
104
60
|
)
|
|
105
61
|
}
|
|
106
62
|
|
|
107
|
-
stopTimeout() {
|
|
63
|
+
stopTimeout () {
|
|
108
64
|
if (this.updateTimeout)
|
|
109
65
|
clearTimeout(this.updateTimeout)
|
|
110
66
|
}
|
|
111
67
|
|
|
112
|
-
updateSessionStatus
|
|
68
|
+
async updateSessionStatus () {
|
|
113
69
|
logger.debug("updateSessionStatus")
|
|
114
70
|
|
|
115
71
|
const result = await this.sessionStatus()
|
|
@@ -119,30 +75,25 @@ export default class ApiMakerSessionStatusUpdater {
|
|
|
119
75
|
this.updateUserSessionsFromResult(result)
|
|
120
76
|
}
|
|
121
77
|
|
|
122
|
-
updateMetaElementsFromResult(result) {
|
|
78
|
+
updateMetaElementsFromResult (result) {
|
|
123
79
|
logger.debug("updateMetaElementsFromResult")
|
|
80
|
+
const csrfTokenElement = document.querySelector("meta[name='csrf-token']")
|
|
124
81
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
if (csrfTokenElement) {
|
|
131
|
-
logger.debug(() => `Changing token from "${csrfTokenElement.getAttribute("content")}" to "${result.csrf_token}"`)
|
|
132
|
-
csrfTokenElement.setAttribute("content", result.csrf_token)
|
|
133
|
-
} else {
|
|
134
|
-
logger.debug("csrf token element couldn't be found")
|
|
135
|
-
}
|
|
82
|
+
if (csrfTokenElement) {
|
|
83
|
+
logger.debug(() => `Changing token from "${csrfTokenElement.getAttribute("content")}" to "${result.csrf_token}"`)
|
|
84
|
+
csrfTokenElement.setAttribute("content", result.csrf_token)
|
|
85
|
+
} else {
|
|
86
|
+
logger.debug("csrf token element couldn't be found")
|
|
136
87
|
}
|
|
137
88
|
}
|
|
138
89
|
|
|
139
|
-
updateUserSessionsFromResult(result) {
|
|
90
|
+
updateUserSessionsFromResult (result) {
|
|
140
91
|
for (const scopeName in result.scopes) {
|
|
141
92
|
this.updateUserSessionScopeFromResult(scopeName, result.scopes[scopeName])
|
|
142
93
|
}
|
|
143
94
|
}
|
|
144
95
|
|
|
145
|
-
updateUserSessionScopeFromResult(scopeName, scope) {
|
|
96
|
+
updateUserSessionScopeFromResult (scopeName, scope) {
|
|
146
97
|
const deviseIsSignedInMethodName = `is${inflection.camelize(scopeName)}SignedIn`
|
|
147
98
|
|
|
148
99
|
if (!(deviseIsSignedInMethodName in Devise)) {
|
|
@@ -3,39 +3,43 @@ import {digg} from "diggerize"
|
|
|
3
3
|
import * as inflection from "inflection"
|
|
4
4
|
import Params from "../params"
|
|
5
5
|
import PropTypes from "prop-types"
|
|
6
|
-
import {memo, useCallback} from "react"
|
|
6
|
+
import {memo, useCallback, useMemo} from "react"
|
|
7
7
|
import Table from "../table/table"
|
|
8
8
|
import useCurrentUser from "../use-current-user"
|
|
9
|
+
import useShape from "set-state-compare/src/use-shape.js"
|
|
9
10
|
|
|
10
|
-
const ApiMakerSuperAdminModelClassTable = (
|
|
11
|
+
const ApiMakerSuperAdminModelClassTable = (props) => {
|
|
12
|
+
const s = useShape(props)
|
|
13
|
+
const {modelClass, ...restProps} = props
|
|
11
14
|
const currentUser = useCurrentUser()
|
|
12
|
-
|
|
13
|
-
const columns =
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
return configReader.tableColumns()
|
|
17
|
-
}, [modelClass])
|
|
15
|
+
const configReader = useMemo(() => ConfigReader.forModel(modelClass), [modelClass])
|
|
16
|
+
const columns = useMemo(() => configReader.tableColumns(), [modelClass])
|
|
17
|
+
const tableConfig = configReader.modelConfig?.table
|
|
18
18
|
|
|
19
19
|
const editModelPath = useCallback((args) => {
|
|
20
|
-
const argName = inflection.camelize(digg(modelClass.modelClassData(), "name"), true)
|
|
20
|
+
const argName = inflection.camelize(digg(s.p.modelClass.modelClassData(), "name"), true)
|
|
21
21
|
const model = digg(args, argName)
|
|
22
22
|
|
|
23
23
|
return Params.withParams({
|
|
24
|
-
model: modelClass.modelClassData().name,
|
|
24
|
+
model: s.p.modelClass.modelClassData().name,
|
|
25
25
|
model_id: model.primaryKey(),
|
|
26
26
|
mode: "edit"
|
|
27
27
|
})
|
|
28
|
-
})
|
|
28
|
+
}, [])
|
|
29
29
|
|
|
30
30
|
const viewModelPath = useCallback((args) => {
|
|
31
|
-
const argName = inflection.camelize(digg(modelClass.modelClassData(), "name"), true)
|
|
31
|
+
const argName = inflection.camelize(digg(s.p.modelClass.modelClassData(), "name"), true)
|
|
32
32
|
const model = digg(args, argName)
|
|
33
33
|
|
|
34
34
|
return Params.withParams({
|
|
35
|
-
model: modelClass.modelClassData().name,
|
|
35
|
+
model: s.p.modelClass.modelClassData().name,
|
|
36
36
|
model_id: model.primaryKey()
|
|
37
37
|
})
|
|
38
|
-
}, [
|
|
38
|
+
}, [])
|
|
39
|
+
|
|
40
|
+
const tableProps = {}
|
|
41
|
+
|
|
42
|
+
if (tableConfig?.query) tableProps.collection = tableConfig.query
|
|
39
43
|
|
|
40
44
|
return (
|
|
41
45
|
<Table
|
|
@@ -44,6 +48,7 @@ const ApiMakerSuperAdminModelClassTable = ({modelClass, ...restProps}) => {
|
|
|
44
48
|
editModelPath={editModelPath}
|
|
45
49
|
modelClass={modelClass}
|
|
46
50
|
viewModelPath={viewModelPath}
|
|
51
|
+
{...tableProps}
|
|
47
52
|
{...restProps}
|
|
48
53
|
/>
|
|
49
54
|
)
|
package/src/use-current-user.mjs
CHANGED
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
import {useCallback, useEffect, useMemo} from "react"
|
|
2
2
|
import {camelize} from "inflection"
|
|
3
3
|
import Devise from "./devise.mjs"
|
|
4
|
-
import Logger from "./logger.mjs"
|
|
5
4
|
import Services from "./services.mjs"
|
|
6
5
|
import useEventEmitter from "./use-event-emitter.mjs"
|
|
7
6
|
import useShape from "set-state-compare/src/use-shape.js"
|
|
8
7
|
|
|
9
|
-
const logger = new Logger({name: "ApiMaker / useCurrentUser"})
|
|
10
|
-
|
|
11
|
-
// logger.setDebug(true)
|
|
12
|
-
|
|
13
8
|
const useCurrentUser = (args) => {
|
|
14
9
|
const s = useShape(args || {})
|
|
15
10
|
const scope = args?.scope || "user"
|
|
@@ -18,10 +13,20 @@ const useCurrentUser = (args) => {
|
|
|
18
13
|
s.meta.scope = scope
|
|
19
14
|
s.meta.scopeName = scopeName
|
|
20
15
|
|
|
16
|
+
const debugs = useCallback((debugCallback) => {
|
|
17
|
+
if (s.props.debug) {
|
|
18
|
+
let debugArgs = debugCallback()
|
|
19
|
+
|
|
20
|
+
if (!Array.isArray(debugArgs)) debugArgs = [debugArgs]
|
|
21
|
+
|
|
22
|
+
console.log("useCurrentUser", ...debugArgs)
|
|
23
|
+
}
|
|
24
|
+
})
|
|
25
|
+
|
|
21
26
|
const loadCurrentUserFromRequest = useCallback(async () => {
|
|
22
27
|
const {scope, scopeName} = s.m
|
|
23
28
|
|
|
24
|
-
|
|
29
|
+
debugs(() => `Loading ${scope} with request`)
|
|
25
30
|
|
|
26
31
|
const result = await Services.current().sendRequest("Devise::Current", {scope})
|
|
27
32
|
const current = digg(result, "current")
|
|
@@ -36,28 +41,21 @@ const useCurrentUser = (args) => {
|
|
|
36
41
|
|
|
37
42
|
const defaultCurrentUser = useCallback(() => {
|
|
38
43
|
const {scope, scopeName} = s.m
|
|
39
|
-
let current
|
|
40
44
|
|
|
41
|
-
if (Devise.current().hasCurrentScope(
|
|
42
|
-
current = Devise
|
|
45
|
+
if (Devise.current().hasCurrentScope(scope)) {
|
|
46
|
+
const current = Devise[scopeName]()
|
|
43
47
|
|
|
44
|
-
|
|
45
|
-
} else if (Devise.current().hasGlobalCurrentScope(scope)) {
|
|
46
|
-
current = Devise[scopeName]()
|
|
48
|
+
debugs(() => `Setting ${scope} from current scope: ${current?.id()}`)
|
|
47
49
|
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
+
if (s.props.onCurrentUserLoaded) setTimeout(() => s.props.onCurrentUserLoaded(current), 0)
|
|
50
51
|
|
|
51
|
-
|
|
52
|
-
setTimeout(() => s.props.onCurrentUserLoaded(current), 0)
|
|
52
|
+
return current
|
|
53
53
|
}
|
|
54
|
-
|
|
55
|
-
return current
|
|
56
54
|
}, [])
|
|
57
55
|
|
|
58
56
|
const useStatesArgument = {}
|
|
59
57
|
|
|
60
|
-
useStatesArgument[scopeName] =
|
|
58
|
+
useStatesArgument[scopeName] = defaultCurrentUser()
|
|
61
59
|
|
|
62
60
|
s.useStates(useStatesArgument)
|
|
63
61
|
|
|
@@ -70,8 +68,7 @@ const useCurrentUser = (args) => {
|
|
|
70
68
|
}, [])
|
|
71
69
|
|
|
72
70
|
useEffect(() => {
|
|
73
|
-
if (!Devise.current().
|
|
74
|
-
logger.debug(() => `Devise hasn't got current scope ${s.m.scope} so loading from request`)
|
|
71
|
+
if (!Devise.current().hasCurrentScope(s.m.scope)) {
|
|
75
72
|
loadCurrentUserFromRequest()
|
|
76
73
|
}
|
|
77
74
|
}, [])
|