jrs-react 1.2.1 → 1.2.3

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": "jrs-react",
3
- "version": "1.2.1",
3
+ "version": "1.2.3",
4
4
  "description": "",
5
5
  "main": "build/index.js",
6
6
  "module": "build/index.es.js",
@@ -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
 
@@ -272,17 +271,16 @@ export default class JRSubmit extends React.Component {
272
271
  const isSuccess = response.status >= 200 && response.status <= 299
273
272
 
274
273
  this.setRes(isSuccess,response,config)
275
- if (isSuccess) {
276
- if (config.successMessage) {
277
- msg.success({ message:config.successMessage })
278
- }
279
- } else {
280
- if (config.failedMessage) {
281
- msg.error({ message:config.failedMessage })
282
- }
283
- }
274
+ this.showMessage(isSuccess,isSuccess?config.successMessage:config.failedMessage)
275
+
276
+
284
277
  config.callback?.bind(this)(isSuccess,response,payload)
285
278
  }
279
+
280
+ showMessage(success,message){
281
+ po('success',success)
282
+ po('message',message)
283
+ }
286
284
 
287
285
  renderer(){
288
286
  return
@@ -3,7 +3,6 @@ import { TFoot, THead } from "./THead";
3
3
  import { TBodies } from "./TBodies";
4
4
  import { StyledJRTable } from "./StyledJRTable";
5
5
  import JRFrame from "../JRFrame/JRFrame";
6
- import { Button, Checkbox } from "antd";
7
6
  import React from "react";
8
7
 
9
8
 
@@ -44,7 +43,7 @@ export default class JRTable extends JRFrame {
44
43
  checkableColumn(props){
45
44
  return {//方法1
46
45
  render({value,onChange}){
47
- return <Checkbox checked={value} onChange={(e)=>{onChange(e.target.checked)}}/>
46
+ return <checkbox checked={value} onChange={(e)=>{onChange(e.target.checked)}}/>
48
47
  }
49
48
  ,align:'center'
50
49
  ,name:'checked'
@@ -69,12 +68,12 @@ export default class JRTable extends JRFrame {
69
68
  deletableColumn({name='deletable',sendValue,sendName,valueName,...props}){
70
69
  return {
71
70
  render({value,onChange}){
72
- return <Checkbox checked={value} onChange={(e)=>{onChange(e.target.checked)}}/>
71
+ return <checkbox checked={value} onChange={(e)=>{onChange(e.target.checked)}}/>
73
72
  }
74
73
  ,align:'center'
75
74
  ,name
76
75
  ,label(){
77
- return <Button
76
+ return <button
78
77
  onClick={()=>{
79
78
  const value=this.props.delete.value
80
79
  ?? this.getDataSource()?.filter(record=>record[name]).map(record=>sendValue?record[sendValue]:record)
@@ -88,7 +87,7 @@ export default class JRTable extends JRFrame {
88
87
  ,...props
89
88
  })
90
89
  }}
91
- >刪除</Button>
90
+ >刪除</button>
92
91
  }
93
92
  ,...props
94
93
  }
@@ -108,7 +108,7 @@ const Td=({column:_column,record,tbodyIndex,trIndex,tdIndex,table})=>{
108
108
  const setStyle=(_style)=>{
109
109
  style=_style
110
110
  }
111
- setStyle.bind(this)
111
+ setStyle.bind(table)
112
112
  render?.bind(table)
113
113
  if(type){
114
114
  const typeStyle=flexType(_typeStyle,table,{record},{})
@@ -116,14 +116,14 @@ const Td=({column:_column,record,tbodyIndex,trIndex,tdIndex,table})=>{
116
116
  content=React.createElement(type,{
117
117
  onChange:_onChange
118
118
  ?(e)=>{
119
- _onChange?.bind(this)(e,{value,onChange,me:content})
119
+ _onChange?.bind(table)(e,{value,onChange,me:content})
120
120
  }
121
121
  :onChange
122
122
  ,value
123
123
  ,style:typeStyle
124
124
  ,render
125
125
  ,...column
126
- ,...funcProps?.bind(this)({value})
126
+ ,...funcProps?.bind(table)({value})
127
127
 
128
128
  })
129
129
  }else if(render){
package/src/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import JRSubmit from './components/JRSubmit'
2
2
  import JRFrame from './components/JRFrame/JRFrame'
3
- // import JRTable from './components/JRTable/JRTable'
3
+ import JRTable from './components/JRTable/JRTable'
4
4
  import JRTestReact from './components/JRTest'
5
5
  export {
6
6
  JRTestReact
7
- ,JRSubmit,JRFrame//,JRTable
7
+ ,JRSubmit,JRFrame,JRTable
8
8
  }