@kaspernj/api-maker 1.0.379 → 1.0.380
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/bootstrap/attribute-rows.jsx +7 -6
- package/src/bootstrap/card.jsx +10 -9
- package/src/bootstrap/live-table.jsx +3 -2
- package/src/bootstrap/paginate.jsx +83 -67
- package/src/bootstrap/sort-link.jsx +14 -16
- package/src/link.jsx +2 -2
- package/src/result.mjs +7 -23
- package/src/super-admin/show-reflection-link.jsx +2 -0
- package/src/table/header-column.jsx +107 -0
- package/src/table/model-row.jsx +14 -13
- package/src/table/style.scss +4 -0
- package/src/table/table.jsx +27 -46
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kaspernj/api-maker",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.380",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "",
|
|
6
6
|
"main": "index.js",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"js-money": ">= 0.6.3",
|
|
33
33
|
"numberable": ">= 1.0.0",
|
|
34
34
|
"object-to-formdata": ">= 4.1.0",
|
|
35
|
-
"on-location-changed": ">= 1.0.
|
|
35
|
+
"on-location-changed": ">= 1.0.13",
|
|
36
36
|
"qs": ">= 6.9.3",
|
|
37
37
|
"replaceall": ">= 0.1.6",
|
|
38
38
|
"set-state-compare": "^1.0.45",
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import AttributeRow from "./attribute-row"
|
|
2
|
-
import
|
|
2
|
+
import BaseComponent from "../base-component"
|
|
3
|
+
import {memo} from "react"
|
|
3
4
|
import PropTypes from "prop-types"
|
|
4
5
|
import propTypesExact from "prop-types-exact"
|
|
5
|
-
import
|
|
6
|
+
import {shapeComponent} from "set-state-compare/src/shape-component.js"
|
|
6
7
|
|
|
7
|
-
export default class ApiMakerBootstrapAttributeRows extends
|
|
8
|
+
export default memo(shapeComponent(class ApiMakerBootstrapAttributeRows extends BaseComponent {
|
|
8
9
|
static defaultProps = {
|
|
9
10
|
checkIfAttributeLoaded: false
|
|
10
11
|
}
|
|
@@ -15,13 +16,13 @@ export default class ApiMakerBootstrapAttributeRows extends React.PureComponent
|
|
|
15
16
|
model: PropTypes.object.isRequired
|
|
16
17
|
})
|
|
17
18
|
|
|
18
|
-
classObject = this.
|
|
19
|
+
classObject = this.p.model.modelClass()
|
|
19
20
|
|
|
20
21
|
render () {
|
|
21
|
-
const {attributes, checkIfAttributeLoaded, model} =
|
|
22
|
+
const {attributes, checkIfAttributeLoaded, model} = this.p
|
|
22
23
|
|
|
23
24
|
return attributes.map((attribute) =>
|
|
24
25
|
<AttributeRow attribute={attribute} checkIfAttributeLoaded={checkIfAttributeLoaded} key={`attribute-${attribute}`} model={model} />
|
|
25
26
|
)
|
|
26
27
|
}
|
|
27
|
-
}
|
|
28
|
+
}))
|
package/src/bootstrap/card.jsx
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import BaseComponent from "../base-component"
|
|
1
2
|
import classNames from "classnames"
|
|
2
3
|
import {digg, digs} from "diggerize"
|
|
3
4
|
import PropTypes from "prop-types"
|
|
4
|
-
import
|
|
5
|
+
import {memo, useRef} from "react"
|
|
6
|
+
import {shapeComponent} from "set-state-compare/src/shape-component.js"
|
|
5
7
|
|
|
6
|
-
export default class ApiMakerBootstrapCard extends
|
|
8
|
+
export default memo(shapeComponent(class ApiMakerBootstrapCard extends BaseComponent {
|
|
7
9
|
static defaultProps = {
|
|
8
10
|
defaultExpanded: true,
|
|
9
11
|
expandable: false,
|
|
@@ -27,13 +29,12 @@ export default class ApiMakerBootstrapCard extends React.PureComponent {
|
|
|
27
29
|
table: PropTypes.bool.isRequired
|
|
28
30
|
}
|
|
29
31
|
|
|
30
|
-
|
|
32
|
+
setup() {
|
|
33
|
+
this.cardRef = useRef()
|
|
31
34
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
expanded: props.defaultExpanded
|
|
36
|
-
}
|
|
35
|
+
this.useStates({
|
|
36
|
+
expanded: this.props.defaultExpanded
|
|
37
|
+
})
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
render () {
|
|
@@ -144,4 +145,4 @@ export default class ApiMakerBootstrapCard extends React.PureComponent {
|
|
|
144
145
|
|
|
145
146
|
return classNames.join(" ")
|
|
146
147
|
}
|
|
147
|
-
}
|
|
148
|
+
}))
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import BaseComponent from "../base-component"
|
|
1
2
|
import Card from "./card"
|
|
2
3
|
import classNames from "classnames"
|
|
3
4
|
import Collection from "../collection"
|
|
@@ -10,10 +11,10 @@ import Paginate from "./paginate"
|
|
|
10
11
|
import Params from "../params"
|
|
11
12
|
import PropTypes from "prop-types"
|
|
12
13
|
import {memo} from "react"
|
|
13
|
-
import {shapeComponent
|
|
14
|
+
import {shapeComponent} from "set-state-compare/src/shape-component.js"
|
|
14
15
|
import SortLink from "./sort-link"
|
|
15
16
|
|
|
16
|
-
export default memo(shapeComponent(class ApiMakerBootstrapLiveTable extends
|
|
17
|
+
export default memo(shapeComponent(class ApiMakerBootstrapLiveTable extends BaseComponent {
|
|
17
18
|
static defaultProps = {
|
|
18
19
|
card: true,
|
|
19
20
|
destroyEnabled: true,
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
+
import BaseComponent from "../base-component"
|
|
1
2
|
import instanceOfClassName from "../instance-of-class-name"
|
|
2
3
|
import Link from "../link"
|
|
3
4
|
import PropTypes from "prop-types"
|
|
4
5
|
import propTypesExact from "prop-types-exact"
|
|
5
6
|
import qs from "qs"
|
|
6
|
-
import {memo} from "react"
|
|
7
|
+
import {memo, useMemo} from "react"
|
|
7
8
|
import Result from "../result"
|
|
8
|
-
import {shapeComponent
|
|
9
|
+
import {shapeComponent} from "set-state-compare/src/shape-component.js"
|
|
9
10
|
import urlEncode from "../url-encode.mjs"
|
|
10
11
|
|
|
11
|
-
export default memo(shapeComponent(class ApiMakerBootstrapPaginate extends
|
|
12
|
+
export default memo(shapeComponent(class ApiMakerBootstrapPaginate extends BaseComponent {
|
|
12
13
|
static propTypes = propTypesExact({
|
|
13
14
|
result: PropTypes.oneOfType([
|
|
14
15
|
instanceOfClassName("ApiMakerResult"),
|
|
@@ -17,34 +18,28 @@ export default memo(shapeComponent(class ApiMakerBootstrapPaginate extends Shape
|
|
|
17
18
|
})
|
|
18
19
|
|
|
19
20
|
setup() {
|
|
20
|
-
this.
|
|
21
|
-
pages: () => this.pages()
|
|
22
|
-
})
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
componentDidUpdate (prevProps) {
|
|
26
|
-
if (prevProps.result != this.props.result) {
|
|
27
|
-
this.setState({pages: this.pages()})
|
|
28
|
-
}
|
|
29
|
-
}
|
|
21
|
+
const {result} = this.p
|
|
30
22
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
return "active"
|
|
23
|
+
this.totalPages = useMemo(() => Math.ceil(this.p.result.count() / this.p.result.perPage()), [result.currentPage(), result.totalCount(), result.totalPages()])
|
|
24
|
+
this.pages = useMemo(() => this.calculatePages(), [result.currentPage(), result.totalCount(), result.totalPages()])
|
|
34
25
|
}
|
|
35
26
|
|
|
36
|
-
|
|
37
|
-
const
|
|
27
|
+
calculatePages () {
|
|
28
|
+
const {result} = this.p
|
|
29
|
+
const {totalPages} = this.tt
|
|
30
|
+
const currentPage = result.currentPage()
|
|
38
31
|
const pages = []
|
|
39
|
-
|
|
32
|
+
|
|
40
33
|
let pagesFrom = currentPage - 5
|
|
41
34
|
let pagesTo = currentPage + 5
|
|
42
35
|
|
|
43
|
-
if (pagesFrom < 1)
|
|
36
|
+
if (pagesFrom < 1) {
|
|
44
37
|
pagesFrom = 1
|
|
38
|
+
}
|
|
45
39
|
|
|
46
|
-
if (pagesTo > totalPages)
|
|
40
|
+
if (pagesTo > totalPages) {
|
|
47
41
|
pagesTo = totalPages
|
|
42
|
+
}
|
|
48
43
|
|
|
49
44
|
for (let i = pagesFrom; i <= pagesTo; i++) {
|
|
50
45
|
pages.push(i)
|
|
@@ -53,8 +48,10 @@ export default memo(shapeComponent(class ApiMakerBootstrapPaginate extends Shape
|
|
|
53
48
|
return pages
|
|
54
49
|
}
|
|
55
50
|
|
|
51
|
+
isPageActiveClass = (pageNumber) => this.p.result.currentPage() == pageNumber ? "active" : "not-active"
|
|
52
|
+
|
|
56
53
|
pagePath (pageNumber) {
|
|
57
|
-
let pageKey = this.
|
|
54
|
+
let pageKey = this.p.result.data.collection.queryArgs.pageKey
|
|
58
55
|
|
|
59
56
|
if (!pageKey) {
|
|
60
57
|
pageKey = "page"
|
|
@@ -69,87 +66,106 @@ export default memo(shapeComponent(class ApiMakerBootstrapPaginate extends Shape
|
|
|
69
66
|
}
|
|
70
67
|
|
|
71
68
|
previousPagePath () {
|
|
69
|
+
const {result} = this.p
|
|
72
70
|
let previousPage
|
|
73
71
|
|
|
74
|
-
if (
|
|
75
|
-
previousPage =
|
|
72
|
+
if (result.currentPage() > 1) {
|
|
73
|
+
previousPage = result.currentPage() - 1
|
|
76
74
|
} else {
|
|
77
|
-
previousPage =
|
|
75
|
+
previousPage = result.currentPage()
|
|
78
76
|
}
|
|
79
77
|
|
|
80
78
|
return this.pagePath(previousPage)
|
|
81
79
|
}
|
|
82
80
|
|
|
83
81
|
nextPagePath () {
|
|
82
|
+
const {result} = this.p
|
|
84
83
|
let nextPage
|
|
85
84
|
|
|
86
|
-
if (
|
|
87
|
-
nextPage =
|
|
85
|
+
if (result.currentPage() < this.tt.totalPages) {
|
|
86
|
+
nextPage = result.currentPage() + 1
|
|
88
87
|
} else {
|
|
89
|
-
nextPage =
|
|
88
|
+
nextPage = result.currentPage()
|
|
90
89
|
}
|
|
91
90
|
|
|
92
91
|
return this.pagePath(nextPage)
|
|
93
92
|
}
|
|
94
93
|
|
|
95
|
-
showBackwardsDots ()
|
|
96
|
-
|
|
97
|
-
return (currentPage - 5 > 1)
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
showForwardsDots () {
|
|
101
|
-
const currentPage = this.props.result.currentPage()
|
|
102
|
-
const totalPages = this.props.result.totalPages()
|
|
103
|
-
return (currentPage + 5 < totalPages)
|
|
104
|
-
}
|
|
94
|
+
showBackwardsDots = () => (this.p.result.currentPage() - 5 > 1)
|
|
95
|
+
showForwardsDots = () => (this.p.result.currentPage() + 5 < this.tt.totalPages)
|
|
105
96
|
|
|
106
97
|
render () {
|
|
107
|
-
const {result} = this.
|
|
108
|
-
const {pages} = this.
|
|
98
|
+
const {result} = this.p
|
|
99
|
+
const {pages, totalPages} = this.tt
|
|
100
|
+
const showNextPage = result.currentPage() < totalPages
|
|
101
|
+
const showLastPage = result.currentPage() < totalPages
|
|
102
|
+
const showPreviousPage = result.currentPage() > 1
|
|
103
|
+
const showFirstPage = result.currentPage() > 1
|
|
109
104
|
|
|
110
105
|
return (
|
|
111
106
|
<>
|
|
112
107
|
<ul className="pagination" data-pages-length={pages.length}>
|
|
113
|
-
<li className={`page-item ${
|
|
114
|
-
|
|
115
|
-
⇤
|
|
116
|
-
|
|
108
|
+
<li className={`page-item ${!showPreviousPage ? "disabled" : ""}`} key="page-first">
|
|
109
|
+
{!showPreviousPage &&
|
|
110
|
+
"⇤"
|
|
111
|
+
}
|
|
112
|
+
{showPreviousPage &&
|
|
113
|
+
<Link className="page-link" to={this.pagePath(1)}>
|
|
114
|
+
⇤
|
|
115
|
+
</Link>
|
|
116
|
+
}
|
|
117
117
|
</li>
|
|
118
|
-
<li className={`page-item ${
|
|
119
|
-
|
|
120
|
-
←
|
|
121
|
-
|
|
118
|
+
<li className={`page-item ${!showFirstPage ? "disabled" : ""}`} key="page-previous">
|
|
119
|
+
{!showFirstPage &&
|
|
120
|
+
"←"
|
|
121
|
+
}
|
|
122
|
+
{showFirstPage &&
|
|
123
|
+
<Link className="page-link" to={this.previousPagePath()}>
|
|
124
|
+
←
|
|
125
|
+
</Link>
|
|
126
|
+
}
|
|
122
127
|
</li>
|
|
123
128
|
{this.showBackwardsDots() &&
|
|
124
|
-
<li className="page-item">
|
|
125
|
-
|
|
126
|
-
…
|
|
127
|
-
</a>
|
|
129
|
+
<li className="page-item disabled">
|
|
130
|
+
…
|
|
128
131
|
</li>
|
|
129
132
|
}
|
|
130
133
|
{pages.map((page) =>
|
|
131
134
|
<li className={`page-item ${this.isPageActiveClass(page)}`} key={`page-${page}`}>
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
+
{this.isPageActiveClass(page) == "active" &&
|
|
136
|
+
page
|
|
137
|
+
}
|
|
138
|
+
{this.isPageActiveClass(page) == "not-active" &&
|
|
139
|
+
<Link className="page-link" to={this.pagePath(page)}>
|
|
140
|
+
{page}
|
|
141
|
+
</Link>
|
|
142
|
+
}
|
|
135
143
|
</li>
|
|
136
144
|
)}
|
|
137
145
|
{this.showForwardsDots() &&
|
|
138
|
-
<li className="page-item">
|
|
139
|
-
|
|
140
|
-
…
|
|
141
|
-
</a>
|
|
146
|
+
<li className="page-item disabled">
|
|
147
|
+
…
|
|
142
148
|
</li>
|
|
143
149
|
}
|
|
144
|
-
<li className={`page-item ${
|
|
145
|
-
|
|
146
|
-
→
|
|
147
|
-
|
|
150
|
+
<li className={`page-item ${!showNextPage ? "disabled" : ""}`} key="page-next">
|
|
151
|
+
{!showNextPage &&
|
|
152
|
+
"→"
|
|
153
|
+
}
|
|
154
|
+
{showNextPage &&
|
|
155
|
+
<Link className="page-link" to={this.nextPagePath()}>
|
|
156
|
+
→
|
|
157
|
+
</Link>
|
|
158
|
+
}
|
|
148
159
|
</li>
|
|
149
|
-
<li className={`page-item ${
|
|
150
|
-
|
|
151
|
-
⇥
|
|
152
|
-
|
|
160
|
+
<li className={`page-item ${!showLastPage ? "disabled" : ""}`} key="page-last">
|
|
161
|
+
{!showLastPage &&
|
|
162
|
+
"⇥"
|
|
163
|
+
}
|
|
164
|
+
{showLastPage &&
|
|
165
|
+
<Link className="page-link" to={this.pagePath(totalPages)}>
|
|
166
|
+
⇥
|
|
167
|
+
</Link>
|
|
168
|
+
}
|
|
153
169
|
</li>
|
|
154
170
|
</ul>
|
|
155
171
|
</>
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
+
import BaseComponent from "../base-component"
|
|
1
2
|
import {digg, digs} from "diggerize"
|
|
2
3
|
import * as inflection from "inflection"
|
|
3
4
|
import PropTypes from "prop-types"
|
|
4
5
|
import qs from "qs"
|
|
5
|
-
import
|
|
6
|
+
import {memo, useMemo} from "react"
|
|
7
|
+
import {shapeComponent} from "set-state-compare/src/shape-component.js"
|
|
6
8
|
import urlEncode from "../url-encode.mjs"
|
|
7
9
|
|
|
8
10
|
import Link from "../link"
|
|
9
|
-
import
|
|
10
|
-
import withQueryParams from "on-location-changed/src/with-query-params"
|
|
11
|
+
import useQueryParams from "on-location-changed/src/use-query-params"
|
|
11
12
|
|
|
12
|
-
class ApiMakerBootstrapSortLink extends
|
|
13
|
+
export default memo(shapeComponent(class ApiMakerBootstrapSortLink extends BaseComponent {
|
|
13
14
|
static propTypes = {
|
|
14
15
|
attribute: PropTypes.string.isRequired,
|
|
15
16
|
className: PropTypes.string,
|
|
@@ -17,20 +18,19 @@ class ApiMakerBootstrapSortLink extends PureComponent {
|
|
|
17
18
|
linkComponent: PropTypes.object,
|
|
18
19
|
onChanged: PropTypes.func,
|
|
19
20
|
query: PropTypes.object.isRequired,
|
|
20
|
-
queryParams: PropTypes.object.isRequired,
|
|
21
21
|
title: PropTypes.node
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
return inflection.underscore(this.props.attribute)
|
|
24
|
+
setup() {
|
|
25
|
+
this.queryParams = useQueryParams()
|
|
26
|
+
this.searchKey = this.p.query.queryArgs.searchKey || "q"
|
|
28
27
|
}
|
|
29
28
|
|
|
29
|
+
attribute = () => inflection.underscore(this.p.attribute)
|
|
30
|
+
|
|
30
31
|
href () {
|
|
31
32
|
const qParams = this.qParams()
|
|
32
|
-
const {queryParams} =
|
|
33
|
-
const {searchKey} = digs(this, "searchKey")
|
|
33
|
+
const {queryParams, searchKey} = this.tt
|
|
34
34
|
|
|
35
35
|
qParams.s = `${this.attribute()} ${this.sortMode()}` // eslint-disable-line id-length
|
|
36
36
|
|
|
@@ -53,7 +53,7 @@ class ApiMakerBootstrapSortLink extends PureComponent {
|
|
|
53
53
|
|
|
54
54
|
render () {
|
|
55
55
|
const LinkComponent = this.linkComponent()
|
|
56
|
-
const {attribute, className, defaultParams, linkComponent, onChanged, query,
|
|
56
|
+
const {attribute, className, defaultParams, linkComponent, onChanged, query, title, ...restProps} = this.props
|
|
57
57
|
|
|
58
58
|
return (
|
|
59
59
|
<>
|
|
@@ -86,7 +86,7 @@ class ApiMakerBootstrapSortLink extends PureComponent {
|
|
|
86
86
|
|
|
87
87
|
qParams() {
|
|
88
88
|
const {defaultParams} = this.props
|
|
89
|
-
const {queryParams} =
|
|
89
|
+
const {queryParams} = this.tt
|
|
90
90
|
const {searchKey} = digs(this, "searchKey")
|
|
91
91
|
|
|
92
92
|
if (searchKey in queryParams) {
|
|
@@ -112,6 +112,4 @@ class ApiMakerBootstrapSortLink extends PureComponent {
|
|
|
112
112
|
|
|
113
113
|
return query.modelClass().humanAttributeName(attribute)
|
|
114
114
|
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
export default withQueryParams(ApiMakerBootstrapSortLink)
|
|
115
|
+
}))
|
package/src/link.jsx
CHANGED
package/src/result.mjs
CHANGED
|
@@ -3,27 +3,11 @@ export default class ApiMakerResult {
|
|
|
3
3
|
this.data = data
|
|
4
4
|
}
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
modelClass () {
|
|
15
|
-
return this.data.collection.modelClass()
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
perPage () {
|
|
19
|
-
return this.data.response.meta.perPage
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
totalCount () {
|
|
23
|
-
return this.data.response.meta.totalCount
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
totalPages () {
|
|
27
|
-
return this.data.response.meta.totalPages
|
|
28
|
-
}
|
|
6
|
+
count = () => this.data.response.meta.count
|
|
7
|
+
currentPage = () => this.data.response.meta.currentPage
|
|
8
|
+
models = () => this.data.models
|
|
9
|
+
modelClass = () => this.data.collection.modelClass()
|
|
10
|
+
perPage = () => this.data.response.meta.perPage
|
|
11
|
+
totalCount = () => this.data.response.meta.totalCount
|
|
12
|
+
totalPages = () => this.data.response.meta.totalPages
|
|
29
13
|
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import BaseComponent from "../base-component"
|
|
2
|
+
import classNames from "classnames"
|
|
3
|
+
import {digs} from "diggerize"
|
|
4
|
+
import {memo} from "react"
|
|
5
|
+
import {Pressable, Text, View} from "react-native"
|
|
6
|
+
import PropTypes from "prop-types"
|
|
7
|
+
import propTypesExact from "prop-types-exact"
|
|
8
|
+
import {shapeComponent} from "set-state-compare/src/shape-component"
|
|
9
|
+
import SortLink from "../bootstrap/sort-link"
|
|
10
|
+
import useEventListener from "../use-event-listener.mjs"
|
|
11
|
+
import {useRef} from "react"
|
|
12
|
+
|
|
13
|
+
export default memo(shapeComponent(class ApiMakerTableHeaderColumn extends BaseComponent {
|
|
14
|
+
static propTypes = propTypesExact({
|
|
15
|
+
column: PropTypes.object.isRequired,
|
|
16
|
+
table: PropTypes.object.isRequired,
|
|
17
|
+
tableSettingColumn: PropTypes.object.isRequired
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
setup() {
|
|
21
|
+
this.columnRef = useRef()
|
|
22
|
+
|
|
23
|
+
useEventListener(window, "mousemove", this.tt.onWindowMouseMove)
|
|
24
|
+
useEventListener(window, "mouseup", this.tt.onWindowMouseUp)
|
|
25
|
+
|
|
26
|
+
this.useStates({
|
|
27
|
+
cursorX: undefined,
|
|
28
|
+
originalWidth: undefined,
|
|
29
|
+
resizing: false,
|
|
30
|
+
width: this.p.tableSettingColumn.width()
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
render() {
|
|
35
|
+
const {column, table, tableSettingColumn} = this.p
|
|
36
|
+
const {width} = this.s
|
|
37
|
+
const {defaultParams} = table.props
|
|
38
|
+
const {query} = digs(table.collection, "query")
|
|
39
|
+
const ColumnInHeadComponent = table.columnInHeadComponent()
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<ColumnInHeadComponent
|
|
43
|
+
className={classNames(...table.headerClassNameForColumn(column))}
|
|
44
|
+
data-identifier={tableSettingColumn.identifier()}
|
|
45
|
+
ref={this.tt.columnRef}
|
|
46
|
+
style={{width}}
|
|
47
|
+
{...table.columnProps(column)}
|
|
48
|
+
>
|
|
49
|
+
<View style={{display: "flex", flexDirection: "row", alignItems: "center"}}>
|
|
50
|
+
{tableSettingColumn.hasSortKey() && query &&
|
|
51
|
+
<SortLink attribute={tableSettingColumn.sortKey()} defaultParams={defaultParams} query={query} title={table.headerLabelForColumn(column)} />
|
|
52
|
+
}
|
|
53
|
+
{(!tableSettingColumn.hasSortKey() || !query) &&
|
|
54
|
+
<Text>
|
|
55
|
+
{table.headerLabelForColumn(column)}
|
|
56
|
+
</Text>
|
|
57
|
+
}
|
|
58
|
+
<Pressable onPressIn={this.tt.onResizePressIn} style={{marginLeft: "auto", cursor: "col-resize"}}>
|
|
59
|
+
<Text>
|
|
60
|
+
|
|
|
61
|
+
</Text>
|
|
62
|
+
</Pressable>
|
|
63
|
+
</View>
|
|
64
|
+
</ColumnInHeadComponent>
|
|
65
|
+
)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
onResizeEnd = async () => {
|
|
69
|
+
this.setState({cursorX: undefined, resizing: false})
|
|
70
|
+
|
|
71
|
+
await this.p.tableSettingColumn.update({
|
|
72
|
+
width: this.s.width
|
|
73
|
+
})
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
onResizePressIn = (e) => {
|
|
77
|
+
e.preventDefault()
|
|
78
|
+
e.stopPropagation()
|
|
79
|
+
|
|
80
|
+
const originalWidth = this.s.width || this.tt.columnRef.current.offsetWidth
|
|
81
|
+
const cursorX = e.nativeEvent.pageX
|
|
82
|
+
|
|
83
|
+
this.setState({
|
|
84
|
+
cursorX,
|
|
85
|
+
originalWidth,
|
|
86
|
+
resizing: true
|
|
87
|
+
})
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
onWindowMouseMove = (e) => {
|
|
91
|
+
const {cursorX, resizing, originalWidth} = this.s
|
|
92
|
+
|
|
93
|
+
if (resizing) {
|
|
94
|
+
const newCursorX = e.pageX
|
|
95
|
+
const diffX = newCursorX - cursorX
|
|
96
|
+
const newWidth = originalWidth + diffX
|
|
97
|
+
|
|
98
|
+
this.setState({width: newWidth})
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
onWindowMouseUp = () => {
|
|
103
|
+
if (this.s.resizing) {
|
|
104
|
+
this.onResizeEnd()
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}))
|
package/src/table/model-row.jsx
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
|
+
import BaseComponent from "../base-component"
|
|
1
2
|
import classNames from "classnames"
|
|
2
3
|
import columnIdentifier from "./column-identifier.mjs"
|
|
3
4
|
import columnVisible from "./column-visible.mjs"
|
|
4
|
-
import {
|
|
5
|
+
import {digs} from "diggerize"
|
|
5
6
|
import * as inflection from "inflection"
|
|
6
7
|
import Link from "../link"
|
|
7
8
|
import MoneyFormatter from "../money-formatter"
|
|
8
9
|
import PropTypes from "prop-types"
|
|
9
10
|
import {memo} from "react"
|
|
10
|
-
import {shapeComponent
|
|
11
|
+
import {shapeComponent} from "set-state-compare/src/shape-component"
|
|
11
12
|
|
|
12
13
|
const WorkerPluginsCheckbox = React.lazy(() => import("./worker-plugins-checkbox"))
|
|
13
14
|
|
|
14
|
-
export default memo(shapeComponent(class ApiMakerBootStrapLiveTableModelRow extends
|
|
15
|
+
export default memo(shapeComponent(class ApiMakerBootStrapLiveTableModelRow extends BaseComponent {
|
|
15
16
|
static propTypes = {
|
|
16
17
|
cacheKey: PropTypes.string.isRequired,
|
|
17
18
|
model: PropTypes.object.isRequired,
|
|
@@ -21,10 +22,10 @@ export default memo(shapeComponent(class ApiMakerBootStrapLiveTableModelRow exte
|
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
render() {
|
|
24
|
-
const {model} =
|
|
25
|
-
const {modelClass, workplace} =
|
|
26
|
-
const {actionsContent, columnsContent, destroyEnabled, editModelPath, viewModelPath} =
|
|
27
|
-
const {columns, currentWorkplace} =
|
|
25
|
+
const {model} = this.p
|
|
26
|
+
const {modelClass, workplace} = this.p.liveTable.p
|
|
27
|
+
const {actionsContent, columnsContent, destroyEnabled, editModelPath, viewModelPath} = this.p.liveTable.props
|
|
28
|
+
const {columns, currentWorkplace} = this.p.liveTable.state
|
|
28
29
|
|
|
29
30
|
this.modelCallbackArgs = this._modelCallbackArgs() // 'model' can change so this needs to be re-cached for every render
|
|
30
31
|
|
|
@@ -39,7 +40,7 @@ export default memo(shapeComponent(class ApiMakerBootStrapLiveTableModelRow exte
|
|
|
39
40
|
return (
|
|
40
41
|
<RowComponent className={`live-table-row ${inflection.dasherize(modelClass.modelClassData().paramKey)}-row`} data-model-id={model.id()}>
|
|
41
42
|
{workplace &&
|
|
42
|
-
<ColumnComponent className="workplace-column">
|
|
43
|
+
<ColumnComponent className="workplace-column" style={{width: 25, textAlign: "center"}}>
|
|
43
44
|
<WorkerPluginsCheckbox currentWorkplace={currentWorkplace} model={model} />
|
|
44
45
|
</ColumnComponent>
|
|
45
46
|
}
|
|
@@ -77,7 +78,7 @@ export default memo(shapeComponent(class ApiMakerBootStrapLiveTableModelRow exte
|
|
|
77
78
|
}
|
|
78
79
|
|
|
79
80
|
columnsContentFromColumns (model) {
|
|
80
|
-
const {preparedColumns} =
|
|
81
|
+
const {preparedColumns} = this.p
|
|
81
82
|
const ColumnComponent = this.props.columnComponent
|
|
82
83
|
|
|
83
84
|
return preparedColumns?.map(({column, tableSettingColumn}) => columnVisible(column, tableSettingColumn) &&
|
|
@@ -98,7 +99,7 @@ export default memo(shapeComponent(class ApiMakerBootStrapLiveTableModelRow exte
|
|
|
98
99
|
)
|
|
99
100
|
}
|
|
100
101
|
|
|
101
|
-
columnContentFromContentArg (column,
|
|
102
|
+
columnContentFromContentArg (column, _model) {
|
|
102
103
|
const value = column.content(this.modelCallbackArgs)
|
|
103
104
|
|
|
104
105
|
return this.presentColumnValue(value)
|
|
@@ -135,7 +136,7 @@ export default memo(shapeComponent(class ApiMakerBootStrapLiveTableModelRow exte
|
|
|
135
136
|
}
|
|
136
137
|
|
|
137
138
|
_modelCallbackArgs () {
|
|
138
|
-
const {model} =
|
|
139
|
+
const {model} = this.p
|
|
139
140
|
const modelArgName = inflection.camelize(this.props.liveTable.props.modelClass.modelClassData().name, true)
|
|
140
141
|
const modelCallbackArgs = {model}
|
|
141
142
|
|
|
@@ -147,8 +148,8 @@ export default memo(shapeComponent(class ApiMakerBootStrapLiveTableModelRow exte
|
|
|
147
148
|
onDestroyClicked = async (e) => {
|
|
148
149
|
e.preventDefault()
|
|
149
150
|
|
|
150
|
-
const {destroyMessage} =
|
|
151
|
-
const {model} =
|
|
151
|
+
const {destroyMessage} = this.p.liveTable.props
|
|
152
|
+
const {model} = this.p
|
|
152
153
|
|
|
153
154
|
if (!confirm(I18n.t("js.shared.are_you_sure"))) {
|
|
154
155
|
return
|
package/src/table/style.scss
CHANGED
package/src/table/table.jsx
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import "./style"
|
|
2
|
+
import BaseComponent from "../base-component"
|
|
2
3
|
import Card from "../bootstrap/card"
|
|
3
4
|
import classNames from "classnames"
|
|
4
5
|
import Collection from "../collection"
|
|
@@ -6,6 +7,7 @@ import columnVisible from "./column-visible.mjs"
|
|
|
6
7
|
import debounce from "debounce"
|
|
7
8
|
import {digg, digs} from "diggerize"
|
|
8
9
|
import Filters from "./filters"
|
|
10
|
+
import HeaderColumn from "./header-column"
|
|
9
11
|
import * as inflection from "inflection"
|
|
10
12
|
import modelClassRequire from "../model-class-require.mjs"
|
|
11
13
|
import ModelRow from "./model-row"
|
|
@@ -16,8 +18,7 @@ import React, {memo, useEffect, useRef} from "react"
|
|
|
16
18
|
import selectCalculator from "./select-calculator"
|
|
17
19
|
import Select from "../inputs/select"
|
|
18
20
|
import Settings from "./settings"
|
|
19
|
-
import {shapeComponent
|
|
20
|
-
import SortLink from "../bootstrap/sort-link"
|
|
21
|
+
import {shapeComponent} from "set-state-compare/src/shape-component"
|
|
21
22
|
import TableSettings from "./table-settings"
|
|
22
23
|
import uniqunize from "uniqunize"
|
|
23
24
|
import useBreakpoint from "./use-breakpoint"
|
|
@@ -27,7 +28,7 @@ import useQueryParams from "on-location-changed/src/use-query-params.js"
|
|
|
27
28
|
const paginationOptions = [30, 60, 90, ["All", "all"]]
|
|
28
29
|
const WorkerPluginsCheckAllCheckbox = React.lazy(() => import("./worker-plugins-check-all-checkbox"))
|
|
29
30
|
|
|
30
|
-
export default memo(shapeComponent(class ApiMakerTable extends
|
|
31
|
+
export default memo(shapeComponent(class ApiMakerTable extends BaseComponent {
|
|
31
32
|
static defaultProps = {
|
|
32
33
|
card: true,
|
|
33
34
|
destroyEnabled: true,
|
|
@@ -87,7 +88,7 @@ export default memo(shapeComponent(class ApiMakerTable extends ShapeComponent {
|
|
|
87
88
|
filterFormRef: useRef()
|
|
88
89
|
})
|
|
89
90
|
|
|
90
|
-
const collectionKey = digg(this.
|
|
91
|
+
const collectionKey = digg(this.p.modelClass.modelClassData(), "collectionKey")
|
|
91
92
|
let queryName = this.props.queryName
|
|
92
93
|
|
|
93
94
|
if (!queryName) queryName = collectionKey
|
|
@@ -188,9 +189,9 @@ export default memo(shapeComponent(class ApiMakerTable extends ShapeComponent {
|
|
|
188
189
|
}
|
|
189
190
|
|
|
190
191
|
render () {
|
|
191
|
-
const {modelClass, noRecordsAvailableContent, noRecordsFoundContent} =
|
|
192
|
+
const {modelClass, noRecordsAvailableContent, noRecordsFoundContent} = this.p
|
|
192
193
|
const {collection, currentUser} = this.props
|
|
193
|
-
const {queryName, querySName, showFilters} =
|
|
194
|
+
const {queryName, querySName, showFilters} = this.s
|
|
194
195
|
const {
|
|
195
196
|
models,
|
|
196
197
|
overallCount,
|
|
@@ -362,8 +363,8 @@ export default memo(shapeComponent(class ApiMakerTable extends ShapeComponent {
|
|
|
362
363
|
}
|
|
363
364
|
|
|
364
365
|
filterForm = () => {
|
|
365
|
-
const {filterFormRef, submitFilter, submitFilterDebounce} =
|
|
366
|
-
const {filterContent, filterSubmitButton} =
|
|
366
|
+
const {filterFormRef, submitFilter, submitFilterDebounce} = this.tt
|
|
367
|
+
const {filterContent, filterSubmitButton} = this.p
|
|
367
368
|
const {filterSubmitLabel} = this.props
|
|
368
369
|
const {qParams} = digs(this.collection, "qParams")
|
|
369
370
|
|
|
@@ -395,7 +396,7 @@ export default memo(shapeComponent(class ApiMakerTable extends ShapeComponent {
|
|
|
395
396
|
}
|
|
396
397
|
|
|
397
398
|
onPerPageChanged = (e) => {
|
|
398
|
-
const {queryName} =
|
|
399
|
+
const {queryName} = this.s
|
|
399
400
|
const newPerPageValue = digg(e, "target", "value")
|
|
400
401
|
const perKey = `${queryName}_per`
|
|
401
402
|
const paramsChange = {}
|
|
@@ -407,20 +408,20 @@ export default memo(shapeComponent(class ApiMakerTable extends ShapeComponent {
|
|
|
407
408
|
|
|
408
409
|
tableControls() {
|
|
409
410
|
const {controls} = this.props
|
|
410
|
-
const {showSettings} =
|
|
411
|
+
const {showSettings} = this.s
|
|
411
412
|
const {models, qParams, query, result} = digs(this.collection, "models", "qParams", "query", "result")
|
|
412
413
|
|
|
413
414
|
return (
|
|
414
415
|
<>
|
|
415
416
|
{controls && controls({models, qParams, query, result})}
|
|
416
|
-
<a className="filter-button" href="#" onClick={
|
|
417
|
+
<a className="filter-button" href="#" onClick={this.tt.onFilterClicked}>
|
|
417
418
|
<i className="fa fa-fw fa-magnifying-glass la la-fw la-search" />
|
|
418
419
|
</a>
|
|
419
420
|
<span style={{position: "relative"}}>
|
|
420
421
|
{showSettings &&
|
|
421
|
-
<Settings onRequestClose={this.onRequestCloseSettings} table={this} />
|
|
422
|
+
<Settings onRequestClose={this.tt.onRequestCloseSettings} table={this} />
|
|
422
423
|
}
|
|
423
|
-
<a className="settings-button" href="#" onClick={
|
|
424
|
+
<a className="settings-button" href="#" onClick={this.tt.onSettingsClicked}>
|
|
424
425
|
<i className="fa fa-fw fa-gear la la-fw la-gear" />
|
|
425
426
|
</a>
|
|
426
427
|
</span>
|
|
@@ -429,9 +430,9 @@ export default memo(shapeComponent(class ApiMakerTable extends ShapeComponent {
|
|
|
429
430
|
}
|
|
430
431
|
|
|
431
432
|
tableContent () {
|
|
432
|
-
const {workplace} =
|
|
433
|
-
const {breakpoint} =
|
|
434
|
-
const {currentWorkplace, preparedColumns, tableSettingFullCacheKey} =
|
|
433
|
+
const {workplace} = this.p
|
|
434
|
+
const {breakpoint} = this.tt
|
|
435
|
+
const {currentWorkplace, preparedColumns, tableSettingFullCacheKey} = this.s
|
|
435
436
|
const {models, query} = digs(this.collection, "models", "query")
|
|
436
437
|
const ColumnInHeadComponent = this.columnInHeadComponent()
|
|
437
438
|
const RowComponent = this.rowComponent()
|
|
@@ -451,7 +452,7 @@ export default memo(shapeComponent(class ApiMakerTable extends ShapeComponent {
|
|
|
451
452
|
<HeadComponent>
|
|
452
453
|
<RowComponent className="live-table-header-row">
|
|
453
454
|
{workplace && currentWorkplace &&
|
|
454
|
-
<ColumnInHeadComponent>
|
|
455
|
+
<ColumnInHeadComponent style={{width: 25, textAlign: "center"}}>
|
|
455
456
|
<WorkerPluginsCheckAllCheckbox currentWorkplace={currentWorkplace} query={query} />
|
|
456
457
|
</ColumnInHeadComponent>
|
|
457
458
|
}
|
|
@@ -498,7 +499,7 @@ export default memo(shapeComponent(class ApiMakerTable extends ShapeComponent {
|
|
|
498
499
|
<Select
|
|
499
500
|
className="per-page-select"
|
|
500
501
|
defaultValue={perPage}
|
|
501
|
-
onChange={
|
|
502
|
+
onChange={this.tt.onPerPageChanged}
|
|
502
503
|
options={paginationOptions}
|
|
503
504
|
/>
|
|
504
505
|
</div>
|
|
@@ -535,28 +536,9 @@ export default memo(shapeComponent(class ApiMakerTable extends ShapeComponent {
|
|
|
535
536
|
responsiveComponent = (largeComponent) => this.isSmallScreen() ? "div" : largeComponent
|
|
536
537
|
rowComponent = () => this.responsiveComponent("tr")
|
|
537
538
|
|
|
538
|
-
headersContentFromColumns () {
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
const {query} = digs(this.collection, "query")
|
|
542
|
-
const ColumnInHeadComponent = this.columnInHeadComponent()
|
|
543
|
-
|
|
544
|
-
return preparedColumns?.map(({column, tableSettingColumn}) => columnVisible(column, tableSettingColumn) &&
|
|
545
|
-
<ColumnInHeadComponent
|
|
546
|
-
className={classNames(...this.headerClassNameForColumn(column))}
|
|
547
|
-
data-identifier={tableSettingColumn.identifier()}
|
|
548
|
-
key={tableSettingColumn.identifier()}
|
|
549
|
-
{...this.columnProps(column)}
|
|
550
|
-
>
|
|
551
|
-
{tableSettingColumn.hasSortKey() && query &&
|
|
552
|
-
<SortLink attribute={tableSettingColumn.sortKey()} defaultParams={defaultParams} query={query} title={this.headerLabelForColumn(column)} />
|
|
553
|
-
}
|
|
554
|
-
{(!tableSettingColumn.hasSortKey() || !query) &&
|
|
555
|
-
this.headerLabelForColumn(column)
|
|
556
|
-
}
|
|
557
|
-
</ColumnInHeadComponent>
|
|
558
|
-
)
|
|
559
|
-
}
|
|
539
|
+
headersContentFromColumns = () => this.s.preparedColumns?.map(({column, tableSettingColumn}) => columnVisible(column, tableSettingColumn) &&
|
|
540
|
+
<HeaderColumn column={column} key={tableSettingColumn.identifier()} table={this} tableSettingColumn={tableSettingColumn} />
|
|
541
|
+
)
|
|
560
542
|
|
|
561
543
|
headerClassNameForColumn (column) {
|
|
562
544
|
const classNames = ["live-table-header"]
|
|
@@ -568,7 +550,7 @@ export default memo(shapeComponent(class ApiMakerTable extends ShapeComponent {
|
|
|
568
550
|
}
|
|
569
551
|
|
|
570
552
|
headerLabelForColumn (column) {
|
|
571
|
-
const {modelClass} =
|
|
553
|
+
const {modelClass} = this.p
|
|
572
554
|
|
|
573
555
|
if ("label" in column) {
|
|
574
556
|
if (typeof column.label == "function") {
|
|
@@ -605,17 +587,16 @@ export default memo(shapeComponent(class ApiMakerTable extends ShapeComponent {
|
|
|
605
587
|
onSettingsClicked = (e) => {
|
|
606
588
|
e.preventDefault()
|
|
607
589
|
|
|
608
|
-
const {showSettings} =
|
|
590
|
+
const {showSettings} = this.s
|
|
609
591
|
|
|
610
592
|
this.setState({showSettings: !showSettings})
|
|
611
593
|
}
|
|
612
594
|
|
|
613
595
|
submitFilter = () => {
|
|
614
|
-
const
|
|
615
|
-
const filterForm = digg(filterFormRef, "current")
|
|
596
|
+
const filterForm = digg(this.tt.filterFormRef, "current")
|
|
616
597
|
const {appHistory} = this.props
|
|
617
598
|
const qParams = Params.serializeForm(filterForm)
|
|
618
|
-
const {queryQName} =
|
|
599
|
+
const {queryQName} = this.s
|
|
619
600
|
const changeParamsParams = {}
|
|
620
601
|
|
|
621
602
|
changeParamsParams[queryQName] = JSON.stringify(qParams)
|
|
@@ -623,5 +604,5 @@ export default memo(shapeComponent(class ApiMakerTable extends ShapeComponent {
|
|
|
623
604
|
Params.changeParams(changeParamsParams, {appHistory})
|
|
624
605
|
}
|
|
625
606
|
|
|
626
|
-
submitFilterDebounce = debounce(
|
|
607
|
+
submitFilterDebounce = debounce(this.tt.submitFilter)
|
|
627
608
|
}))
|