ywana-core8 0.0.537 → 0.0.538
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/db/db.json +17 -1
- package/dist/index.cjs +178 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +66 -59
- package/dist/index.css.map +1 -1
- package/dist/index.modern.js +178 -21
- package/dist/index.modern.js.map +1 -1
- package/dist/index.umd.js +178 -21
- package/dist/index.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/domain/CollectionPage.css +1 -19
- package/src/domain/ContentEditor.css +47 -22
- package/src/domain/ContentEditor.js +147 -41
- package/src/domain/TablePage.js +1 -0
- package/src/site/site.test.js +12 -9
package/package.json
CHANGED
@@ -30,25 +30,7 @@ main.collection-page {
|
|
30
30
|
flex-direction: column;
|
31
31
|
}
|
32
32
|
|
33
|
-
.collection-page
|
33
|
+
main.collection-page>.content-editor {
|
34
34
|
flex: 1;
|
35
35
|
}
|
36
36
|
|
37
|
-
.collection-page .content-editor>section {
|
38
|
-
border: solid 1px var(--divider-color);
|
39
|
-
background-color: var(--paper-color);
|
40
|
-
padding: 0 1rem 1rem 1rem;
|
41
|
-
}
|
42
|
-
|
43
|
-
.collection-page .content-editor.tabbed>section {
|
44
|
-
border: solid 1px var(--divider-color);
|
45
|
-
border-width: 0 1px 1px 1px;
|
46
|
-
background-color: var(--paper-color);
|
47
|
-
padding: 0 1rem 1rem 1rem;
|
48
|
-
}
|
49
|
-
|
50
|
-
.collection-page > article {
|
51
|
-
display: flex;
|
52
|
-
overflow: hidden;
|
53
|
-
}
|
54
|
-
|
@@ -1,19 +1,43 @@
|
|
1
|
+
/**************************************/
|
2
|
+
/*********** content-editor ***********/
|
3
|
+
/**************************************/
|
4
|
+
|
1
5
|
.content-editor {
|
2
|
-
padding:
|
6
|
+
padding: .5rem;
|
3
7
|
}
|
4
8
|
|
5
|
-
|
6
|
-
|
7
|
-
|
9
|
+
/**************************************/
|
10
|
+
/******* content-editor tabbed ********/
|
11
|
+
/**************************************/
|
12
|
+
|
13
|
+
.content-editor.tabbed {
|
14
|
+
overflow: hidden !important;
|
15
|
+
display: flex;
|
16
|
+
flex-direction: column;
|
8
17
|
}
|
9
18
|
|
10
|
-
.content-editor
|
11
|
-
|
19
|
+
.content-editor.tabbed>.tabs {
|
20
|
+
min-height: 3rem;
|
21
|
+
}
|
22
|
+
|
23
|
+
.content-editor.tabbed>section {
|
24
|
+
border: solid 1px var(--divider-color);
|
25
|
+
border-width: 0 1px 1px 1px;
|
26
|
+
background-color: var(--paper-color);
|
27
|
+
padding: 1rem;
|
28
|
+
overflow: auto;
|
29
|
+
}
|
30
|
+
|
31
|
+
.content-editor>section>header {
|
12
32
|
padding: .5rem;
|
13
33
|
border-bottom: solid 1px var(--divider-color);
|
14
34
|
margin-bottom: .5rem;
|
15
35
|
}
|
16
36
|
|
37
|
+
/**************************************/
|
38
|
+
/************ entity-editor ***********/
|
39
|
+
/**************************************/
|
40
|
+
|
17
41
|
.entity-editor {
|
18
42
|
}
|
19
43
|
|
@@ -21,20 +45,19 @@
|
|
21
45
|
padding: .5rem;
|
22
46
|
}
|
23
47
|
|
24
|
-
.
|
48
|
+
.entity-editor>section {
|
49
|
+
margin-bottom: 1rem;
|
25
50
|
}
|
26
51
|
|
27
|
-
.
|
28
|
-
padding:
|
29
|
-
|
30
|
-
|
52
|
+
.entity-editor>section>header {
|
53
|
+
padding: .5rem;
|
54
|
+
border-bottom: solid 1px var(--divider-color);
|
55
|
+
margin-bottom: .5rem;
|
31
56
|
}
|
32
57
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
justify-content: flex-end;
|
37
|
-
}
|
58
|
+
/**************************************/
|
59
|
+
/********* collection-editor **********/
|
60
|
+
/**************************************/
|
38
61
|
|
39
62
|
.collection-editor>header>.actions button {
|
40
63
|
height: 2rem !important;
|
@@ -54,12 +77,6 @@
|
|
54
77
|
width: 99%;
|
55
78
|
}
|
56
79
|
|
57
|
-
.collection-editor .actions {
|
58
|
-
width: 8rem;
|
59
|
-
text-align: right;
|
60
|
-
padding: .5rem;
|
61
|
-
}
|
62
|
-
|
63
80
|
.collection-adder {
|
64
81
|
display: flex;
|
65
82
|
}
|
@@ -97,6 +114,10 @@
|
|
97
114
|
align-items: center;
|
98
115
|
}
|
99
116
|
|
117
|
+
/**************************************/
|
118
|
+
/************ field-editor ************/
|
119
|
+
/**************************************/
|
120
|
+
|
100
121
|
.field-editor {
|
101
122
|
padding: 0;
|
102
123
|
}
|
@@ -105,6 +126,10 @@
|
|
105
126
|
width: 100%;
|
106
127
|
}
|
107
128
|
|
129
|
+
/**************************************/
|
130
|
+
/*********** function-editor **********/
|
131
|
+
/**************************************/
|
132
|
+
|
108
133
|
.function-editor {
|
109
134
|
width: 100%;
|
110
135
|
min-height: 10rem;
|
@@ -1,10 +1,9 @@
|
|
1
1
|
import React, { Fragment, useState } from 'react';
|
2
|
-
import { Button, CheckBox, DataTable, DropDown, Icon, Stack, Tab, Tabs, Text, TextField, Tree, TreeNode, TreeItem, TokenField,
|
3
|
-
import { CHECK, Content, TYPES } from './ContentType';
|
4
|
-
import './ContentEditor.css';
|
5
|
-
import { FORMATS } from './ContentType';
|
6
|
-
import { ColorField } from '../html/color';
|
2
|
+
import { Button, CheckBox, DataTable, DropDown, Icon, Stack, Tab, Tabs, Text, TextField, Tree, TreeNode, TreeItem, TokenField, Header } from '../html';
|
3
|
+
import { CHECK, Content, TYPES, FORMATS } from './ContentType';
|
7
4
|
import { DateRange } from '../html/textfield';
|
5
|
+
import { ColorField } from '../html/color';
|
6
|
+
import './ContentEditor.css';
|
8
7
|
|
9
8
|
/**
|
10
9
|
* Content Editor
|
@@ -81,33 +80,28 @@ export const TabbedContentEditor = ({ content, filter, grouped = false, onChange
|
|
81
80
|
const { title, fields } = section
|
82
81
|
return (
|
83
82
|
<section key={title}>
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
.filter(field => field.id !== 'id')
|
107
|
-
.filter(field => filter ? filter(field) : true)
|
108
|
-
.map((field) => <FieldEditor key={field.id} field={field} onChange={change} content={content} />)
|
109
|
-
}
|
110
|
-
</main>
|
83
|
+
{
|
84
|
+
grouped ?
|
85
|
+
group(section)
|
86
|
+
.map(group => {
|
87
|
+
return (
|
88
|
+
<Fragment>
|
89
|
+
{group.name.length > 0 ? <div className="group-caption">{group.name}</div> : null}
|
90
|
+
{
|
91
|
+
group.fields
|
92
|
+
.filter(field => field.id !== 'id')
|
93
|
+
.filter(field => filter ? filter(field) : true)
|
94
|
+
.map((field) => <FieldEditor key={field.id} field={field} onChange={change} content={content} />)
|
95
|
+
}
|
96
|
+
</Fragment>
|
97
|
+
)
|
98
|
+
})
|
99
|
+
:
|
100
|
+
fields
|
101
|
+
.filter(field => field.id !== 'id')
|
102
|
+
.filter(field => filter ? filter(field) : true)
|
103
|
+
.map((field) => <FieldEditor key={field.id} field={field} onChange={change} content={content} />)
|
104
|
+
}
|
111
105
|
</section>
|
112
106
|
)
|
113
107
|
})}
|
@@ -404,7 +398,9 @@ export const CollectionEditor = ({ field, value = [], onChange }) => {
|
|
404
398
|
}
|
405
399
|
}
|
406
400
|
|
407
|
-
const columns = Object.values(item)
|
401
|
+
const columns = Object.values(item)
|
402
|
+
.filter(field => field.column === true)
|
403
|
+
.map((item) => ({ ...item, onChange: change }))
|
408
404
|
columns.push({ id: 'actions', label: 'Actions' })
|
409
405
|
|
410
406
|
const rows = value.map((item, index) => ({
|
@@ -419,14 +415,15 @@ export const CollectionEditor = ({ field, value = [], onChange }) => {
|
|
419
415
|
|
420
416
|
return (
|
421
417
|
<div className='collection-editor'>
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
418
|
+
{
|
419
|
+
Renderer ?
|
420
|
+
<Renderer field={field} value={value} onRemove={remove} onChange={onChange} />
|
421
|
+
// : <DataTable {...table} editable={editable} />
|
422
|
+
: <TableEditor icon={"info"} title={label} data={value} schema={item} groupBy={"field1"} />
|
423
|
+
|
424
|
+
}
|
429
425
|
<footer>
|
426
|
+
{Feeder ? <Feeder onAdd={add} /> : null}
|
430
427
|
{Adder ? <CollectionAdder item={item} onAdd={add} /> : null}
|
431
428
|
</footer>
|
432
429
|
</div>
|
@@ -470,4 +467,113 @@ const CollectionAdder = ({ item, onAdd }) => {
|
|
470
467
|
{edit ? <DataTable {...table} editable={true} /> : <Button icon='add' label='Añadir' action={toggle} />}
|
471
468
|
</div>
|
472
469
|
)
|
473
|
-
}
|
470
|
+
}
|
471
|
+
|
472
|
+
|
473
|
+
/**
|
474
|
+
* Table Editor
|
475
|
+
*/
|
476
|
+
const TableEditor = (props) => {
|
477
|
+
|
478
|
+
const { data = [], icon, title, schema, editable, canDelete, filter, actions, className } = props
|
479
|
+
const [groupBy, setGroupBy] = useState(props.groupBy)
|
480
|
+
|
481
|
+
function changeGroup(id, value) {
|
482
|
+
setGroupBy(value)
|
483
|
+
}
|
484
|
+
|
485
|
+
async function select(row) {
|
486
|
+
if (onSelect) onSelect(row.id)
|
487
|
+
}
|
488
|
+
|
489
|
+
function renderGroupLabel(groupName) {
|
490
|
+
const grouper = schema[groupBy]
|
491
|
+
if (!groupName || !grouper) return ""
|
492
|
+
if (grouper.options) {
|
493
|
+
const options = CHECK['isFunction'](grouper.options) ? grouper.options() : grouper.options
|
494
|
+
const option = options.find(option => option.value === groupName)
|
495
|
+
return option ? option.label : groupName
|
496
|
+
} else {
|
497
|
+
return groupName
|
498
|
+
}
|
499
|
+
}
|
500
|
+
|
501
|
+
function renderGroups() {
|
502
|
+
const items = filter ? filter(data) : data
|
503
|
+
|
504
|
+
if (items.length === 0) return (
|
505
|
+
<div className='empty-message'>
|
506
|
+
<Icon icon="search_off" />
|
507
|
+
<Text>No Result Found</Text>
|
508
|
+
</div>
|
509
|
+
)
|
510
|
+
|
511
|
+
const groups = items.reduce((groups, item) => {
|
512
|
+
const groupName = item[groupBy]
|
513
|
+
const group = groups[groupName]
|
514
|
+
if (!group) groups[groupName] = []
|
515
|
+
groups[groupName].push(item)
|
516
|
+
return groups
|
517
|
+
}, {})
|
518
|
+
|
519
|
+
return Object.keys(groups).map(groupName => {
|
520
|
+
const table = {
|
521
|
+
columns: Object.values(schema)
|
522
|
+
.filter(field => field.column === true)
|
523
|
+
.map(field => {
|
524
|
+
let options = field.options;
|
525
|
+
if (options && typeof (options) == 'function') {
|
526
|
+
options = options()
|
527
|
+
}
|
528
|
+
return {
|
529
|
+
id: field.id,
|
530
|
+
label: field.label,
|
531
|
+
type: field.type,
|
532
|
+
format: field.format,
|
533
|
+
item: field.item ? field.item : [],
|
534
|
+
onChange: field.id === "checked" ? checkOne : field.editable ? change : null, /* checked has it´s own handler */
|
535
|
+
options
|
536
|
+
}
|
537
|
+
}),
|
538
|
+
rows: groups[groupName]
|
539
|
+
.map(item => {
|
540
|
+
item.actions = actions ? actions.map(action => {
|
541
|
+
return action.filter ?
|
542
|
+
action.filter(item) ? <Icon icon={action.icon} clickable size="small" action={() => run(action, item)} /> : null
|
543
|
+
: <Icon icon={action.icon} clickable size="small" action={() => run(action, item)} />
|
544
|
+
}) : []
|
545
|
+
if (canDelete) item.actions.push(<Icon icon="delete" size="small" clickable action={() => remove(item.id)} />)
|
546
|
+
return item
|
547
|
+
})
|
548
|
+
}
|
549
|
+
table.columns.push({ id: "actions" })
|
550
|
+
const groupSize = groups[groupName].length
|
551
|
+
const title = <span><span className="size">{groupSize}</span>{renderGroupLabel(groupName)}</span>
|
552
|
+
return (
|
553
|
+
<Fragment key={groupName}>
|
554
|
+
<Header title={title} >
|
555
|
+
<span className="size">{groupSize}</span>
|
556
|
+
</Header>
|
557
|
+
<DataTable {...table} onRowSelection={select} editable={editable} className={className} />
|
558
|
+
</Fragment>
|
559
|
+
)
|
560
|
+
})
|
561
|
+
}
|
562
|
+
|
563
|
+
function buildGroupOptions(schema) {
|
564
|
+
return Object.values(schema)
|
565
|
+
.filter(field => field.grouper === true)
|
566
|
+
.map(field => ({ label: field.label, value: field.id }))
|
567
|
+
}
|
568
|
+
|
569
|
+
return (
|
570
|
+
<Fragment>
|
571
|
+
<Header icon={icon} title={<Text>{title}</Text>}>
|
572
|
+
<DropDown id="groupBy" label="Agrupar Por" value={groupBy} options={buildGroupOptions(schema)} onChange={changeGroup} />
|
573
|
+
</Header>
|
574
|
+
<main className="table-editor">
|
575
|
+
{renderGroups()}
|
576
|
+
</main>
|
577
|
+
</Fragment>
|
578
|
+
)
|
579
|
+
}
|
package/src/domain/TablePage.js
CHANGED
package/src/site/site.test.js
CHANGED
@@ -192,16 +192,14 @@ const Page4 = (props) => {
|
|
192
192
|
const Page5 = (props) => {
|
193
193
|
|
194
194
|
const ENTITYTYPE = {
|
195
|
-
name : { id: "name" , section: "", type: TYPES.STRING, format: FORMATS.NONE , required: true, tab: false, grouper: true , column: true , filter: true , like: true, label: "Name"
|
196
|
-
field1: { id: "field1", section: "
|
197
|
-
field2: { id: "field2", section: "
|
198
|
-
field3: { id: "field3", section: "
|
199
|
-
|
195
|
+
name : { id: "name" , section: "", type: TYPES.STRING, format: FORMATS.NONE , required: true, tab: false, grouper: true , column: true , filter: true , like: true, label: "Name" },
|
196
|
+
field1: { id: "field1", section: "", type: TYPES.STRING, format: FORMATS.NONE , required: true, tab: false, grouper: true , column: false, filter: true , label: "E field1" },
|
197
|
+
field2: { id: "field2", section: "", type: TYPES.STRING, format: FORMATS.NONE , required: true, tab: false, grouper: true , column: false, filter: true , label: "E field2" },
|
198
|
+
field3: { id: "field3", section: "", type: TYPES.STRING, format: FORMATS.NONE , required: true, tab: false, grouper: true , column: true , filter: true , label: "E field3" },
|
200
199
|
}
|
201
200
|
|
202
201
|
const schema = {
|
203
|
-
|
204
|
-
|
202
|
+
field6: { id: "field6", section: "C", type: TYPES.ARRAY , item: ENTITYTYPE, label: "Collection 100" },
|
205
203
|
name : { id: "name" , section: "A", type: TYPES.STRING, format: FORMATS.NONE , required: true, tab: false, grouper: true , column: true , filter: true , like: true, label: "Name" },
|
206
204
|
state : { id: "state" , section: "A", type: TYPES.STRING, format: FORMATS.NONE , required: true, tab: true , grouper: true , column: true , filter: false , label: "State" , options: [
|
207
205
|
{ label: "Pendiente", value: "NOT_CLASSIFIED" },
|
@@ -211,12 +209,17 @@ const Page5 = (props) => {
|
|
211
209
|
field2: { id: "field2", section: "B", type: TYPES.STRING , format: FORMATS.NONE , required: true, tab: false, grouper: true , column: true , filter: true , label: "field2" },
|
212
210
|
field4: { id: "field4", section: "B", type: TYPES.STRING , format: FORMATS.COLOR, required: true, tab: false, grouper: true , column: true , filter: true , label: "Color" },
|
213
211
|
field5: { id: "field5", section: "B", type: TYPES.ENTITY, item: ENTITYTYPE, format: FORMATS.NONE , editable: true, tab: false, grouper: false, column: true , filter: true , like: false, label: "Entity5"},
|
214
|
-
|
212
|
+
id : { id: "id", type: TYPES.STRING },
|
215
213
|
}
|
216
214
|
|
217
215
|
return (
|
218
216
|
<Fragment>
|
219
|
-
<CollectionPage
|
217
|
+
<CollectionPage
|
218
|
+
title="Referencias"
|
219
|
+
schema={schema} host="http://localhost:3000" url="/references" fetching={true} // resource
|
220
|
+
searchBy={["field1"]} levels={["color"]} // menu
|
221
|
+
editor="TABBED" canAdd={true} // editor
|
222
|
+
/>
|
220
223
|
</Fragment>
|
221
224
|
)
|
222
225
|
}
|