jrs-react 1.2.2 → 1.2.4

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.
@@ -0,0 +1,423 @@
1
+ import styled from "styled-components";
2
+ import React from "react";
3
+ import { flexType, po } from "../JRUtils";
4
+ import JRFrame from "../JRFrame/JRFrame";
5
+ import {StyleJRFields} from "./StyleJRFields"
6
+
7
+ function checkMap(_name,inputValue,mapValue,nameList){
8
+ if(nameList.length) {
9
+ const name=nameList.shift()
10
+ if(typeof mapValue[name]!='object' ){
11
+ mapValue[name]={}
12
+ }
13
+ checkMap(_name,inputValue,mapValue[name],nameList)
14
+ }else{
15
+ mapValue[_name]=inputValue
16
+ }
17
+ }
18
+
19
+ const StyledGridFrame = styled.div`
20
+ overflow: auto;
21
+ flex:1;
22
+ `
23
+
24
+ const StyledGrid = styled.div`
25
+ display: grid;
26
+ grid: ${({ grid, cols, children }) =>
27
+ grid
28
+ ? grid
29
+ : `auto / ${Array(cols ?? 1)
30
+ .fill()
31
+ .map(() => "1fr")
32
+ .join(" ")}`};
33
+
34
+ gap: ${({ $gap }) => $gap};
35
+ `
36
+ const StyledFooter = styled.div`
37
+ `
38
+
39
+ const StyledColumn=styled.div`
40
+ flex:1;
41
+ display: grid;
42
+
43
+ ${({$layout,$labelWidth,$hasLabel,$valueWidth})=>{
44
+ if($layout=='v'){
45
+ return `grid: auto 1fr / 1fr;`
46
+ }else{
47
+ return `grid: 1fr / ${$hasLabel?$labelWidth:''} ${$valueWidth};`
48
+ }
49
+ }}
50
+ `
51
+ const StyledColumnLabel=styled.label`
52
+ ${({$layout})=>{
53
+ if($layout=='v'){
54
+ return `text-align: start;`
55
+ }else{
56
+ return `text-align: end;`
57
+ }
58
+ }}
59
+
60
+ ${({$required})=>{
61
+ if($required!==undefined && $required)
62
+ return `
63
+ &:not(:empty)::before{
64
+ padding-right:4px;
65
+ color:red;
66
+ content:'*';
67
+ }
68
+ `
69
+ }}
70
+
71
+ ${({$colon})=>{
72
+ if($colon){
73
+ return `
74
+ &:not(:empty)::after{
75
+ content:'${$colon}';
76
+ }
77
+ `
78
+ }
79
+ }}
80
+
81
+ `
82
+ const StyledColumnValue=styled.main`
83
+ Xflex:1;
84
+ Xdisplay:flex;
85
+ overflow: hidden;
86
+
87
+ text-align: start;
88
+ ${({$validateValue})=>{
89
+ if($validateValue!=null){
90
+ return `
91
+ > * {
92
+ xborder:1px solid red;
93
+ }
94
+ `
95
+ }
96
+ }}
97
+ `
98
+
99
+ // String.prototype.valueString = function (value = {}) {
100
+ // return Array.from(new Set(this.match(/[^{}]+(?=})/g))).reduce((aco, name) => {
101
+ // return aco.replace(new RegExp(`\\{${name}\\}`, "g"), value[name] ?? `{${name}}`);
102
+ // }, String(this));
103
+ // };
104
+
105
+ const valueString=(str='',value = {})=>{
106
+ return Array.from(new Set(str.match(/[^{}]+(?=})/g))).reduce((aco, name) => {
107
+ return aco.replace(new RegExp(`\\{${name}\\}`, "g"), value?.[name] ?? `{${name}}`);
108
+ }, String(str));
109
+ }
110
+
111
+ const ColumnMessage=({value={},record})=>{
112
+ if(value.isValid===false){
113
+ return valueString(value.msg,record)
114
+ }
115
+ }
116
+ const StyledColumnFooter=styled.div`
117
+ &:empty{
118
+ display: none;
119
+ }
120
+ ${({$layout})=>{
121
+ if($layout=='v'){
122
+ return ``
123
+ }else{
124
+ return `grid-column-start:2;`
125
+ }
126
+ }}
127
+ height:25px;
128
+ color:#ff6060;
129
+
130
+ display: flex;
131
+ justify-content: space-between;
132
+
133
+ .left:{
134
+ xflex:1;
135
+ }
136
+ .right{
137
+ color:gray;
138
+ xflex:1;
139
+ }
140
+ `
141
+
142
+ function requiredValidator({value}){
143
+ if( value==null || value==''){
144
+ return {
145
+ msg:this.msg ?? 'This is required'
146
+ }
147
+ }
148
+ }
149
+ const maxValidator=({value,max})=>{
150
+ if(typeof value==='string' && value.length>max){
151
+ return `Max is ${max}`
152
+ }else if(value>max){
153
+ return `Max is ${max}`
154
+ }
155
+ }
156
+
157
+
158
+
159
+ export default class JRFields extends JRFrame {
160
+ UNSAFE_componentWillMount(){
161
+ this.#initValidateValue()
162
+
163
+ }
164
+ reset(){
165
+ this.clearValidateValue()
166
+ super.reset()
167
+ }
168
+ setValue(value,reset){
169
+ super.setValue(value,reset)
170
+ if(reset){
171
+ this.clearValidateValue()
172
+ }
173
+ }
174
+ //-----------------------------------------------------------------------------------
175
+ #findValidator(acc,fullname,{required,...column}){
176
+ const _required=required
177
+ if(required==true || required?.value ){
178
+ acc[fullname]={
179
+ isValid:null
180
+ ,validators:[requiredValidator.bind(_required)]
181
+ }
182
+ }
183
+ }
184
+ #loopColumnsForValidateValue(no,_fullnameList,columns,tab,result){
185
+ const validateValue= columns?.reduce((acc,{name,type,columns,...column},index)=>{
186
+ no+=1
187
+ const fullnameList=name?[..._fullnameList,name]:_fullnameList
188
+ const fullname=fullnameList.join('.')
189
+ // po(`${no} - ${tab}fn= ${fullname}`)
190
+ this.#findValidator(acc,fullname,column)
191
+ if(type==null&&columns){
192
+ this.#loopColumnsForValidateValue(no,fullnameList,columns,`${tab}\t`,result)
193
+ }
194
+ return acc
195
+ },result)
196
+ return validateValue
197
+ }
198
+
199
+ clearValidateValue(){
200
+ Object.values(this.getValidateValue()).forEach((v)=>v.isValid=null)
201
+ }
202
+ #initValidateValue(){
203
+ const columns=this.getColumns()
204
+ const validateValue=this.#loopColumnsForValidateValue(0,this.props.dataSourceName?[this.props.dataSourceName]:[],columns,'',{})
205
+ this.setState({validateValue})
206
+ }
207
+ #exeValidateConfig(validateConfig,value,record){
208
+ validateConfig.isValid=true
209
+ for(var i=0;i<validateConfig.validators.length;i++){
210
+ const result=validateConfig.validators[i]({value,record})
211
+ if(result){
212
+ validateConfig.isValid=false
213
+ validateConfig.msg=result.msg
214
+ break
215
+ }
216
+ }
217
+ }
218
+ validateFields(){
219
+ console.clear()
220
+ Object.entries(this.getValidateValue())
221
+ .filter(([fullname,validateConfig])=>validateConfig.isValid!=true)
222
+ .forEach(([fullname,validateConfig])=>{
223
+ this.#exeValidateConfig(validateConfig,this.getValue(fullname),this.getValue())
224
+ })
225
+ this.setState({validateValue:this.getValidateValue()})
226
+ }
227
+ get validateValueFrom(){
228
+ return this.props.validateValue===undefined?'state':'props'
229
+ }
230
+ getValidateValue(fullname){
231
+ if(fullname===undefined){
232
+ return this[this.validateValueFrom]?.validateValue
233
+ }else{
234
+ return this[this.validateValueFrom]?.validateValue?.[fullname]
235
+ }
236
+ }
237
+ setValidateValue(validateValue){
238
+ if(this.props.setValidateValue){
239
+ this.props.setValidateValue(validateValue)
240
+ }else{
241
+ this.setState({validateValue})
242
+ }
243
+ }
244
+ createValidator({required}){
245
+ const validators=[]
246
+ if(required===true && required.value){
247
+ validators.push(requiredValidator)
248
+ }
249
+ return validators
250
+ }
251
+ //--------------------------------------------------------------------------------------
252
+ get columnsFrom(){
253
+ return this.props.initColumns!==undefined?'state':'props'
254
+ }
255
+ getColumns(){
256
+ return this[this.columnsFrom]?.columns
257
+ }
258
+ //-------------------------------------------------------------------------------------------
259
+
260
+ get colon(){
261
+ return this.props.labelProps?.colon===undefined ?':':this.props.labelProps?.colon
262
+ }
263
+
264
+ createColumn(
265
+ parentValue
266
+ ,{
267
+ type,name,colSpan,rowSpan,style
268
+ ,typeStyle:_typeStyle
269
+ ,required
270
+ ,...column
271
+ }
272
+ ,index
273
+ ,parentName
274
+ ,fullname
275
+ ){
276
+ // po('----------------------------------------')
277
+ // po('parentName',parentName)
278
+ // po('fullname',fullname)
279
+ const value=name?parentValue?.[name]:parentValue
280
+
281
+ const gap=column.gap??this.props.gap
282
+ const label=column.label
283
+ const _style=flexType(style,this,{},{})
284
+ if (colSpan) _style.gridColumn = `span ${colSpan}`
285
+ if (rowSpan) _style.gridRow = `span ${rowSpan}`
286
+ // Object.assign(_style,style)
287
+
288
+
289
+ let content
290
+
291
+ const validators=this.createValidator({required,column})
292
+
293
+ const fn=fullname.join('.')
294
+ const onChange=(inputValue)=>{
295
+ const targetValue=inputValue?.target?.value ?? inputValue
296
+ // po('===Form onChange===',targetValue)
297
+ try{
298
+ parentValue[name]=targetValue
299
+ this.setValue({...this.getValue()})
300
+ }catch(e){
301
+ const _value=this.getValue()??{}
302
+ checkMap(name,targetValue,_value,[...parentName])
303
+ this.setValue(_value)
304
+ }
305
+ if(this.getValidateValue()[fn]) this.#exeValidateConfig(this.getValidateValue()[fn],targetValue,this.getValue())
306
+ }
307
+
308
+ const _parentName=[...parentName]
309
+ if(name!==undefined){
310
+ _parentName.push(name)
311
+ }
312
+
313
+ if(type){
314
+ const typeStyle=flexType(_typeStyle,this,null)
315
+ content=<StyledColumnValue className={'jr-column-value'}
316
+ style={{
317
+ gridColumn:label==null?'span 2':null
318
+ }}
319
+ >
320
+ {
321
+ React.createElement(
322
+ type
323
+ ,{
324
+ value:value,onChange,record:parentValue,style:{width:'100%',...typeStyle}
325
+ ,...column
326
+ }
327
+ )
328
+ }
329
+ </StyledColumnValue>
330
+ }else if(column.columns){
331
+ content=<StyledGrid cols={column.cols} className={'jr-grid'} $gap={gap}>
332
+ {
333
+ this.createColumns(
334
+ value
335
+ ,column.columns
336
+ ,_parentName
337
+ ,fullname
338
+ )
339
+ }
340
+ </StyledGrid>
341
+ }else if(name || column.render ){
342
+ content=<StyledColumnValue className={'jr-column-value'}
343
+ style={{
344
+ gridColumn:label==null?'span 2':null
345
+ ,padding:column.render?'4px 0':null
346
+ }}
347
+ >
348
+ {
349
+ column.render
350
+ ?column.render.bind(this)({onChange,value: value,record:this.getValue()})
351
+ :typeof value ==='object'?JSON.stringify(value):value
352
+ }
353
+ </StyledColumnValue>
354
+ }
355
+ const layout=column.labelProps?.layout===undefined ? this.props.labelProps?.layout: column.labelProps?.layout
356
+ return <StyledColumn
357
+ $layout={layout}
358
+ $hasLabel={label!=null }
359
+ key={`f${index}`}
360
+ style={_style}
361
+ className={'jr-column'}
362
+ $labelWidth={ column.labelProps?.width ?? this.props.labelProps?.width ?? '120px'}
363
+ $valueWidth={ column.valueProps?.width ?? this.props.valueProps?.width ?? '1fr'}
364
+ >
365
+ {
366
+ label!=null
367
+ && <StyledColumnLabel
368
+ $required={required}
369
+ className={'label'}
370
+ $layout={layout}
371
+ $colon={column.labelProps?.colon===undefined ? this.colon:column.labelProps?.colon}>{label}
372
+ </StyledColumnLabel>
373
+ }
374
+ {content}
375
+ { this.props.debugMode &&
376
+ <StyledColumnFooter>
377
+ <div className="left">
378
+ <ColumnMessage value={this.getValidateValue(_parentName.join('.'))} record={this.getValue()}/>
379
+ </div>
380
+ <div className="right">
381
+ {/* {_parentName.join('.')} */}
382
+ </div>
383
+ </StyledColumnFooter>
384
+ // validateValue?.[name]!==undefined && <StyledColumnFooter $layout={layout}>
385
+ // {/* {validateValue?.[name]?.$message} */}
386
+ // <ColumnMessage value={validateValue?.[name]}/>
387
+ // </StyledColumnFooter>
388
+ }
389
+
390
+ </StyledColumn>
391
+ }
392
+
393
+ createColumns(parentValue,columns,parentName,fullname){
394
+ return columns?.map((column,index)=>{
395
+ return this.createColumn(
396
+ parentValue
397
+ ,column,index,parentName
398
+ ,column.name?[...fullname,column.name]:fullname
399
+ )
400
+ })
401
+ }
402
+
403
+
404
+
405
+ renderMe(){
406
+ return <StyleJRFields className={'jr-fields'}>
407
+ <StyledGrid cols={this.props.cols} style={this.props.gridStyle} className={'jr-grid'} $gap={this.props.gap}>
408
+ {
409
+ this.createColumns(
410
+ this.props.dataSourceName?this.getValue()?.[this.props.dataSourceName]:this.getValue()
411
+ ,this.props.columns
412
+ ,this.props.dataSourceName?[this.props.dataSourceName]:[]
413
+ ,this.props.dataSourceName?[this.props.dataSourceName]:[]
414
+ )
415
+ }
416
+ </StyledGrid>
417
+ </StyleJRFields>
418
+ }
419
+
420
+ // render(){
421
+ // return this.renderMe()
422
+ // }
423
+ }
@@ -0,0 +1,30 @@
1
+ import styled from "styled-components";
2
+
3
+ export const StyleJRFields=styled.main`
4
+ --column-bd-color:#cccccc;
5
+ --column-b-color:#eeeeee;
6
+ --column-b-hover-color:#ffffff;
7
+
8
+ flex-direction: column;
9
+ flex:1;
10
+ overflow: overlay;
11
+
12
+ color:#525252;
13
+ XXXborder: 1px solid #a0a0a0;
14
+ background: var(--column-b-color);
15
+
16
+ >.jr-grid{
17
+ background:var(--column-b-color);
18
+
19
+ .jr-column{
20
+ padding: 6px;
21
+
22
+ label{
23
+ color:#525252;
24
+ text-wrap: nowrap;
25
+ padding: 4px 10px 4px 0;
26
+ font-weight: bold;
27
+ }
28
+ }
29
+ }
30
+ `
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+
3
+ export default class JRText extends React.Component{
4
+ render(){
5
+ return <input value={this.props.value}/>
6
+ }
7
+ }
@@ -2,7 +2,6 @@ import React from 'react'
2
2
  import axios from 'axios'
3
3
  import { colonValueString, flexType, po } from './JRUtils'
4
4
  import { displaySpinner } from './LoadingBar'
5
- // import msg from './Message'
6
5
  import styled from 'styled-components'
7
6
 
8
7
 
@@ -274,17 +273,7 @@ export default class JRSubmit extends React.Component {
274
273
  this.setRes(isSuccess,response,config)
275
274
  this.showMessage(isSuccess,isSuccess?config.successMessage:config.failedMessage)
276
275
 
277
- // if (isSuccess) {
278
- // if (config.successMessage) {
279
- // // msg.success({ message:config.successMessage })
280
- // // alert(config.successMessage)
281
- // }
282
- // } else {
283
- // if (config.failedMessage) {
284
- // // msg.error({ message:config.failedMessage })
285
- // // alert(config.failedMessage)
286
- // }
287
- // }
276
+
288
277
  config.callback?.bind(this)(isSuccess,response,payload)
289
278
  }
290
279
 
package/src/index.js CHANGED
@@ -1,8 +1,9 @@
1
1
  import JRSubmit from './components/JRSubmit'
2
2
  import JRFrame from './components/JRFrame/JRFrame'
3
3
  import JRTable from './components/JRTable/JRTable'
4
+ import JRFields from './components/JRFields/JRFields'
4
5
  import JRTestReact from './components/JRTest'
5
6
  export {
6
7
  JRTestReact
7
- ,JRSubmit,JRFrame,JRTable
8
+ ,JRSubmit,JRFrame,JRTable,JRFields
8
9
  }