@kaspernj/api-maker 1.0.304 → 1.0.305

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.
@@ -1,77 +1,17 @@
1
1
  import "./style"
2
- import {digg, digs} from "diggerize"
2
+ import {memo, useCallback, useRef} from "react"
3
3
  import Link from "../../../link"
4
4
  import MenuContent from "./menu-content"
5
5
  import MenuItem from "./menu-item"
6
- import React from "react"
7
6
  import PropTypes from "prop-types"
8
7
  import PropTypesExact from "prop-types-exact"
9
- import withCurrentUser from "../../../with-current-user"
8
+ import useCurrentUser from "../../../use-current-user"
10
9
 
11
- class ComponentsAdminLayoutMenu extends React.PureComponent {
12
- static propTypes = PropTypesExact({
13
- active: PropTypes.string,
14
- currentUser: PropTypes.instanceOf(User),
15
- noAccess: PropTypes.bool.isRequired,
16
- onRequestMenuClose: PropTypes.func.isRequired,
17
- triggered: PropTypes.bool.isRequired
18
- })
10
+ const ComponentsAdminLayoutMenu = ({active, noAccess, triggered}) => {
11
+ const currentUser = useCurrentUser()
12
+ const rootRef = useRef()
19
13
 
20
- rootRef = React.createRef()
21
-
22
- render() {
23
- const {rootRef} = digs(this, "rootRef")
24
- const {active} = this.props
25
- const {
26
- currentUser,
27
- noAccess,
28
- triggered
29
- } = digs(
30
- this.props,
31
- "currentUser",
32
- "noAccess",
33
- "triggered"
34
- )
35
- return (
36
- <div className="components--admin--layout--menu" data-triggered={triggered} ref={rootRef}>
37
- <div className="menu-logo">
38
- <Link className="menu-logo-link" to={Params.withParams({})}>
39
- Admin
40
- </Link>
41
- </div>
42
- <div className="menu-items-center">
43
- {!noAccess &&
44
- <MenuContent active={active} />
45
- }
46
- </div>
47
- <div className="menu-items-bottom">
48
- {currentUser &&
49
- <div className="menu-user-section">
50
- <div className="menu-user-icon">
51
- <i className="fa fa-user" />
52
- </div>
53
- <div className="menu-user-name">
54
- <div className="menu-user-name-container">
55
- {currentUser.name()}
56
- </div>
57
- </div>
58
- </div>
59
- }
60
- {currentUser &&
61
- <MenuItem
62
- active
63
- className="sign-out-menu-item"
64
- icon="sign-out-alt"
65
- label={I18n.t("js.api_maker.super_admin.layout.menu.sign_out", {defaultValue: "Sign out"})}
66
- onClick={digg(this, "onSignOutClicked")}
67
- />
68
- }
69
- </div>
70
- </div>
71
- )
72
- }
73
-
74
- onSignOutClicked = async (e) => {
14
+ const onSignOutClicked = useCallback(async (e) => {
75
15
  e.preventDefault()
76
16
 
77
17
  try {
@@ -80,8 +20,53 @@ class ComponentsAdminLayoutMenu extends React.PureComponent {
80
20
  } catch (error) {
81
21
  FlashMessage.errorResponse(error)
82
22
  }
83
- }
23
+ }, [])
84
24
 
25
+ return (
26
+ <div className="components--admin--layout--menu" data-triggered={triggered} ref={rootRef}>
27
+ <div className="menu-logo">
28
+ <Link className="menu-logo-link" to={Params.withParams({})}>
29
+ Admin
30
+ </Link>
31
+ </div>
32
+ <div className="menu-items-center">
33
+ {!noAccess &&
34
+ <MenuContent active={active} />
35
+ }
36
+ </div>
37
+ <div className="menu-items-bottom">
38
+ {currentUser &&
39
+ <div className="menu-user-section">
40
+ <div className="menu-user-icon">
41
+ <i className="fa fa-user" />
42
+ </div>
43
+ <div className="menu-user-name">
44
+ <div className="menu-user-name-container">
45
+ {currentUser.name()}
46
+ </div>
47
+ </div>
48
+ </div>
49
+ }
50
+ {currentUser &&
51
+ <MenuItem
52
+ active
53
+ className="sign-out-menu-item"
54
+ icon="sign-out-alt"
55
+ label={I18n.t("js.api_maker.super_admin.layout.menu.sign_out", {defaultValue: "Sign out"})}
56
+ onClick={onSignOutClicked}
57
+ />
58
+ }
59
+ </div>
60
+ </div>
61
+ )
85
62
  }
86
63
 
87
- export default withCurrentUser(ComponentsAdminLayoutMenu)
64
+ ComponentsAdminLayoutMenu.propTypes = PropTypesExact({
65
+ active: PropTypes.string,
66
+ currentUser: PropTypes.instanceOf(User),
67
+ noAccess: PropTypes.bool.isRequired,
68
+ onRequestMenuClose: PropTypes.func.isRequired,
69
+ triggered: PropTypes.bool.isRequired
70
+ })
71
+
72
+ export default memo(ComponentsAdminLayoutMenu)
@@ -1,10 +1,12 @@
1
- import CanCanLoader from "@kaspernj/api-maker/src/can-can-loader"
2
- import {digg, digs} from "diggerize"
1
+ import CanCan from "../../../can-can"
2
+ import {digg} from "diggerize"
3
+ import {memo, useMemo} from "react"
3
4
  import MenuItem from "./menu-item"
4
5
  import models from "../../models"
5
6
  import Params from "../../../params"
6
7
  import PropTypes from "prop-types"
7
8
  import PropTypesExact from "prop-types-exact"
9
+ import withCanCan from "@kaspernj/api-maker/src/with-can-can"
8
10
 
9
11
  const abilities = []
10
12
 
@@ -14,37 +16,31 @@ for (const model of models) {
14
16
  )
15
17
  }
16
18
 
17
- export default class ComponentsAdminLayoutMenuContent extends React.PureComponent {
18
- static propTypes = PropTypesExact({
19
- active: PropTypes.string
20
- })
21
-
22
- state = {
23
- canCan: undefined
24
- }
19
+ const ComponentsAdminLayoutMenuContent = ({active, canCan}) => {
20
+ const sortedModels = useMemo(
21
+ () => models.sort((a, b) => a.modelName().human({count: 2}).toLowerCase().localeCompare(b.modelName().human({count: 2}).toLowerCase())),
22
+ []
23
+ )
25
24
 
26
- render() {
27
- const {active} = digs(this.props, "active")
28
- const {canCan} = digs(this.state, "canCan")
25
+ return (
26
+ <>
27
+ {sortedModels.map((model) => canCan?.can("index", model) &&
28
+ <MenuItem
29
+ active={active}
30
+ icon="sitemap"
31
+ identifier={digg(model.modelClassData(), "name")}
32
+ label={model.modelName().human({count: 2})}
33
+ key={model.modelClassData().name}
34
+ to={Params.withParams({model: model.modelClassData().name})}
35
+ />
36
+ )}
37
+ </>
38
+ )
39
+ }
29
40
 
30
- return (
31
- <>
32
- <CanCanLoader abilities={abilities} component={this} />
33
- {this.sortedModels().map((model) => canCan?.can("index", model) &&
34
- <MenuItem
35
- active={active}
36
- icon="sitemap"
37
- identifier={digg(model.modelClassData(), "name")}
38
- label={model.modelName().human({count: 2})}
39
- key={model.modelClassData().name}
40
- to={Params.withParams({model: model.modelClassData().name})}
41
- />
42
- )}
43
- </>
44
- )
45
- }
41
+ ComponentsAdminLayoutMenuContent.propTypes = PropTypesExact({
42
+ active: PropTypes.string,
43
+ canCan: PropTypes.instanceOf(CanCan)
44
+ })
46
45
 
47
- sortedModels() {
48
- return models.sort((a, b) => a.modelName().human({count: 2}).toLowerCase().localeCompare(b.modelName().human({count: 2}).toLowerCase()))
49
- }
50
- }
46
+ export default withCanCan(memo(ComponentsAdminLayoutMenuContent), abilities)
@@ -1,31 +1,29 @@
1
1
  import "./style"
2
2
  import classNames from "classnames"
3
3
  import Link from "../../../../link"
4
+ import {memo} from "react"
4
5
  import PropTypes from "prop-types"
5
- import React from "react"
6
6
 
7
- export default class ComponentsAdminLayoutMenuMenuItem extends React.PureComponent {
8
- static propTypes = {
9
- active: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),
10
- className: PropTypes.string,
11
- icon: PropTypes.string.isRequired,
12
- label: PropTypes.node
13
- }
14
-
15
- render() {
16
- const {active, children, className, icon, identifier, label, to, ...restProps} = this.props
7
+ const ComponentsAdminLayoutMenuMenuItem = ({active, children, className, icon, identifier, label, to, ...restProps}) => {
8
+ return (
9
+ <Link
10
+ className={classNames("components--admin--layout--menu--menu-item", className)}
11
+ data-active={active === true || active == identifier}
12
+ data-identifier={identifier}
13
+ to={to || "#"}
14
+ {...restProps}
15
+ >
16
+ <i className={`fa fa-fw fa-${icon} menu-item-icon`} />
17
+ {children || label}
18
+ </Link>
19
+ )
20
+ }
17
21
 
18
- return (
19
- <Link
20
- className={classNames("components--admin--layout--menu--menu-item", className)}
21
- data-active={active === true || active == identifier}
22
- data-identifier={identifier}
23
- to={to || "#"}
24
- {...restProps}
25
- >
26
- <i className={`fa fa-fw fa-${icon} menu-item-icon`} />
27
- {children || label}
28
- </Link>
29
- )
30
- }
22
+ ComponentsAdminLayoutMenuMenuItem.propTypes = {
23
+ active: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),
24
+ className: PropTypes.string,
25
+ icon: PropTypes.string.isRequired,
26
+ label: PropTypes.node
31
27
  }
28
+
29
+ export default memo(ComponentsAdminLayoutMenuMenuItem)
@@ -3,6 +3,8 @@
3
3
  .components--admin--layout--menu {
4
4
  position: fixed;
5
5
  z-index: 9;
6
+ overflow-y: auto;
7
+ overflow-x: hidden;
6
8
  top: 0;
7
9
  left: 0;
8
10
  display: flex;
@@ -1,16 +1,17 @@
1
- class ComponentsAdminLayoutNoAccess extends React.PureComponent {
2
- render() {
3
- const {currentUser} = digs(this.props, "currentUser")
1
+ import {memo} from "react"
2
+ import useCurrentUser from "../../use-current-user"
4
3
 
5
- return (
6
- <div
7
- className="components--admin--layout-no-access"
8
- data-user-roles={currentUser?.userRoles()?.loaded()?.map((userRole) => userRole.role()?.identifier()).join(", ")}
9
- >
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
- </div>
12
- )
13
- }
4
+ const ComponentsAdminLayoutNoAccess = () => {
5
+ const currentUser = useCurrentUser()
6
+
7
+ return (
8
+ <div
9
+ className="components--admin--layout-no-access"
10
+ data-user-roles={currentUser?.userRoles()?.loaded()?.map((userRole) => userRole.role()?.identifier()).join(", ")}
11
+ >
12
+ {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."})}
13
+ </div>
14
+ )
14
15
  }
15
16
 
16
- export default withCurrentUser(ComponentsAdminLayoutNoAccess)
17
+ export default memo(ComponentsAdminLayoutNoAccess)
@@ -1,46 +1,44 @@
1
1
  import ConfigReader from "./config-reader"
2
- import {digg, digs} from "diggerize"
2
+ 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 React from "react"
6
+ import {memo, useCallback} from "react"
7
7
  import Table from "../table/table"
8
+ import useCurrentUser from "../use-current-user"
8
9
 
9
- export default class ApiMakerSuperAdminModelClassTable extends React.PureComponent {
10
- static propTypes = {
11
- currentUser: PropTypes.object,
12
- modelClass: PropTypes.func.isRequired,
13
- queryParams: PropTypes.object.isRequired
14
- }
15
-
16
- render() {
17
- const {currentUser, modelClass, queryParams, ...restProps} = this.props
18
-
19
- return (
20
- <Table
21
- columns={digg(this, "columns")}
22
- currentUser={currentUser}
23
- modelClass={modelClass}
24
- viewModelPath={digg(this, "viewModelPath")}
25
- {...restProps}
26
- />
27
- )
28
- }
29
-
30
- columns = () => {
31
- const {modelClass} = digs(this.props, "modelClass")
10
+ const ApiMakerSuperAdminModelClassTable = ({modelClass, ...restProps}) => {
11
+ const currentUser = useCurrentUser()
12
+
13
+ const columns = useCallback(() => {
32
14
  const configReader = ConfigReader.forModel(modelClass)
33
15
 
34
16
  return configReader.tableColumns()
35
- }
17
+ }, [modelClass])
36
18
 
37
- viewModelPath = (args) => {
38
- const argName = inflection.camelize(digg(this.props.modelClass.modelClassData(), "name"), true)
19
+ const viewModelPath = useCallback((args) => {
20
+ const argName = inflection.camelize(digg(modelClass.modelClassData(), "name"), true)
39
21
  const model = digg(args, argName)
40
22
 
41
23
  return Params.withParams({
42
- model: this.props.modelClass.modelClassData().name,
24
+ model: modelClass.modelClassData().name,
43
25
  model_id: model.primaryKey()
44
26
  })
45
- }
27
+ }, [modelClass])
28
+
29
+ return (
30
+ <Table
31
+ columns={columns}
32
+ currentUser={currentUser}
33
+ modelClass={modelClass}
34
+ viewModelPath={viewModelPath}
35
+ {...restProps}
36
+ />
37
+ )
46
38
  }
39
+
40
+ ApiMakerSuperAdminModelClassTable.propTypes = {
41
+ modelClass: PropTypes.func.isRequired
42
+ }
43
+
44
+ export default memo(ApiMakerSuperAdminModelClassTable)
@@ -1,35 +1,35 @@
1
- import {digg, digs} from "diggerize"
1
+ import {digg} from "diggerize"
2
2
  import Link from "../link"
3
3
  import PropTypes from "prop-types"
4
4
  import PropTypesExact from "prop-types-exact"
5
5
  import React from "react"
6
+ import useQueryParams from "on-location-changed/src/use-query-params"
6
7
 
7
- export default class ApiMakerSuperAdminShowNav extends React.PureComponent {
8
- static propTypes = PropTypesExact({
9
- model: PropTypes.object.isRequired,
10
- modelClass: PropTypes.func.isRequired,
11
- queryParams: PropTypes.object.isRequired
12
- })
8
+ const ApiMakerSuperAdminShowNav = ({model, modelClass}) => {
9
+ const queryParams = useQueryParams()
10
+ const reflections = modelClass.reflections()
13
11
 
14
- render() {
15
- const {model, modelClass, queryParams} = digs(this.props, "model", "modelClass", "queryParams")
16
- const reflections = modelClass.reflections()
17
-
18
- return (
12
+ return (
13
+ <div>
19
14
  <div>
20
- <div>
21
- <Link to={Params.withParams({model: modelClass.modelClassData().name, model_id: queryParams.model_id})}>
22
- {I18n.t("js.api_maker.suprt_admin.show_reflection_page.general", {defaultValue: "General"})}
15
+ <Link to={Params.withParams({model: modelClass.modelClassData().name, model_id: queryParams.model_id})}>
16
+ {I18n.t("js.api_maker.suprt_admin.show_reflection_page.general", {defaultValue: "General"})}
17
+ </Link>
18
+ </div>
19
+ {model && reflections.filter((reflection) => reflection.macro() == "has_many").map((reflection) =>
20
+ <div key={reflection.name()}>
21
+ <Link to={Params.withParams({model: digg(modelClass.modelClassData(), "name"), model_id: model.primaryKey(), model_reflection: reflection.name()})}>
22
+ {modelClass.humanAttributeName(reflection.name())}
23
23
  </Link>
24
24
  </div>
25
- {model && reflections.filter((reflection) => reflection.macro() == "has_many").map((reflection) =>
26
- <div key={reflection.name()}>
27
- <Link to={Params.withParams({model: digg(modelClass.modelClassData(), "name"), model_id: model.primaryKey(), model_reflection: reflection.name()})}>
28
- {modelClass.humanAttributeName(reflection.name())}
29
- </Link>
30
- </div>
31
- )}
32
- </div>
33
- )
34
- }
25
+ )}
26
+ </div>
27
+ )
35
28
  }
29
+
30
+ ApiMakerSuperAdminShowNav.propTypes = PropTypesExact({
31
+ model: PropTypes.object.isRequired,
32
+ modelClass: PropTypes.func.isRequired
33
+ })
34
+
35
+ export default React.memo(ApiMakerSuperAdminShowNav)
@@ -1,25 +1,23 @@
1
1
  import AttributeRow from "../../bootstrap/attribute-row"
2
- import {digs} from "diggerize"
3
2
  import * as inflection from "inflection"
4
3
  import Link from "../../link"
5
4
  import Params from "../../params"
6
- import React from "react"
5
+ import {memo} from "react"
7
6
 
8
- export default class ApiMakerSuperAdminShowPageBelongsToAttributeRow extends React.PureComponent {
9
- render() {
10
- const {model, modelClass, reflection} = digs(this.props, "model", "modelClass", "reflection")
11
- const reflectionMethodName = inflection.camelize(reflection.name(), true)
12
- const subModel = model[reflectionMethodName]()
7
+ const ApiMakerSuperAdminShowPageBelongsToAttributeRow = ({model, modelClass, reflection}) => {
8
+ const reflectionMethodName = inflection.camelize(reflection.name(), true)
9
+ const subModel = model[reflectionMethodName]()
13
10
 
14
- return (
15
- <AttributeRow label={modelClass.humanAttributeName(inflection.camelize(reflection.name(), true))}>
16
- {subModel &&
17
- <Link to={Params.withParams({model: subModel.modelClassData().name, model_id: subModel.primaryKey()})}>
18
- {subModel && "name" in subModel && subModel.name()}
19
- {subModel && !("name" in subModel) && subModel?.id()}
20
- </Link>
21
- }
22
- </AttributeRow>
23
- )
24
- }
11
+ return (
12
+ <AttributeRow label={modelClass.humanAttributeName(inflection.camelize(reflection.name(), true))}>
13
+ {subModel &&
14
+ <Link to={Params.withParams({model: subModel.modelClassData().name, model_id: subModel.primaryKey()})}>
15
+ {subModel && "name" in subModel && subModel.name()}
16
+ {subModel && !("name" in subModel) && subModel?.id()}
17
+ </Link>
18
+ }
19
+ </AttributeRow>
20
+ )
25
21
  }
22
+
23
+ export default memo(ApiMakerSuperAdminShowPageBelongsToAttributeRow)
@@ -1,54 +1,41 @@
1
1
  import AttributeRows from "../../bootstrap/attribute-rows"
2
2
  import BelongsToAttributeRow from "./belongs-to-attribute-row"
3
3
  import ConfigReader from "../config-reader"
4
- import {digg, digs} from "diggerize"
4
+ import {digg} from "diggerize"
5
5
  import * as inflection from "inflection"
6
6
  import PropTypes from "prop-types"
7
- import React from "react"
7
+ import {memo} from "react"
8
8
  import ShowNav from "../show-nav"
9
9
  import withModel from "../../with-model"
10
10
 
11
- class ApiMakerSuperAdminShowPage extends React.PureComponent {
12
- static propTypes = {
13
- modelClass: PropTypes.func.isRequired,
14
- queryParams: PropTypes.object.isRequired
15
- }
16
-
17
- configReader = ConfigReader.forModel(digg(this, "props", "modelClass"))
18
-
19
- render() {
20
- const {modelClass, queryParams} = digs(this.props, "modelClass", "queryParams")
21
- const attributes = this.attributes()
22
- const model = this.model()
23
- const extraContent = this.configReader.modelConfig?.show?.extraContent
24
- const modelArgs = {}
25
-
26
- modelArgs[inflection.camelize(modelClass.modelClassData().name, true)] = model
27
-
28
- return (
29
- <div className="super-admin--show-page">
30
- {model &&
31
- <ShowNav model={model} modelClass={modelClass} queryParams={queryParams} />
32
- }
33
- {attributes && model &&
34
- <AttributeRows attributes={attributes} model={model} />
35
- }
36
- {model && modelClass.reflections().filter((reflection) => reflection.macro() == "belongs_to").map((reflection) =>
37
- <BelongsToAttributeRow key={reflection.name()} model={model} modelClass={modelClass} reflection={reflection} />
38
- )}
39
- {model && extraContent && extraContent(modelArgs)}
40
- </div>
41
- )
42
- }
43
-
44
- attributes = () => this.configReader.attributesToShow()
45
-
46
- model() {
47
- const {modelClass} = digs(this.props, "modelClass")
48
- const camelizedLower = digg(modelClass.modelClassData(), "camelizedLower")
11
+ const ApiMakerSuperAdminShowPage = ({modelClass, ...restProps}) => {
12
+ const configReader = ConfigReader.forModel(modelClass)
13
+ const attributes = configReader.attributesToShow()
14
+ const camelizedLower = digg(modelClass.modelClassData(), "camelizedLower")
15
+ const model = digg(restProps, camelizedLower)
16
+ const extraContent = configReader.modelConfig?.show?.extraContent
17
+ const modelArgs = {}
18
+
19
+ modelArgs[inflection.camelize(modelClass.modelClassData().name, true)] = model
20
+
21
+ return (
22
+ <div className="super-admin--show-page">
23
+ {model &&
24
+ <ShowNav model={model} modelClass={modelClass} />
25
+ }
26
+ {attributes && model &&
27
+ <AttributeRows attributes={attributes} model={model} />
28
+ }
29
+ {model && modelClass.reflections().filter((reflection) => reflection.macro() == "belongs_to").map((reflection) =>
30
+ <BelongsToAttributeRow key={reflection.name()} model={model} modelClass={modelClass} reflection={reflection} />
31
+ )}
32
+ {model && extraContent && extraContent(modelArgs)}
33
+ </div>
34
+ )
35
+ }
49
36
 
50
- return digg(this, "props", camelizedLower)
51
- }
37
+ ApiMakerSuperAdminShowPage.propTypes = {
38
+ modelClass: PropTypes.func.isRequired
52
39
  }
53
40
 
54
41
  const modelClassResolver = {callback: ({queryParams}) => {
@@ -59,7 +46,7 @@ const modelClassResolver = {callback: ({queryParams}) => {
59
46
  }}
60
47
 
61
48
  export default withModel(
62
- ApiMakerSuperAdminShowPage,
49
+ memo(ApiMakerSuperAdminShowPage),
63
50
  modelClassResolver,
64
51
  ({modelClass}) => {
65
52
  const preload = []