@kaspernj/api-maker 1.0.375 → 1.0.376

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": "@kaspernj/api-maker",
3
- "version": "1.0.375",
3
+ "version": "1.0.376",
4
4
  "type": "module",
5
5
  "description": "",
6
6
  "main": "index.js",
@@ -6,8 +6,10 @@ import SaveSearchModal from "./save-search-modal"
6
6
  import PropTypes from "prop-types"
7
7
  import {memo} from "react"
8
8
  import {shapeComponent, ShapeComponent} from "set-state-compare/src/shape-component.js"
9
+ import {TableSearch} from "../../models.mjs.erb"
9
10
  import useI18n from "i18n-on-steroids/src/use-i18n.mjs"
10
11
  import useQueryParams from "on-location-changed/src/use-query-params"
12
+ import {View} from "react-native"
11
13
 
12
14
  export default memo(shapeComponent(class ApiMakerTableFilters extends ShapeComponent {
13
15
  static propTypes = {
@@ -24,7 +26,7 @@ export default memo(shapeComponent(class ApiMakerTableFilters extends ShapeCompo
24
26
  this.t = t
25
27
  this.useStates({
26
28
  filter: undefined,
27
- showLoadSearchModal: false,
29
+ showLoadSearchModal: undefined,
28
30
  showSaveSearchModal: false
29
31
  })
30
32
  }
@@ -36,7 +38,7 @@ export default memo(shapeComponent(class ApiMakerTableFilters extends ShapeCompo
36
38
  const currentFilters = this.currentFilters()
37
39
 
38
40
  return (
39
- <div className="api-maker--table--filters">
41
+ <View dataSet={{class: "api-maker--table--filters"}}>
40
42
  {filter &&
41
43
  <FilterForm
42
44
  filter={filter}
@@ -50,6 +52,7 @@ export default memo(shapeComponent(class ApiMakerTableFilters extends ShapeCompo
50
52
  <LoadSearchModal
51
53
  currentUser={currentUser}
52
54
  modelClass={modelClass}
55
+ onEditSearchPressed={digg(this, "onEditSearchPressed")}
53
56
  onRequestClose={digg(this, "onRequestCloseLoadSearchModal")}
54
57
  querySearchName={querySName}
55
58
  />
@@ -59,6 +62,7 @@ export default memo(shapeComponent(class ApiMakerTableFilters extends ShapeCompo
59
62
  currentFilters={digg(this, "currentFilters")}
60
63
  currentUser={currentUser}
61
64
  onRequestClose={digg(this, "onRequestCloseSaveSearchModal")}
65
+ search={showSaveSearchModal}
62
66
  />
63
67
  }
64
68
  {currentFilters?.map((filterData, filterIndex) =>
@@ -85,7 +89,7 @@ export default memo(shapeComponent(class ApiMakerTableFilters extends ShapeCompo
85
89
  </>
86
90
  }
87
91
  </div>
88
- </div>
92
+ </View>
89
93
  )
90
94
  }
91
95
 
@@ -109,10 +113,19 @@ export default memo(shapeComponent(class ApiMakerTableFilters extends ShapeCompo
109
113
  }
110
114
 
111
115
  onApplyClicked = () => this.setState({filter: undefined})
116
+
117
+ onEditSearchPressed = ({search}) => {
118
+ this.onRequestCloseLoadSearchModal()
119
+ this.setState({
120
+ showSaveSearchModal: search
121
+ })
122
+ }
123
+
112
124
  onFilterClicked = (args) => this.setState({filter: args})
113
125
 
114
126
  onLoadSearchClicked = (e) => {
115
127
  e.preventDefault()
128
+
116
129
  this.setState({
117
130
  showLoadSearchModal: true
118
131
  })
@@ -136,13 +149,13 @@ export default memo(shapeComponent(class ApiMakerTableFilters extends ShapeCompo
136
149
  }
137
150
 
138
151
  onRequestCloseLoadSearchModal = () => this.setState({showLoadSearchModal: false})
139
- onRequestCloseSaveSearchModal = () => this.setState({showSaveSearchModal: false})
152
+ onRequestCloseSaveSearchModal = () => this.setState({showSaveSearchModal: undefined})
140
153
 
141
154
  onSaveSearchClicked = (e) => {
142
155
  e.preventDefault()
143
156
 
144
157
  if (this.hasAnyFilters()) {
145
- this.setState({showSaveSearchModal: true})
158
+ this.setState({showSaveSearchModal: new TableSearch()})
146
159
  } else {
147
160
  FlashMessage.alert(this.t(".no_filters_has_been_set", {defaultValue: "No filters has been set"}))
148
161
  }
@@ -1,38 +1,127 @@
1
1
  import apiMakerConfig from "@kaspernj/api-maker/src/config.mjs"
2
2
  import classNames from "classnames"
3
3
  import {digg} from "diggerize"
4
+ import {memo, useEffect} from "react"
5
+ import {shapeComponent, ShapeComponent} from "set-state-compare/src/shape-component.js"
4
6
  import {TableSearch} from "../../models.mjs.erb"
5
- import {useCallback, useEffect, useState} from "react"
6
-
7
- const SearchLink = (props) => {
8
- const {onClick, search} = props
9
- const onSearchClicked = useCallback((e) => {
10
- e.preventDefault()
11
- onClick({search})
12
- })
13
-
14
- return (
15
- <a className="load-search-link" href="#" key={search.id()} onClick={onSearchClicked} style={{display: "block"}}>
16
- {search.name()}
17
- </a>
18
- )
19
- }
20
-
21
- const ApiMakerTableFiltersLoadSearchModal = (props) => {
22
- const {className, currentUser, modelClass, onRequestClose, querySearchName, ...restProps} = props
23
- const Modal = apiMakerConfig.getModal()
24
- const [searches, setSearches] = useState(undefined)
25
-
26
- const loadSearches = async () => {
7
+ import {Pressable, Text, View} from "react-native"
8
+ import useI18n from "i18n-on-steroids/src/use-i18n.mjs"
9
+
10
+ const SearchLink = memo(shapeComponent(class SearchLink extends ShapeComponent {
11
+ render() {
12
+ const {search} = this.props
13
+
14
+ return (
15
+ <View dataSet={{class: "search-row", searchId: search.id()}} style={{flexDirection: "row", width: "100%"}}>
16
+ <Pressable dataSet={{class: "load-search-link"}} onPress={this.onSearchClicked} style={{justifyContent: "center"}}>
17
+ <Text>
18
+ {search.name()}
19
+ </Text>
20
+ </Pressable>
21
+ <View style={{flexDirection: "row", marginLeft: "auto"}}>
22
+ <Pressable
23
+ dataSet={{class: "edit-search-button"}}
24
+ onPress={this.onEditPressed}
25
+ style={{
26
+ alignItems: "center",
27
+ justifyContent: "center",
28
+ width: 25,
29
+ height: 25,
30
+ backgroundColor: "#fff",
31
+ border: "1px solid #007bff",
32
+ borderRadius: 5,
33
+ color: "#007bff"
34
+ }}
35
+ >
36
+ <Text>
37
+ &#x270E;
38
+ </Text>
39
+ </Pressable>
40
+ <Pressable
41
+ dataSet={{class: "delete-search-button"}}
42
+ onPress={this.onDeletePressed}
43
+ style={{
44
+ alignItems: "center",
45
+ justifyContent: "center",
46
+ marginLeft: 5,
47
+ width: 25,
48
+ height: 25,
49
+ backgroundColor: "#fff",
50
+ border: "1px solid #dc3545",
51
+ borderRadius: 5,
52
+ color: "#dc3545"
53
+ }}
54
+ >
55
+ <Text>
56
+ &#x2715;
57
+ </Text>
58
+ </Pressable>
59
+ </View>
60
+ </View>
61
+ )
62
+ }
63
+
64
+ onDeletePressed = async () => {
65
+ if (!confirm("Are you sure?")) {
66
+ return
67
+ }
68
+
69
+ const {search} = this.props
70
+
71
+ await search.destroy()
72
+ this.props.onDeleted({search})
73
+ }
74
+
75
+ onEditPressed = () => this.props.onEditPressed({search: this.props.search})
76
+ onSearchClicked = () => this.props.onClick({search: this.props.search})
77
+ }))
78
+
79
+ export default memo(shapeComponent(class ApiMakerTableFiltersLoadSearchModal extends ShapeComponent {
80
+ setup() {
81
+ const {t} = useI18n({namespace: "js.api_maker.table.filters.load_search_modal"})
82
+
83
+ this.useStates({
84
+ editSearch: undefined,
85
+ searches: undefined
86
+ })
87
+ this.setInstance({t})
88
+
89
+ useEffect(() => {
90
+ this.loadSearches()
91
+ }, [])
92
+ }
93
+
94
+ loadSearches = async () => {
95
+ const {currentUser} = this.props
27
96
  const userType = digg(currentUser.modelClassData(), "name")
28
97
  const searches = await TableSearch
29
98
  .ransack({user_id_eq: currentUser.id(), user_type_eq: userType})
30
99
  .toArray()
31
100
 
32
- setSearches(searches)
101
+ this.setState({searches})
33
102
  }
34
103
 
35
- const onSearchClicked = useCallback(({search}) => {
104
+ render() {
105
+ const {t} = this
106
+ const {className, currentUser, modelClass, onEditSearchPressed, onRequestClose, querySearchName, ...restProps} = this.props
107
+ const Modal = apiMakerConfig.getModal()
108
+
109
+ return (
110
+ <Modal className={classNames("api-maker--table--filters--load-search-modal", className)} onRequestClose={onRequestClose} {...restProps}>
111
+ <View>
112
+ <Text>
113
+ {t(".choose_a_search", {defaultValue: "Choose a search"})}
114
+ </Text>
115
+ </View>
116
+ {this.state.searches?.map((search) =>
117
+ <SearchLink key={search.id()} onClick={this.onSearchClicked} onDeleted={this.onSearchDeleted} onEditPressed={onEditSearchPressed} search={search} />
118
+ )}
119
+ </Modal>
120
+ )
121
+ }
122
+
123
+ onSearchClicked = ({search}) => {
124
+ const {onRequestClose, querySearchName} = this.props
36
125
  const queryParams = search.queryParams()
37
126
  const newParams = {}
38
127
 
@@ -41,20 +130,11 @@ const ApiMakerTableFiltersLoadSearchModal = (props) => {
41
130
  Params.changeParams(newParams)
42
131
 
43
132
  onRequestClose()
44
- })
45
-
46
- useEffect(() => { loadSearches() }, [])
47
-
48
- return (
49
- <Modal className={classNames("api-maker--table--filters--load-search-modal", className)} onRequestClose={onRequestClose} {...restProps}>
50
- <div>
51
- {I18n.t("js.api_maker.table.filters.load_search_modal.choose_a_search", {defaultValue: "Choose a search"})}
52
- </div>
53
- {searches?.map((search) =>
54
- <SearchLink key={search.id()} onClick={onSearchClicked} search={search} />
55
- )}
56
- </Modal>
57
- )
58
- }
59
-
60
- export default ApiMakerTableFiltersLoadSearchModal
133
+ }
134
+
135
+ onSearchDeleted = ({search}) => {
136
+ this.setState({
137
+ searches: this.state.searches.filter((existingSearch) => existingSearch.id() != search.id())
138
+ })
139
+ }
140
+ }))
@@ -1,9 +1,8 @@
1
1
  import apiMakerConfig from "@kaspernj/api-maker/src/config.mjs"
2
2
  import Checkbox from "@kaspernj/api-maker/src/bootstrap/checkbox"
3
- import {digg} from "diggerize"
3
+ import {digg, digs} from "diggerize"
4
4
  import Input from "../../bootstrap/input"
5
5
  import {shapeComponent, ShapeComponent} from "set-state-compare/src/shape-component.js"
6
- import {TableSearch} from "../../models.mjs.erb"
7
6
  import {memo} from "react"
8
7
  import useI18n from "i18n-on-steroids/src/use-i18n.mjs"
9
8
 
@@ -15,18 +14,20 @@ export default memo(shapeComponent(class ApiMakerTableFiltersSaveSearchModal ext
15
14
  }
16
15
 
17
16
  render() {
18
- const {currentFilters, currentUser, onRequestClose, ...restProps} = this.props
17
+ const {currentFilters, currentUser, onRequestClose, search, ...restProps} = this.props
19
18
  const Modal = apiMakerConfig.getModal()
20
19
 
21
20
  return (
22
21
  <Modal onRequestClose={onRequestClose} {...restProps}>
23
22
  <form onSubmit={this.onSaveSearchSubmit}>
24
23
  <Input
24
+ defaultValue={search.name()}
25
25
  id="table_search_name"
26
26
  label={this.t(".search_name", {defaultValue: "Search name"})}
27
27
  name="table_search[name]"
28
28
  />
29
29
  <Checkbox
30
+ defaultChecked={search.public()}
30
31
  id="table_search_public"
31
32
  label={this.t(".public", {defaultValue: "Public"})}
32
33
  name="table_search[public]"
@@ -44,15 +45,18 @@ export default memo(shapeComponent(class ApiMakerTableFiltersSaveSearchModal ext
44
45
 
45
46
  const form = digg(e, "target")
46
47
  const formData = new FormData(form)
47
- const tableSearch = new TableSearch()
48
+ const {currentFilters, currentUser, onRequestClose, search} = digs(this.props, "currentFilters", "currentUser", "onRequestClose", "search")
48
49
 
49
- formData.append("table_search[query_params]", JSON.stringify(this.props.currentFilters()))
50
- formData.append("table_search[user_type]", digg(this.props.currentUser.modelClassData(), "className"))
51
- formData.append("table_search[user_id]", this.props.currentUser.id())
50
+ if (search.isNewRecord()) {
51
+ formData.append("table_search[query_params]", JSON.stringify(currentFilters()))
52
+ }
53
+
54
+ formData.append("table_search[user_type]", digg(currentUser.modelClassData(), "className"))
55
+ formData.append("table_search[user_id]", currentUser.id())
52
56
 
53
57
  try {
54
- await tableSearch.saveRaw(formData, {form})
55
- this.props.onRequestClose()
58
+ await search.saveRaw(formData, {form})
59
+ onRequestClose()
56
60
  } catch (error) {
57
61
  FlashMessage.errorResponse(error)
58
62
  }