ywana-core8 0.0.699 → 0.0.701

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": "ywana-core8",
3
- "version": "0.0.699",
3
+ "version": "0.0.701",
4
4
  "description": "ywana-core8",
5
5
  "homepage": "https://ywana.github.io/workspace",
6
6
  "author": "Ernesto Roldan Garcia",
@@ -25,7 +25,6 @@ import { isEmpty} from '../commons'
25
25
  const paramString = notEmptyFields.reduce((query, key) => {
26
26
  const value = obj[key]
27
27
  const like = likes.includes(key) ? '%' : ''
28
-
29
28
  if (Array.isArray(value)) {
30
29
  const values = value.map(v => `${key}=${like}${v}${like}`).join("&")
31
30
  return `${query}${values}&`
@@ -39,7 +38,6 @@ import { isEmpty} from '../commons'
39
38
  return `${query}${key}=${like}${value}${like}&`
40
39
  }
41
40
  }, "")
42
-
43
41
  return paramString
44
42
  }
45
43
 
@@ -24,6 +24,7 @@ export const CollectionPage = (props) => {
24
24
  autosave = false, delay = 1000, patch = false, versioning = false,
25
25
  groupBy, levels, sorter, namer,
26
26
  editor, editorTitle, editorActions,
27
+ filters,
27
28
  footer,
28
29
  children
29
30
  } = props
@@ -78,7 +79,7 @@ export const CollectionPage = (props) => {
78
79
  {renderActions()}
79
80
  </Header>
80
81
  <menu className={`collection-page ${className} ${hiddenStyle}`}>
81
- {canFilter ? <CollectionFilters schema={schema} /> : null}
82
+ {canFilter ? <CollectionFilters schema={schema} initial={filters} /> : null}
82
83
  {levels ? <CollectionTree schema={schema} icon={icon} levels={levels} onSelect={onSelect} sorter={sorter} searchBy={searchBy} namer={namer} /> : <CollectionList groupBy={groupBy} onSelect={onSelect} searchBy={searchBy} />}
83
84
  </menu>
84
85
  <main key={id} className={`collection-page ${className}`}>
@@ -97,6 +98,7 @@ export const CollectionPage = (props) => {
97
98
  */
98
99
  export const CollectionFilters = (props) => {
99
100
 
101
+ const [pageContext, setPageContext] = useContext(PageContext)
100
102
  const { schema, initial = {}, onChange } = props
101
103
  const [form, setForm] = useState(initial)
102
104
  const [showFilters, setShowFilters] = useState(false)
File without changes
@@ -0,0 +1,83 @@
1
+ import { HTTPClient, Session } from '../http'
2
+ import { isEmpty} from '../commons'
3
+
4
+ /**
5
+ * Collection API
6
+ */
7
+ export const CollectionAPI = (url, host) => {
8
+
9
+ const http = HTTPClient(host || window.API || process.env.REACT_APP_API, Session);
10
+
11
+ /**
12
+ * objectToQueryParamString
13
+ *
14
+ * @param {*} obj
15
+ * @returns
16
+ */
17
+ function objectToQueryParamString(obj, likes) {
18
+
19
+ if (isEmpty(obj)) {
20
+ return ""
21
+ }
22
+
23
+ const notEmptyFields = Object.keys(obj).filter(key => !isEmpty(obj[key]))
24
+
25
+ const paramString = notEmptyFields.reduce((query, key) => {
26
+ const value = obj[key]
27
+ const like = likes.includes(key) ? '%' : ''
28
+ if (Array.isArray(value)) {
29
+ const values = value.map(v => `${key}=${like}${v}${like}`).join("&")
30
+ return `${query}${values}&`
31
+ } else if (typeof value === "object") {
32
+ const params = objectToQueryParamString(value, likes)
33
+ params.split("&").forEach(param => {
34
+ query = query.concat(`${key}.${param}&`)
35
+ })
36
+ return query
37
+ } else {
38
+ return `${query}${key}=${like}${value}${like}&`
39
+ }
40
+ }, "")
41
+ return paramString
42
+ }
43
+
44
+ return {
45
+
46
+ all(filters, likes = [], page) {
47
+ let queryParams = page ? `?page=${page}&` : "?"
48
+ const filterQuery = objectToQueryParamString(filters, likes)
49
+ queryParams = `${queryParams}${filterQuery}`
50
+ queryParams = queryParams.substring(0, queryParams.length - 1)
51
+ return http.GET(`${url}${queryParams}`)
52
+ },
53
+
54
+ find(id) {
55
+ return http.GET(`${url}/${id}`)
56
+ },
57
+
58
+ create(form) {
59
+ const body = JSON.stringify(form)
60
+ return http.POST(url, body)
61
+ },
62
+
63
+ update(form) {
64
+ const body = JSON.stringify(form)
65
+ return http.PUT(`${url}/${form.id}`, body)
66
+ },
67
+
68
+ updateProperty(id, propertyName, form) {
69
+ const body = JSON.stringify(form)
70
+ return http.PUT(`${url}/${id}/${propertyName}`, body)
71
+ },
72
+
73
+ patch(id, form) {
74
+ const body = JSON.stringify(form)
75
+ return http.PATCH(`${url}/${id}`, body)
76
+ },
77
+
78
+ remove(id) {
79
+ return http.DELETE(`${url}/${id}`)
80
+ },
81
+
82
+ }
83
+ }
@@ -0,0 +1,19 @@
1
+ import React, { useState } from 'react'
2
+ import { Button } from '../html'
3
+
4
+ import { CollectionAPI } from './CollectionAPI'
5
+
6
+ const CollectionAPITest = (prop) => {
7
+
8
+ const API = CollectionAPI('/references', 'http://localhost:3000')
9
+
10
+ function all() {
11
+ API.all({ name: "2223"}, ["name"]).then(res => console.log(res))
12
+ }
13
+
14
+ return (
15
+ <>
16
+ <Button label="ALL" action={all} />
17
+ </>
18
+ )
19
+ }
@@ -0,0 +1,160 @@
1
+ import React, { useState } from 'react'
2
+ import { CollectionAPI } from "./CollectionAPI";
3
+
4
+ export const CollectionContext = React.createContext()
5
+
6
+ /**
7
+ * Collection Context
8
+ */
9
+ export const CollectionContextProvider = (props) => {
10
+
11
+ const { host, url, page, fetching=true, field, versioning = false, children } = props
12
+ const API = CollectionAPI(url, host)
13
+
14
+ const [all, setAll] = useState([])
15
+ const [filters, setFilters] = useState({})
16
+ const [likes, setLikes] = useState([])
17
+ const [customFilters, setCustomFilters] = useState({})
18
+ const [queries, setQueries] = useState([])
19
+ const [selected, setSelected] = useState(null)
20
+
21
+ async function load() {
22
+
23
+ const runCustomFilters = (all) => {
24
+ const cfs = Object.values(customFilters)
25
+ const data = cfs.length ? cfs.reduce((acc, filter) => filter(acc), all) : all;
26
+ return data
27
+ }
28
+
29
+ try {
30
+ const response = await API.all(filters, likes, page);
31
+ const next = field ? response[field] : response;
32
+ const data = runCustomFilters(next)
33
+ setAll(data)
34
+ } catch (error) {
35
+ console.log(error)
36
+ }
37
+ return
38
+ }
39
+
40
+ async function select(id) {
41
+ if (fetching) {
42
+ const result = await this.fetch(id)
43
+ setSelected(result)
44
+ } else {
45
+ const result = this.all.find(item => item.id === id);
46
+ setSelected(result)
47
+ }
48
+ }
49
+
50
+ function addCustomFilter(id, filter) {
51
+ setCustomFilters({ ...customFilters, [id]: filter })
52
+ }
53
+
54
+ function removeCustomFilter(id) {
55
+ const next = { ...customFilters }
56
+ delete next[id]
57
+ setCustomFilters(next)
58
+ }
59
+
60
+ /*
61
+ async function reloadSelection() {
62
+ const result = await this.fetch(this.selected.id)
63
+ this.selected = result
64
+ }
65
+
66
+ async function fetch(id) {
67
+ try {
68
+ const result = await API.find(id)
69
+ return result
70
+ } catch (error) {
71
+ console.log(error)
72
+ }
73
+ }
74
+
75
+ function clear() {
76
+ this.selected = null
77
+ }
78
+
79
+ async function create(form) {
80
+ try {
81
+ if (versioning) form.version = 1
82
+ await API.create(form);
83
+ await this.load();
84
+ } catch (error) {
85
+ console.log(error)
86
+ }
87
+ return
88
+ }
89
+
90
+ async function update(form) {
91
+ try {
92
+ if (versioning) form.version = form.version ? form.version + 1 : 1
93
+ await API.update(form)
94
+ await this.load()
95
+ } catch (error) {
96
+ console.log(error)
97
+ }
98
+ return
99
+ }
100
+
101
+ async function patch(id, form) {
102
+ try {
103
+ if (versioning) form.version = form.version ? form.version + 1 : 1
104
+ await API.patch(id, form)
105
+ await this.load()
106
+ } catch (error) {
107
+ console.log(error)
108
+ }
109
+ return
110
+ }
111
+
112
+ async function updateProperty(id, propertyName, form) {
113
+ try {
114
+ await API.updateProperty(id, propertyName, form)
115
+ await this.load()
116
+ } catch (error) {
117
+ console.log(error)
118
+ }
119
+ return
120
+ }
121
+
122
+ async function remove(id) {
123
+ try {
124
+ await API.remove(id)
125
+ await this.load()
126
+ } catch (error) {
127
+ console.log(error)
128
+ }
129
+ return
130
+ }
131
+
132
+ */
133
+
134
+ const value = {
135
+ all,
136
+ load,
137
+
138
+ selected,
139
+ select,
140
+
141
+ filters,
142
+ setFilters,
143
+ setLikes,
144
+
145
+ customFilters,
146
+ addCustomFilter,
147
+ removeCustomFilter,
148
+
149
+ queries,
150
+ setQueries,
151
+
152
+ }
153
+
154
+ return (
155
+ < CollectionContext.Provider value = { value } >
156
+ { children }
157
+ </CollectionContext.Provider >
158
+ )
159
+ }
160
+
@@ -0,0 +1,58 @@
1
+ import React, { useContext } from 'react'
2
+ import { CheckBox } from '../html'
3
+ import { CollectionContext, CollectionContextProvider } from './CollectionContext'
4
+ import { CollectionEditor } from './CollectionEditor'
5
+ import { CollectionFilters } from './CollectionFilters'
6
+ import { CollectionList } from './CollectionList'
7
+
8
+ const CollectionContextTest = (props) => {
9
+
10
+ const config = {
11
+ host: "http://localhost:3000",
12
+ url: "/references",
13
+ }
14
+
15
+ const style = {
16
+ display: "flex",
17
+ flexDirection: "row",
18
+ }
19
+
20
+ const schema = [
21
+ { id: "id", type: "string", label: "ID" },
22
+ { id: "name", type: "string", label: "Name", filter: true, like: true },
23
+ { id: "gender", type: "string", label: "Gender", filter: true, options: [
24
+ { label: "Masculine", value: 1 },
25
+ { label: "Feminine", value: 0 }
26
+ ]},
27
+ { id: "description", type: "string", label: "Description" },
28
+ ]
29
+
30
+ return (
31
+ <div style={style}>
32
+ <CollectionContextProvider {...config}>
33
+ <CollectionFilters schema={schema} >
34
+ <CustomFilter1 />
35
+ </CollectionFilters>
36
+ <CollectionList />
37
+ <CollectionEditor />
38
+ </CollectionContextProvider>
39
+ </div>
40
+
41
+ )
42
+ }
43
+
44
+ const CustomFilter1 = (props) => {
45
+ const collectionContext = useContext(CollectionContext)
46
+ const { filters, setFilters } = collectionContext
47
+
48
+ function change(id, value) {
49
+ setFilters({ ...filters, [id]: value })
50
+ }
51
+
52
+ return (
53
+ <div>
54
+ <CheckBox id="custom1" label="Custom Filter 1" value={filters.custom1} onChange={change} />
55
+ </div>
56
+ )
57
+ }
58
+
@@ -0,0 +1,17 @@
1
+ import React, { useContext } from 'react'
2
+ import { CollectionContext } from './CollectionContext'
3
+
4
+ /**
5
+ * Collection Editor
6
+ */
7
+ export const CollectionEditor = (props) => {
8
+
9
+ const context = useContext(CollectionContext)
10
+ const { selected } = context
11
+
12
+ return (
13
+ <div className="collection-editor">
14
+ editor
15
+ </div>
16
+ )
17
+ }
@@ -0,0 +1,50 @@
1
+ .collection-filters {
2
+ display: flex;
3
+ flex-direction: column;
4
+ width: 30rem;
5
+ background-color: rgb(243, 243, 243);
6
+ }
7
+
8
+ .collection-filters>header {
9
+ display: flex;
10
+ flex-direction: row;
11
+ justify-content: space-between;
12
+ align-items: center;
13
+ border-bottom: 1px solid rgb(207, 207, 207);
14
+ }
15
+
16
+ .custom-filters {
17
+ display: flex;
18
+ flex-direction: row;
19
+ justify-content: space-between;
20
+ align-items: center;
21
+ padding: 0.5rem;
22
+ }
23
+
24
+ .collection-filter-resume {
25
+ display: flex;
26
+ flex-direction: row;
27
+ justify-content: space-between;
28
+ align-items: center;
29
+ padding: 0.5rem;
30
+ font-size: .8rem;
31
+ font-weight: 300;
32
+ }
33
+
34
+ .collection-filter-resume-label {
35
+ display: flex;
36
+ flex-direction: row;
37
+ justify-content: space-between;
38
+ align-items: center;
39
+ margin-right: 0.2rem;
40
+ }
41
+
42
+ .collection-filter-resume-value {
43
+ font-weight: 400;
44
+ }
45
+
46
+ .dynamic-filters {
47
+ display: flex;
48
+ flex-direction: column;
49
+ padding: 0 0 1rem 0;
50
+ }
@@ -0,0 +1,71 @@
1
+ import React, { useContext, useEffect, useState } from 'react'
2
+ import { Icon, Tooltip } from '../html'
3
+ import { CollectionContext } from './CollectionContext'
4
+ import { DynamicForm } from './DynamicForm'
5
+ import './CollectionFilters.css'
6
+
7
+ /*.
8
+ * Collection Filters
9
+ */
10
+ export const CollectionFilters = (props) => {
11
+
12
+ const { schema, children } = props
13
+ const context = useContext(CollectionContext)
14
+ const { filters } = context
15
+ const [open, setOpen] = useState(false)
16
+
17
+ useEffect(() => {
18
+ context.setLikes(schema.filter(field => field.like).map(field => field.id))
19
+ }, [schema])
20
+
21
+ function change(id, value) {
22
+ context.setFilters({ ...filters, [id]: value })
23
+ }
24
+
25
+ function toggle() {
26
+ setOpen(!open)
27
+ }
28
+
29
+ const toggleIcon = open ? "expand_less" : "expand_more"
30
+ return (
31
+ <div className="collection-filters">
32
+ <header>
33
+ <div className='custom-filters'>
34
+ {children}
35
+ </div>
36
+ <CollectionFiltersResume schema={schema} />
37
+ <Icon icon={toggleIcon} clickable action={toggle} />
38
+ </header>
39
+ {open ? <div className='dynamic-filters'>
40
+ <DynamicForm schema={schema} values={filters} onChange={change} />
41
+ </div> : null}
42
+ </div>
43
+ )
44
+ }
45
+
46
+ const CollectionFiltersResume = (props) => {
47
+
48
+ const { schema } = props
49
+ const context = useContext(CollectionContext)
50
+ const { filters } = context
51
+ const fields = Object.keys(filters)
52
+
53
+ if (!fields.length) return null
54
+
55
+ return (
56
+ <>
57
+ {fields
58
+ .filter(id => filters[id] !== undefined && filters[id] !== null && filters[id] !== "")
59
+ .map(id => {
60
+ const field = schema.find(field => field.id === id)
61
+ const value = filters[id]
62
+ return (
63
+ <div className='collection-filter-resume'>
64
+ <span className='collection-filter-resume-label'>{field.label}:</span>
65
+ <span className='collection-filter-resume-value'>{value}</span>
66
+ </div>
67
+ )
68
+ })}
69
+ </>
70
+ )
71
+ }
@@ -0,0 +1,30 @@
1
+ import React, { useContext, useEffect } from 'react'
2
+ import { List } from '../html'
3
+ import { CollectionContext } from './CollectionContext'
4
+
5
+ /**
6
+ * Collection List
7
+ */
8
+ export const CollectionList = (props) => {
9
+
10
+ const context = useContext(CollectionContext)
11
+ const { all = [], selected, filters, customFilters } = context
12
+
13
+ useEffect(() => {
14
+ context.load()
15
+ }, [filters, customFilters])
16
+
17
+ const items = all.map(item => {
18
+ return {
19
+ icon: "folder",
20
+ line1: item.name,
21
+ meta: item.state,
22
+ }
23
+ })
24
+
25
+ return (
26
+ <div className="collection-list">
27
+ <List items={items} />
28
+ </div>
29
+ )
30
+ }
@@ -0,0 +1,36 @@
1
+ .collection-page.ide {
2
+ display: grid;
3
+ grid-template-areas: "header header"
4
+ "filters main"
5
+ "list main";
6
+ grid-template-columns: auto 1fr;
7
+ grid-template-rows: auto auto 1fr;
8
+ }
9
+
10
+ .collection-page.ide .header {
11
+ grid-area: header;
12
+ }
13
+
14
+ .collection-page.ide .collection-filters {
15
+ grid-area: filters;
16
+ }
17
+
18
+ .collection-page.ide .collection-editor {
19
+ grid-area: main;
20
+ }
21
+
22
+ .collection-page.ide .collection-aside {
23
+ grid-area: aside;
24
+ }
25
+
26
+ .collection-page.ide .collection-list {
27
+ grid-area: list;
28
+ }
29
+
30
+ .collection-page.ide .collection-console {
31
+ grid-area: console;
32
+ }
33
+
34
+ .collection-page.ide .footer {
35
+ grid-area: footer;
36
+ }
@@ -0,0 +1,31 @@
1
+ import React from 'react'
2
+ import { CollectionContextProvider } from './CollectionContext'
3
+ import { CollectionFilters } from './CollectionFilters'
4
+ import { CollectionList } from './CollectionList'
5
+ import { CollectionEditor } from './CollectionEditor'
6
+ import './CollectionPage.css'
7
+ import { Header } from '../html'
8
+
9
+ /**
10
+ * Collection Page
11
+ */
12
+ export const CollectionPage = (props) => {
13
+
14
+ const {
15
+ host, url, schema,
16
+ layout,
17
+ canFilter, customFilters
18
+ } = props
19
+
20
+ return (
21
+ <div className={`collection-page ${layout}`}>
22
+ <CollectionContextProvider host={host} url={url}>
23
+ <Header title="CollectionPage" />
24
+ {canFilter ? <CollectionFilters schema={schema} >{customFilters}</CollectionFilters> : null}
25
+ <CollectionList />
26
+ <CollectionEditor />
27
+ </CollectionContextProvider>
28
+ </div>
29
+
30
+ )
31
+ }