@kaspernj/api-maker 1.0.221 → 1.0.224

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
@@ -16,7 +16,7 @@
16
16
  ]
17
17
  },
18
18
  "name": "@kaspernj/api-maker",
19
- "version": "1.0.221",
19
+ "version": "1.0.224",
20
20
  "type": "module",
21
21
  "description": "",
22
22
  "main": "index.js",
@@ -94,6 +94,10 @@ class BaseModel {
94
94
  return new ModelName({modelClassData: this.modelClassData()})
95
95
  }
96
96
 
97
+ static primaryKey() {
98
+ return digg(this.modelClassData(), "primaryKey")
99
+ }
100
+
97
101
  static ransack (query = {}) {
98
102
  return new Collection({modelClass: this}, {ransack: query})
99
103
  }
@@ -71,10 +71,9 @@ export default class ApiMakerBootstrapAttributeRow extends React.PureComponent {
71
71
  if (value instanceof Date) {
72
72
  return strftime("%Y-%m-%d %H:%M", value)
73
73
  } else if (typeof value === "boolean") {
74
- if (value)
75
- return I18n.t("js.shared.yes")
74
+ if (value) return I18n.t("js.shared.yes", {defaultValue: "Yes"})
76
75
 
77
- return I18n.t("js.shared.no")
76
+ return I18n.t("js.shared.no", {defaultValue: "No"})
78
77
  } else if (MoneyFormatter.isMoney(value)) {
79
78
  return MoneyFormatter.format(value)
80
79
  } else {
@@ -1,17 +1,19 @@
1
+ import {digg, digs} from "diggerize"
1
2
  import EventUpdated from "./event-updated"
2
3
  import Params from "./params.mjs"
3
4
  import PropTypes from "prop-types"
4
5
  import React from "react"
5
6
  import withQueryParams from "on-location-changed/src/with-query-params"
6
7
 
7
- export default (WrappedComponent, ModelClass, args = {}) => {
8
+ export default (WrappedComponent, mdelClassArg, args = {}) => {
8
9
  class ModelLoadWrapper extends React.PureComponent {
9
10
  static propTypes = {
10
11
  queryParams: PropTypes.object
11
12
  }
12
13
 
13
- camelizedLower = ModelClass.modelName().camelizedLower()
14
- paramsVariableName = `${ModelClass.modelName().paramKey()}_id`
14
+ modelClass = this.resolveModelClass(mdelClassArg)
15
+ camelizedLower = this.modelClass.modelName().camelizedLower()
16
+ paramsVariableName = `${this.modelClass.modelName().paramKey()}_id`
15
17
 
16
18
  state = {
17
19
  model: undefined,
@@ -19,6 +21,14 @@ export default (WrappedComponent, ModelClass, args = {}) => {
19
21
  notFound: undefined
20
22
  }
21
23
 
24
+ resolveModelClass(modelClassArg) {
25
+ const {queryParams} = digs(this.props, "queryParams")
26
+
27
+ if (typeof modelClassArg == "object") return modelClassArg.callback({queryParams})
28
+
29
+ return modelClassArg
30
+ }
31
+
22
32
  componentDidMount() {
23
33
  this.loadModel()
24
34
  }
@@ -50,6 +60,7 @@ export default (WrappedComponent, ModelClass, args = {}) => {
50
60
 
51
61
  loadExistingModel = async () => {
52
62
  const modelId = this.getModelId()
63
+ const ModelClass = digg(this, "modelClass")
53
64
  const query = await ModelClass.ransack({id_eq: modelId})
54
65
 
55
66
  if (args.abilities) query.abilities(args.abilities)
@@ -0,0 +1,73 @@
1
+ import {digg, digs} from "diggerize"
2
+ import inflection from "inflection"
3
+
4
+ export default class ApiMakerSuperAdminConfigReader {
5
+ static forModel(modelClass) {
6
+ const modelNameCamelized = digg(modelClass.modelClassData(), "nameDasherized")
7
+ let modelConfig
8
+
9
+ try {
10
+ modelConfig = require(`super-admin/model-configs/${modelNameCamelized}`).default
11
+ } catch (error) {
12
+ console.log(`No model-config for ${modelClass.modelClassData().name}`)
13
+ }
14
+
15
+ return new ApiMakerSuperAdminConfigReader(modelClass, modelConfig)
16
+ }
17
+
18
+ constructor(modelClass, modelConfig) {
19
+ this.modelClass = modelClass
20
+ this.modelConfig = modelConfig
21
+ }
22
+
23
+ attributesToShow() {
24
+ const {modelConfig} = digs(this, "modelConfig")
25
+
26
+ if (modelConfig?.show?.attributesToShow) {
27
+ return modelConfig.show.attributesToShow()
28
+ }
29
+
30
+ return this.defaultAttributesToShow()
31
+ }
32
+
33
+ defaultAttributesToShow() {
34
+ const attributesToShow = []
35
+
36
+ for (const column of this.defaultTableColumns()) {
37
+ attributesToShow.push(digg(column, "attribute"))
38
+ }
39
+
40
+ return attributesToShow
41
+ }
42
+
43
+ tableColumns() {
44
+ const {modelConfig} = digs(this, "modelConfig")
45
+
46
+ if (modelConfig?.table?.columns) {
47
+ return modelConfig.table.columns()
48
+ }
49
+
50
+ return this.defaultTableColumns()
51
+ }
52
+
53
+ defaultTableColumns() {
54
+ const {modelClass} = digs(this, "modelClass")
55
+ const attributes = modelClass.attributes()
56
+ const columns = []
57
+
58
+ for (const attribute of attributes) {
59
+ if (!attribute.isSelectedByDefault()) continue
60
+
61
+ const camelizedName = inflection.camelize(attribute.name(), true)
62
+ const column = {
63
+ attribute: camelizedName
64
+ }
65
+
66
+ if (attribute.isColumn()) column.sortKey = camelizedName
67
+
68
+ columns.push(column)
69
+ }
70
+
71
+ return columns
72
+ }
73
+ }
@@ -1,5 +1,5 @@
1
+ import ConfigReader from "../config-reader"
1
2
  import {digg, digs} from "diggerize"
2
- import inflection from "inflection"
3
3
  import Params from "../../params"
4
4
  import PropTypes from "prop-types"
5
5
  import React from "react"
@@ -27,23 +27,9 @@ export default class ApiMakerSuperAdminIndexPage extends React.PureComponent {
27
27
 
28
28
  columns = () => {
29
29
  const {modelClass} = digs(this.props, "modelClass")
30
- const attributes = modelClass.attributes()
31
- const columns = []
30
+ const configReader = ConfigReader.forModel(modelClass)
32
31
 
33
- for (const attribute of attributes) {
34
- if (!attribute.isSelectedByDefault()) continue
35
-
36
- const camelizedName = inflection.camelize(attribute.name(), true)
37
- const column = {
38
- attribute: camelizedName
39
- }
40
-
41
- if (attribute.isColumn()) column.sortKey = camelizedName
42
-
43
- columns.push(column)
44
- }
45
-
46
- return columns
32
+ return configReader.tableColumns()
47
33
  }
48
34
 
49
35
  viewModelPath = (args) => {
@@ -20,7 +20,7 @@ class ApiMakerSuperAdmin extends React.PureComponent {
20
20
  if (queryParams.model) modelClass = modelsModule[queryParams.model]
21
21
 
22
22
  return (
23
- <Layout>
23
+ <Layout headerTitle={modelClass?.modelName()?.human({count: 2})}>
24
24
  {pageToShow == "index" &&
25
25
  <IndexPage
26
26
  currentUser={currentUser}
@@ -81,14 +81,14 @@ class ApiMakerSuperAdminLayout extends React.PureComponent {
81
81
  {currentUser &&
82
82
  <>
83
83
  <div className="mb-4">
84
- {I18n.t("js.api_maker.super_admin.layout.try_signing_out_and_in_with_a_different_user")}
84
+ {I18n.t("js.api_maker.super_admin.layout.try_signing_out_and_in_with_a_different_user", {defaultValue: "Try signing in with a different user."})}
85
85
  </div>
86
86
  </>
87
87
  }
88
88
  {!currentUser &&
89
89
  <>
90
90
  <div className="mb-4">
91
- {I18n.t("js.api_maker.super_admin.layout.try_signing_in")}
91
+ {I18n.t("js.api_maker.super_admin.layout.try_signing_in", {defaultValue: "Try signing in."})}
92
92
  </div>
93
93
  </>
94
94
  }
@@ -1,18 +1,10 @@
1
1
  import CanCanLoader from "@kaspernj/api-maker/src/can-can-loader"
2
2
  import {digg, digs} from "diggerize"
3
3
  import MenuItem from "./menu-item"
4
+ import models from "../../models"
4
5
  import Params from "../../../params"
5
6
  import PropTypes from "prop-types"
6
7
  import PropTypesExact from "prop-types-exact"
7
- import * as modelsModule from "@kaspernj/api-maker/src/models.mjs.erb"
8
-
9
- const models = []
10
-
11
- for (const modelKey of Object.keys(modelsModule)) {
12
- const model = modelsModule[modelKey]
13
-
14
- models.push(model)
15
- }
16
8
 
17
9
  const abilities = []
18
10
 
@@ -7,7 +7,7 @@ class ComponentsAdminLayoutNoAccess extends React.PureComponent {
7
7
  className="components--admin--layout-no-access"
8
8
  data-user-roles={currentUser?.userRoles()?.loaded()?.map((userRole) => userRole.role()?.identifier()).join(", ")}
9
9
  >
10
- {I18n.t("js.api_maker.super_admin.layout.no_access.you_dont_have_no_access_to_this_page")}
10
+ {I18n.t("js.api_maker.super_admin.layout.no_access.you_dont_have_no_access_to_this_page", {defaultValue: "You don't have access to this page."})}
11
11
  </div>
12
12
  )
13
13
  }
@@ -0,0 +1,11 @@
1
+ import * as modelsModule from "@kaspernj/api-maker/src/models.mjs.erb"
2
+
3
+ const models = []
4
+
5
+ for (const modelKey of Object.keys(modelsModule)) {
6
+ const model = modelsModule[modelKey]
7
+
8
+ models.push(model)
9
+ }
10
+
11
+ export default models
@@ -1,11 +1,49 @@
1
+ import AttributeRows from "../bootstrap/attribute-rows"
2
+ import ConfigReader from "./config-reader"
3
+ import {digg, digs} from "diggerize"
4
+ import modelLoadWrapper from "../model-load-wrapper"
1
5
  import React from "react"
2
6
 
3
- export default class ApiMakerSuperAdminShowPage extends React.PureComponent {
7
+ class ApiMakerSuperAdminShowPage extends React.PureComponent {
4
8
  render() {
9
+ const attributes = this.attributes()
10
+ const model = this.model()
11
+
5
12
  return (
6
13
  <div className="super-admin--show-page">
7
- show page
14
+ {attributes && model &&
15
+ <AttributeRows attributes={attributes} model={model} />
16
+ }
8
17
  </div>
9
18
  )
10
19
  }
20
+
21
+ attributes() {
22
+ const {modelClass} = digs(this.props, "modelClass")
23
+ const configReader = ConfigReader.forModel(modelClass)
24
+
25
+ return configReader.attributesToShow()
26
+ }
27
+
28
+ model() {
29
+ const {modelClass} = digs(this.props, "modelClass")
30
+ const camelizedLower = digg(modelClass.modelClassData(), "camelizedLower")
31
+
32
+ return digg(this, "props", camelizedLower)
33
+ }
11
34
  }
35
+
36
+ const modelClassResolver = {callback: ({queryParams}) => {
37
+ const modelClassName = digg(queryParams, "model")
38
+ const modelClass = digg(require("../models.mjs.erb"), modelClassName)
39
+
40
+ return modelClass
41
+ }}
42
+
43
+ export default modelLoadWrapper(
44
+ ApiMakerSuperAdminShowPage,
45
+ modelClassResolver,
46
+ {
47
+ loadByQueryParam: ({props}) => props.queryParams.model_id
48
+ }
49
+ )
@@ -12,6 +12,16 @@ class SelectCalculator {
12
12
  const select = this.table.props.select || {}
13
13
  const {preparedColumns} = digs(this.table.shape, "preparedColumns")
14
14
 
15
+
16
+ // Ensure the primary key column is loader for the primary model class
17
+ const className = digg(modelClass.modelClassData(), "className")
18
+ const primaryKeyColumnName = modelClass.primaryKey()
19
+
20
+ if (!(className in select)) select[className] = []
21
+ if (!select[className].includes(primaryKeyColumnName)) select[className].push(primaryKeyColumnName)
22
+
23
+
24
+ // Ensure columns used for columns are loaded
15
25
  for (const preparedColumn of preparedColumns) {
16
26
  const {column} = digs(preparedColumn, "column")
17
27