@andersonalmeidax0/webcomponents 0.1.0
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/README.md +50 -0
- package/XButton.jsx +56 -0
- package/XCheckbox.jsx +22 -0
- package/XDateSelect.jsx +22 -0
- package/XInput.jsx +140 -0
- package/XSelect.jsx +59 -0
- package/XTextArea.jsx +31 -0
- package/jzcomponents/ErrorCard.jsx +18 -0
- package/jzcomponents/ErrorCardAuth.jsx +15 -0
- package/jzcomponents/Errors.js +41 -0
- package/jzcomponents/JZEditComponent.jsx +173 -0
- package/jzcomponents/JZInPlaceListComponent.jsx +95 -0
- package/jzcomponents/JZListComponent.jsx +305 -0
- package/jzcomponents/XFormEdit.jsx +105 -0
- package/jzcomponents/XTableRead.jsx +271 -0
- package/package.json +19 -0
- package/releasenotes.txt +37 -0
package/README.md
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# webcomponents
|
|
2
|
+
React HTML controls, with convenience functions and events\
|
|
3
|
+
1 XButton: button (WHY COMPONENT?)
|
|
4
|
+
2 XInput: with numeric validation (shows error), transale "," to "." (store internally with different format) (WHY COMPONENT?)
|
|
5
|
+
3 XtextArea: (WHY COMPONENT?)
|
|
6
|
+
4 XSelect: input array key / value
|
|
7
|
+
5 XCheckbox: true/false
|
|
8
|
+
6 XDateSelect: (WHY COMPONENT?)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# how to use:
|
|
12
|
+
1. Create index.html
|
|
13
|
+
2. Create App WebComponents
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
## Example
|
|
18
|
+
```
|
|
19
|
+
<XButton id="bt1" type="button" disabled={false} label="Btn1" onClick={}/>
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
### Example "routes": labels, links and components for navigation
|
|
23
|
+
```
|
|
24
|
+
var routes = [
|
|
25
|
+
{"route":"/page/page1","label":"PageNotes", "component":Page1},
|
|
26
|
+
{"route":"/page/page2","label":"PageNotes2", "component":Page2},
|
|
27
|
+
{"route":"/page/page3","label":"PageTestComps", "component":PageTestComps},
|
|
28
|
+
]
|
|
29
|
+
```
|
|
30
|
+
### Example appContext
|
|
31
|
+
```
|
|
32
|
+
let kc = {tokenParsed:{email:"noLogon@nologon"}, logout(){alert("Fake logout")}}
|
|
33
|
+
class AppContext {
|
|
34
|
+
constructor(kc){
|
|
35
|
+
this.kc=kc;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
### Example PageComponent
|
|
40
|
+
```
|
|
41
|
+
class Page1 extends React.Component{
|
|
42
|
+
constructor(props){
|
|
43
|
+
super(props);
|
|
44
|
+
this.state ={}
|
|
45
|
+
}
|
|
46
|
+
render() {
|
|
47
|
+
return ( <React.Fragment>...)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
package/XButton.jsx
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
var xstyles = {
|
|
5
|
+
button: function() { return "primary shadowed small"}
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
/* ************************************************** */
|
|
10
|
+
// Simple Button => se tiver icon prop, renderiza como icon
|
|
11
|
+
// PROP: onClick, icon, label
|
|
12
|
+
/* ************************************************** */
|
|
13
|
+
class XButton extends React.Component {
|
|
14
|
+
constructor(props) {
|
|
15
|
+
super(props)
|
|
16
|
+
this.evt = this.evt.bind(this);
|
|
17
|
+
this.evtFile = this.evtFile.bind(this);
|
|
18
|
+
}
|
|
19
|
+
evt(ev) {
|
|
20
|
+
ev.preventDefault();
|
|
21
|
+
this.props.onClick(ev);
|
|
22
|
+
}
|
|
23
|
+
evtFile(ev) {
|
|
24
|
+
ev.preventDefault();
|
|
25
|
+
this.props.onClick(ev);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
render() {
|
|
29
|
+
var t=this.props.attachFile?'file':'button';
|
|
30
|
+
if(this.props.attachFile)
|
|
31
|
+
return (
|
|
32
|
+
<label onChange={this.evtFile} xclassName='tile bg--lightblue fg--white btn--raised ' xstyle={{lineHeight:20,xwidth:20,display:'inline-block'}} htmlFor="formId">
|
|
33
|
+
<input name="" type="file" id="formId" hidden />
|
|
34
|
+
<i className={'fa fa-paperclip'} />
|
|
35
|
+
</label>
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
if(this.props.icon){
|
|
39
|
+
if(this.props.textlabel==null)
|
|
40
|
+
return (
|
|
41
|
+
<button id={this.props.id} type={t} className="btn--raised tooltip" data-text={this.props.label} onClick={this.props.attachFile?this.evtFile:this.evt} disabled={this.props.disabled}> <i className={this.props.icon} ></i> </button>
|
|
42
|
+
)
|
|
43
|
+
else
|
|
44
|
+
return (
|
|
45
|
+
<button id={this.props.id} type={t} className="btn--raised tooltip" data-text={this.props.label} onClick={this.props.attachFile?this.evtFile:this.evt} disabled={this.props.disabled}>{this.props.textlabel} </button>
|
|
46
|
+
)
|
|
47
|
+
}
|
|
48
|
+
else
|
|
49
|
+
return (
|
|
50
|
+
<button id={this.props.id} className={xstyles.button()} onClick={this.evt} disabled={this.props.disabled} > {this.props.label} </button>
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
export {XButton};
|
package/XCheckbox.jsx
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
class XCheckbox extends React.Component {
|
|
4
|
+
constructor(props) {
|
|
5
|
+
super(props);
|
|
6
|
+
this.state = { isChecked: this.props.defaultValue, };
|
|
7
|
+
}
|
|
8
|
+
toggleChange = (ev) => {
|
|
9
|
+
this.setState({ isChecked: !this.state.isChecked, });
|
|
10
|
+
this.props.onChange(this.state.isChecked);
|
|
11
|
+
//this.props.onChange(ev.target.value);
|
|
12
|
+
};
|
|
13
|
+
render() {
|
|
14
|
+
return (
|
|
15
|
+
<input type="checkbox" disabled={this.props.disabled}
|
|
16
|
+
defaultChecked={this.props.defaultValue}
|
|
17
|
+
onChange={this.toggleChange} />
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export {XCheckbox};
|
package/XDateSelect.jsx
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
class XDateSelect extends React.Component {
|
|
4
|
+
constructor(props) {
|
|
5
|
+
super(props);
|
|
6
|
+
//this.state = { value: this.props.value, };
|
|
7
|
+
}
|
|
8
|
+
toggleChange = (ev) => {
|
|
9
|
+
//this.setState({value: v.target.value});
|
|
10
|
+
//this.props.onChange(this.state.value);
|
|
11
|
+
this.props.onChange(ev.target.value);
|
|
12
|
+
};
|
|
13
|
+
render() {
|
|
14
|
+
return (
|
|
15
|
+
<input type="date" disabled={this.props.disabled}
|
|
16
|
+
value={this.props.defaultValue}
|
|
17
|
+
onChange={this.toggleChange} />
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export {XDateSelect};
|
package/XInput.jsx
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
var xstyles = {
|
|
5
|
+
button: function() { return "primary shadowed small"}
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function isNumeric(n) {
|
|
9
|
+
return !isNaN(n);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function nv2m(n){return NumberView2Model(n)}
|
|
13
|
+
function nm2v(n){return NumberModel2View(n)}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* View 2 model => number digitado com fmt para numero interno
|
|
17
|
+
*/
|
|
18
|
+
function NumberView2Model(n) {
|
|
19
|
+
var nStr = n+'';
|
|
20
|
+
nStr = nStr.replaceAll('.','@');
|
|
21
|
+
nStr = nStr.replaceAll(',','.');
|
|
22
|
+
nStr = nStr.replaceAll('@',',');
|
|
23
|
+
var nOk = nStr;// Number.parseFloat(nStr);
|
|
24
|
+
return nOk;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Mode 2 view => number interno para fmt
|
|
28
|
+
*/
|
|
29
|
+
function NumberModel2View(n) {
|
|
30
|
+
var nStr = n+'';
|
|
31
|
+
//nStr = nStr.replace('.','');
|
|
32
|
+
nStr = nStr.replaceAll('.','@');
|
|
33
|
+
nStr = nStr.replaceAll(',','.');
|
|
34
|
+
nStr = nStr.replaceAll('@',',');
|
|
35
|
+
var nOk = (nStr);
|
|
36
|
+
return nOk;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
/** *********************************************************
|
|
42
|
+
* XInputExternal (sem estado)
|
|
43
|
+
* PROP: value,
|
|
44
|
+
* PROP onXG, ==> altera sem mudar "." para ","
|
|
45
|
+
* PROP onChangeNew => altera SIM "." para "," fazendo "view2model"
|
|
46
|
+
* PROP: context: o interceptor passa para o onChangeNew, ctx é opcional
|
|
47
|
+
* PROP:
|
|
48
|
+
* cada evento de mudanca, chama o metodo onXG com valor
|
|
49
|
+
* cabe ao chamador atualizar o estado
|
|
50
|
+
* localvalue: é o
|
|
51
|
+
* onKeypress
|
|
52
|
+
* ********************************************************* */
|
|
53
|
+
class XInputExternal extends React.Component {
|
|
54
|
+
constructor(props) {
|
|
55
|
+
super(props);
|
|
56
|
+
var valid=true;
|
|
57
|
+
var localValue=this.props.value;
|
|
58
|
+
console.log('XInputExternal.ctor localvalue:['+localValue+']');
|
|
59
|
+
if(this.props.type==='number') {
|
|
60
|
+
valid= isNumeric(this.props.value);
|
|
61
|
+
localValue=nm2v(this.props.value);
|
|
62
|
+
}
|
|
63
|
+
this.state={valid:valid,localValue:localValue}
|
|
64
|
+
}
|
|
65
|
+
style1 = (valid) => {
|
|
66
|
+
//return {all: 'unset', border: '2px solid red;', padding:'2px 2px', margin: '2px 0;', xboxSizing: 'border-box', width:'100px',borderBottom:'1px red',borderStyle:'1px red',backgroundSize:'100px',background:'rgb(202,202,255)'};
|
|
67
|
+
//return {all: 'unset', width:(this.props.width?this.props.width:100)+'px', boxSizing: 'border-box', border: '1px solid #a0a0a0', padding:'4px 2px', margin: '4px 2px',background:'rgb(255,255,255)'};
|
|
68
|
+
//return {all: 'unset', padding:'2px 2px',margin: '2px 0', borderWidth: '1px', borderStyle: 'solid', borderColor: valid?'#aaa':'#f00', /*borderBottom: '2px solid red',*/height:'25px', width:(this.props.width?this.props.width:100)+'px',background:'rgb(242,242,242)',margin: '1px 1px'}//, boxSizing: 'border-box', border: '1px solid #a0a0a0', padding:'4px 2px', margin: '4px 2px',background:'rgb(255,255,255)'};
|
|
69
|
+
return { width:(this.props.width?this.props.width:150)+'px'}
|
|
70
|
+
//return {};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
onChangeCheckInterceptor = (event) => {
|
|
74
|
+
var value=event.target.value;
|
|
75
|
+
//var item=this.props.context.item;
|
|
76
|
+
//var v=this.props.context.v;
|
|
77
|
+
//console.log('********\nu.Input3.value:'+value);
|
|
78
|
+
//console.log('u.Input3.p.type:'+this.props.type);
|
|
79
|
+
//console.log('u.Input3.p.stvalid:'+this.state.valid);
|
|
80
|
+
//console.log('u.Input3.p.item:'+item+" v:"+v);
|
|
81
|
+
if(this.props.type==='number') {
|
|
82
|
+
var testValid= isNumeric(nv2m(value));
|
|
83
|
+
if(this.props.onXG)this.props.onXG(event);
|
|
84
|
+
if(this.props.onChangeNew){
|
|
85
|
+
//troca formato
|
|
86
|
+
var modelValue=nv2m(value);
|
|
87
|
+
this.props.onChangeNew(modelValue,this.props.context);
|
|
88
|
+
this.setState({valid:testValid,localValue:modelValue});
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
this.setState({valid:testValid,localValue:value});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
else{
|
|
95
|
+
if(this.props.onChangeNew)this.props.onChangeNew(value,this.props.context);
|
|
96
|
+
if(this.props.onXG)this.props.onXG(event);
|
|
97
|
+
this.setState({localValue:value});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
componentDidMount = () => {
|
|
102
|
+
console.log('XInputExternal.didmount localvalue:['+this.state.localValue+']');
|
|
103
|
+
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
render() {
|
|
107
|
+
//var type=this.props.type?this.props.type:"text";
|
|
108
|
+
//var pattern=this.props.pattern=='number'?"[0-9]*":"[A-Za-z0-9]+";
|
|
109
|
+
//var w=150;
|
|
110
|
+
//if(this.props.width)
|
|
111
|
+
// w=this.props.width;
|
|
112
|
+
//console.log('XInputExternal.didmount RENDER:['+this.state.localValue+']');
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
if(this.props.cellStyle)
|
|
116
|
+
return (
|
|
117
|
+
<React.Fragment>
|
|
118
|
+
<input id={this.props.id} style={this.style1(this.state.valid)} readOnly={this.props.readOnly}
|
|
119
|
+
defaultValue={this.state.localValue} value={this.state.localValue} onChange={this.onChangeCheckInterceptor}
|
|
120
|
+
onKeyDown ={(e)=>{if (e.keyCode === 13){console.log('Xint.onKEnter');this.props.onEnterKey();this.setState({localValue:''}); }}} />
|
|
121
|
+
{(this.state.valid)?'':'(invalid)'}
|
|
122
|
+
</React.Fragment>
|
|
123
|
+
); else
|
|
124
|
+
return (
|
|
125
|
+
<React.Fragment>
|
|
126
|
+
<label> {this.props.label} </label>
|
|
127
|
+
<input id={this.props.id} readOnly={this.props.readOnly}
|
|
128
|
+
style={this.style1(this.state.valid)}
|
|
129
|
+
className="card"
|
|
130
|
+
defaultValue={this.state.localValue} onChange={this.onChangeCheckInterceptor} />
|
|
131
|
+
|
|
132
|
+
{(this.state.valid)?'':'(invalid)'}<br/>
|
|
133
|
+
</React.Fragment>
|
|
134
|
+
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
export {XInputExternal};
|
package/XSelect.jsx
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
var xstyles = {
|
|
5
|
+
button: function() { return "primary shadowed small"}
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const TEST_UI_AUX=true;
|
|
9
|
+
|
|
10
|
+
/** *********************************************************
|
|
11
|
+
* XSelect3 ==> mandem o estado local, mas quando muda, chama evento externo.
|
|
12
|
+
* PROP: value (é initial value), onChange,list
|
|
13
|
+
* ********************************************************* */
|
|
14
|
+
class XSelect3 extends React.Component {
|
|
15
|
+
constructor(props) {
|
|
16
|
+
super(props)
|
|
17
|
+
this.evt = this.evt.bind(this);
|
|
18
|
+
this.state = {value: this.props.value};
|
|
19
|
+
}
|
|
20
|
+
evt(ev)
|
|
21
|
+
{
|
|
22
|
+
console.log('Xselect3.evt value:'+ev.target.value);
|
|
23
|
+
this.setState({value: ev.target.value})
|
|
24
|
+
this.props.onChange(ev);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
render() {
|
|
28
|
+
//console.log(JSON.stringify(this.props.list));
|
|
29
|
+
if(Array.isArray(this.props.list))
|
|
30
|
+
if(this.props.isFilter)
|
|
31
|
+
return (
|
|
32
|
+
<React.Fragment>
|
|
33
|
+
<select id={this.props.id} style={{width:(this.props.width?this.props.width:300)+'px'}} disabled={this.props.disabled} onChange={this.evt} value={this.state.value} >
|
|
34
|
+
{this.props.list.map(function(v){
|
|
35
|
+
return <option key={v.id} value={v.id}>{v.descr}</option>;
|
|
36
|
+
})}
|
|
37
|
+
</select>
|
|
38
|
+
</React.Fragment>
|
|
39
|
+
)
|
|
40
|
+
else
|
|
41
|
+
return (
|
|
42
|
+
<div >
|
|
43
|
+
<span id={'Last_'+this.props.id} style={{visibility: 'hidden'}} >{TEST_UI_AUX&&this.props.list[this.props.list.length-1].id}</span>
|
|
44
|
+
<select id={this.props.id} style={{width:(this.props.width?this.props.width:300)+'px'}} disabled={this.props.disabled} onChange={this.evt} value={this.state.value} >
|
|
45
|
+
{this.props.list.map(function(v){
|
|
46
|
+
return <option key={v.id} value={v.id}>{v.descr}</option>;
|
|
47
|
+
})}
|
|
48
|
+
</select>
|
|
49
|
+
</div>
|
|
50
|
+
)
|
|
51
|
+
else
|
|
52
|
+
return (
|
|
53
|
+
<div>LOV: INVALID LIST:{this.props.list}</div>
|
|
54
|
+
)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
export {XSelect3};
|
package/XTextArea.jsx
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
var xstyles = {
|
|
5
|
+
button: function() { return "primary shadowed small"}
|
|
6
|
+
}
|
|
7
|
+
/** *********************************************************
|
|
8
|
+
* XTextArea (sem estado)
|
|
9
|
+
* PROP: value, onXG
|
|
10
|
+
* cada evento de mudanca, chama o metodo onXG com valor
|
|
11
|
+
* cabe ao chamador atualizar o estado
|
|
12
|
+
* ********************************************************* */
|
|
13
|
+
class XTextArea extends React.Component {
|
|
14
|
+
constructor(props) {
|
|
15
|
+
super(props);
|
|
16
|
+
}
|
|
17
|
+
/*
|
|
18
|
+
style1 = () => {
|
|
19
|
+
//return {all: 'unset', border: '2px solid red;', padding:'2px 2px', margin: '2px 0;', xboxSizing: 'border-box', width:'100px',borderBottom:'1px red',borderStyle:'1px red',backgroundSize:'100px',background:'rgb(202,202,255)'};
|
|
20
|
+
//return {all: 'unset', width:(this.props.width?this.props.width:100)+'px', boxSizing: 'border-box', border: '1px solid #a0a0a0', padding:'4px 2px', margin: '4px 2px',background:'rgb(255,255,255)'};
|
|
21
|
+
return {all: 'unset', width:(this.props.width?this.props.width:100)+'px',background:'rgb(242,242,242)',margin: '4px 2px'}//, boxSizing: 'border-box', border: '1px solid #a0a0a0', padding:'4px 2px', margin: '4px 2px',background:'rgb(255,255,255)'};
|
|
22
|
+
}
|
|
23
|
+
*/
|
|
24
|
+
render() {
|
|
25
|
+
return (
|
|
26
|
+
<textarea id={this.props.id} onChange={this.props.onXG} defaultValue={this.props.value} ></textarea>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export {XTextArea};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
export class ErrorCard extends React.Component {
|
|
4
|
+
render() {
|
|
5
|
+
return (
|
|
6
|
+
<div className="g--10 m--2">
|
|
7
|
+
<h3>Erro de sistema inesperado. Entre em contato com metalmarket@gmail.com e informe a mensagem abaixo:</h3>
|
|
8
|
+
<h4>{JSON.stringify(this.props.myException)}</h4>
|
|
9
|
+
<h4>{JSON.stringify(this.props.myException.stack)}</h4>
|
|
10
|
+
<div className="card g--10 m--0">
|
|
11
|
+
<div> <div className=""> <p> <a href='/loginExternal'>Entrar novamente.</a> </p> </div> <span> </span>
|
|
12
|
+
</div>
|
|
13
|
+
</div>
|
|
14
|
+
</div>
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
export class ErrorCardAuth extends React.Component {
|
|
4
|
+
render() {
|
|
5
|
+
return (
|
|
6
|
+
<div className="g--10 m--2">
|
|
7
|
+
<h3>Sessão expirada. </h3>
|
|
8
|
+
<div className="card g--10 m--0">
|
|
9
|
+
<div> <div className=""> <p> <a href='/loginExternal'>Entrar novamente.</a> </p> </div> <span> </span>
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
12
|
+
</div>
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* ************************************************** */
|
|
3
|
+
/* ************************************************** */
|
|
4
|
+
class PlatAPIError extends Error {
|
|
5
|
+
constructor(message, type) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = "PlatAPIError";
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
/* ************************************************** */
|
|
11
|
+
/* ************************************************** */
|
|
12
|
+
class PlatAPIReturnCodeError extends Error {
|
|
13
|
+
constructor(message, rc) {
|
|
14
|
+
super(message);
|
|
15
|
+
this.name = "PlatAPIReturnCodeError";
|
|
16
|
+
this.rc = rc;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/* ************************************************** */
|
|
20
|
+
/* ************************************************** */
|
|
21
|
+
class PlatAPIAuthError extends Error {
|
|
22
|
+
constructor(message, rc) { super(message); this.name = "PlatAPIAuthError"; this.rc = rc;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/* ************************************************** */
|
|
26
|
+
class PlatAPIDBNotFound extends Error {
|
|
27
|
+
constructor(message) { super(message); this.name = "PlatAPIDBNotFound"; }
|
|
28
|
+
}
|
|
29
|
+
/* ************************************************** */
|
|
30
|
+
class PlatAPIDBIntegrityConstraint extends Error {
|
|
31
|
+
constructor(message) { super(message); this.name = "PlatAPIDBIntegrityConstraint"; }
|
|
32
|
+
}
|
|
33
|
+
/* ************************************************** */
|
|
34
|
+
class PlatAPIForbidden extends Error {
|
|
35
|
+
constructor(message) { super(message); this.name = "PlatAPIForbidden"; }
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
//exports.PlatAPIDBNotFound = PlatAPIDBNotFound;
|
|
40
|
+
|
|
41
|
+
export {PlatAPIError,PlatAPIReturnCodeError,PlatAPIAuthError,PlatAPIDBNotFound,PlatAPIDBIntegrityConstraint,PlatAPIForbidden};
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import {XButton} from "../XButton.jsx"
|
|
3
|
+
import {XInputExternal} from "../XInput.jsx"
|
|
4
|
+
import {XSelect3} from "../XSelect"
|
|
5
|
+
import {XTextArea} from "../XTextArea"
|
|
6
|
+
import {XCheckbox} from "../XCheckbox.jsx"
|
|
7
|
+
import {XDateSelect} from "../XDateSelect.jsx"
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
import { XTableRead } from "./XTableRead.jsx";
|
|
13
|
+
import { XFormEdit } from "./XFormEdit.jsx";
|
|
14
|
+
import { JZInPlaceListComponent } from "./JZInPlaceListComponent.jsx";
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
import {PlatAPIError,PlatAPIReturnCodeError,PlatAPIAuthError,PlatAPIDBNotFound,PlatAPIDBIntegrityConstraint,PlatAPIForbidden} from "./Errors.js";
|
|
18
|
+
import { ErrorCard } from "./ErrorCard";
|
|
19
|
+
import { ErrorCardAuth } from "./ErrorCardAuth";
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
/*
|
|
23
|
+
import { useNavigate } from "react-router";
|
|
24
|
+
export const withRouter = (Component) => {
|
|
25
|
+
const Wrapper = (props) => {
|
|
26
|
+
const history = useNavigate();
|
|
27
|
+
return <Component history={history} {...props} />;
|
|
28
|
+
};
|
|
29
|
+
return Wrapper;
|
|
30
|
+
};
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
const DEBUG_ID=false;
|
|
35
|
+
const DEBUG_ID2=DEBUG_ID;
|
|
36
|
+
const DEBUG_ID3=false;
|
|
37
|
+
const DEBUGAPICALL_UTIL=false;
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
/* ************************************************** */
|
|
44
|
+
// Formulario de EDIT ===> Usa XFormEdit !!!!!!!!!!!!!
|
|
45
|
+
// api => api de BP
|
|
46
|
+
// editConfig => config de list
|
|
47
|
+
// mode => modo: 'I' ou 'U'
|
|
48
|
+
/* ************************************************** */
|
|
49
|
+
class JZEditComponent extends React.Component {
|
|
50
|
+
constructor() {
|
|
51
|
+
super()
|
|
52
|
+
this.state = {
|
|
53
|
+
currObj: null,
|
|
54
|
+
message:"",
|
|
55
|
+
notFound:false,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/* ******** ####################### ********** */
|
|
59
|
+
async componentDidMount() {
|
|
60
|
+
var obj=null;
|
|
61
|
+
|
|
62
|
+
//alert("jzedit.didmount");
|
|
63
|
+
//console.log("jzedit.didmount")
|
|
64
|
+
if(this.props.mode=='I'){
|
|
65
|
+
var mobj=this.props.api.newVO();
|
|
66
|
+
obj = this.props.api.model2view(mobj);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
try{
|
|
70
|
+
//alert("jzedit.didmount.find");
|
|
71
|
+
//console.log("jzedit.didmount.find");
|
|
72
|
+
var mobj=await this.props.api.findByPK(this.props.editKey,this.props.apiContext);
|
|
73
|
+
obj = this.props.api.model2view(mobj);
|
|
74
|
+
if(DEBUGAPICALL_UTIL)alert(JSON.stringify(obj,null,2));
|
|
75
|
+
} catch(error){
|
|
76
|
+
if(error instanceof PlatAPIDBNotFound) {
|
|
77
|
+
obj={};
|
|
78
|
+
this.setState({currObj:obj,notFound:true});
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if(
|
|
82
|
+
error instanceof PlatAPIDBIntegrityConstraint ||
|
|
83
|
+
error instanceof PlatAPIAuthError ||
|
|
84
|
+
error instanceof PlatAPIReturnCodeError ||
|
|
85
|
+
error instanceof PlatAPIError)
|
|
86
|
+
this.setState({myException:error});
|
|
87
|
+
else
|
|
88
|
+
this.setState({myException:error});
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
this.setState({currObj:obj});
|
|
93
|
+
}
|
|
94
|
+
/* ******** ####################### ********** */
|
|
95
|
+
evtSubmit = async () => {
|
|
96
|
+
try{
|
|
97
|
+
if(this.props.mode=='I') {
|
|
98
|
+
var obj=this.props.api.view2model(this.state.currObj);
|
|
99
|
+
this.props.api.validate(obj);
|
|
100
|
+
var r =await this.props.api.create(obj,this.props.apiContext);
|
|
101
|
+
if(DEBUGAPICALL_UTIL)alert(JSON.stringify(r,null,2));
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
//mode=='U'
|
|
105
|
+
var obj=this.props.api.view2model(this.state.currObj);
|
|
106
|
+
this.props.api.validate(obj);
|
|
107
|
+
var r= await this.props.api.update(obj,this.props.apiContext)
|
|
108
|
+
if(DEBUGAPICALL_UTIL)alert(JSON.stringify(r,null,2));
|
|
109
|
+
}
|
|
110
|
+
this.props.onClose();
|
|
111
|
+
}catch(error) {
|
|
112
|
+
if(error instanceof PlatAPIReturnCodeError ||
|
|
113
|
+
error instanceof PlatAPIDBIntegrityConstraint ||
|
|
114
|
+
error instanceof PlatAPIAuthError ||
|
|
115
|
+
error instanceof PlatAPIError)
|
|
116
|
+
this.setState({myException:error});
|
|
117
|
+
else
|
|
118
|
+
if(error instanceof RangeError)
|
|
119
|
+
this.setState({message:error.message});
|
|
120
|
+
else
|
|
121
|
+
this.setState({myException:error});
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/* ******** ####################### ********** */
|
|
125
|
+
evtCancel = () => {
|
|
126
|
+
this.props.onClose();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/* ******** ####################### ********** */
|
|
130
|
+
render() {
|
|
131
|
+
if (this.state.myException) {
|
|
132
|
+
if(this.state.myException instanceof PlatAPIAuthError)
|
|
133
|
+
return (<ErrorCardAuth/>)
|
|
134
|
+
else
|
|
135
|
+
return (<ErrorCard myException={this.state.myException}/>)
|
|
136
|
+
} //if
|
|
137
|
+
|
|
138
|
+
if(this.state.notFound)
|
|
139
|
+
return (
|
|
140
|
+
<React.Fragment>
|
|
141
|
+
<h5 style={{color:'red'}} >Item não encontrado</h5>
|
|
142
|
+
{<XButton label='Voltar' onClick={this.evtCancel}/>}<span> </span>
|
|
143
|
+
</React.Fragment>
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
if(this.state.currObj)
|
|
147
|
+
return (
|
|
148
|
+
<React.Fragment>
|
|
149
|
+
<fieldset class="vertical">
|
|
150
|
+
<XFormEdit id={this.props._id} metadata={this.props.editConfig} textlabels={true} formData={this.state.currObj} />
|
|
151
|
+
</fieldset>
|
|
152
|
+
|
|
153
|
+
<div> </div>
|
|
154
|
+
<fieldset class="actions">
|
|
155
|
+
{this.props.editConfig.hasSaveFn&&this.props.editConfig.hasSaveFn(this.state.currObj)&&<React.Fragment>{DEBUG_ID&&'Save_'+this.props._id}<XButton label='Salvar' id={'Save_'+this.props._id} onClick={this.evtSubmit}/></React.Fragment>}<span> </span>
|
|
156
|
+
{this.props.editConfig.hasBackFn&&this.props.editConfig.hasBackFn(this.state.currObj)&&<XButton label='Voltar' onClick={this.evtCancel}/>}<span> </span>
|
|
157
|
+
{this.props.editConfig.extraButtons&&this.props.editConfig.extraButtons.map((v,i)=> {return <React.Fragment key={i} >{DEBUG_ID&&v.btnLabel+'_'+this.props._id}<XButton id={v.btnLabel+'_'+this.props._id} label={v.btnLabel} onClick={()=>v.evtBtn(this.state.currObj)}/><span> </span></React.Fragment> } )}
|
|
158
|
+
</fieldset>
|
|
159
|
+
<h5 style={{color:'red'}} >{this.state.message}</h5>
|
|
160
|
+
|
|
161
|
+
</React.Fragment>
|
|
162
|
+
)
|
|
163
|
+
else
|
|
164
|
+
return (<p className="color--blue">Carregando formulario...</p>);
|
|
165
|
+
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
export {JZEditComponent};
|