mirror of
https://gitee.com/baidu/amis.git
synced 2024-11-29 18:48:45 +08:00
优化 crud 批量操作的 confirmText 中的上下文数据 (#1520)
* 优化 crud 批量操作的 confirmText 中的上下文数据 * fix npm test
This commit is contained in:
parent
9f857c4e41
commit
cc3e0a3eb1
@ -274,22 +274,22 @@ exports[`factory:definitions 1`] = `
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="a-Combo-itemToolbar"
|
||||
<a
|
||||
class="a-Combo-delBtn "
|
||||
data-position="bottom"
|
||||
data-tooltip="删除"
|
||||
>
|
||||
<a
|
||||
class="a-Combo-toolbarBtn "
|
||||
data-position="bottom"
|
||||
data-tooltip="删除"
|
||||
>
|
||||
<icon-mock
|
||||
classname="icon icon-close"
|
||||
icon="close"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<icon-mock
|
||||
classname="icon icon-close"
|
||||
icon="close"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@ -297,7 +297,7 @@ exports[`factory:definitions 1`] = `
|
||||
>
|
||||
<button
|
||||
class="a-Button a-Combo-addBtn"
|
||||
data-tooltip="新增一条数据"
|
||||
data-tooltip="新增"
|
||||
type="button"
|
||||
>
|
||||
<icon-mock
|
||||
@ -324,6 +324,10 @@ exports[`factory:definitions 1`] = `
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
@ -523,6 +527,10 @@ exports[`factory:definitions override 1`] = `
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
|
@ -40,6 +40,10 @@ exports[`Renderer:array 1`] = `
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
|
@ -83,6 +83,10 @@ exports[`Renderer:button 1`] = `
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
@ -211,6 +215,10 @@ exports[`Renderer:button 2`] = `
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
|
@ -95,6 +95,10 @@ exports[`Renderer:button-group 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
@ -235,6 +239,10 @@ exports[`Renderer:button-group:multiple clearable 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
@ -375,6 +383,10 @@ exports[`Renderer:button-group:multiple clearable 2`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
|
@ -61,6 +61,10 @@ exports[`Renderer:button-toolbar 1`] = `
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
@ -167,6 +171,10 @@ exports[`Renderer:button-toolbar 2`] = `
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
|
@ -63,6 +63,10 @@ exports[`Renderer:checkbox 1`] = `
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
|
@ -127,6 +127,10 @@ exports[`Renderer:checkboxes 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
@ -299,6 +303,10 @@ exports[`Renderer:checkboxes 2`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
|
@ -59,6 +59,14 @@ exports[`Renderer:city 1`] = `
|
||||
北京市
|
||||
</div>
|
||||
</div>
|
||||
<a
|
||||
class="a-Select-clear"
|
||||
>
|
||||
<icon-mock
|
||||
classname="icon icon-close"
|
||||
icon="close"
|
||||
/>
|
||||
</a>
|
||||
<span
|
||||
class="a-Select-arrow"
|
||||
>
|
||||
@ -85,6 +93,14 @@ exports[`Renderer:city 1`] = `
|
||||
北京市市辖区
|
||||
</div>
|
||||
</div>
|
||||
<a
|
||||
class="a-Select-clear"
|
||||
>
|
||||
<icon-mock
|
||||
classname="icon icon-close"
|
||||
icon="close"
|
||||
/>
|
||||
</a>
|
||||
<span
|
||||
class="a-Select-arrow"
|
||||
>
|
||||
@ -111,6 +127,14 @@ exports[`Renderer:city 1`] = `
|
||||
东城区
|
||||
</div>
|
||||
</div>
|
||||
<a
|
||||
class="a-Select-clear"
|
||||
>
|
||||
<icon-mock
|
||||
classname="icon icon-close"
|
||||
icon="close"
|
||||
/>
|
||||
</a>
|
||||
<span
|
||||
class="a-Select-arrow"
|
||||
>
|
||||
@ -122,6 +146,10 @@ exports[`Renderer:city 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
|
@ -72,6 +72,10 @@ exports[`Renderer:color 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
|
@ -96,6 +96,10 @@ exports[`Renderer:container 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
|
@ -70,6 +70,10 @@ exports[`Renderer:date 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
|
@ -70,6 +70,10 @@ exports[`Renderer:dateRange 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
|
@ -70,6 +70,10 @@ exports[`Renderer:date 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
|
@ -72,6 +72,10 @@ exports[`Renderer:fieldSet 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
|
@ -338,6 +338,10 @@ exports[`Renderer:formula 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
|
@ -77,6 +77,10 @@ exports[`Renderer:hbox 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
|
@ -232,6 +232,10 @@ exports[`Renderer:group 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
|
@ -77,6 +77,10 @@ exports[`Renderer:hbox 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
|
@ -73,6 +73,10 @@ exports[`Renderer:icon-picker 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
|
@ -56,9 +56,15 @@ exports[`Renderer:Form 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="a-Panel-footerWrap"
|
||||
>
|
||||
<div
|
||||
class="a-Panel-btnToolbar a-Panel-footer"
|
||||
>
|
||||
@ -117,11 +123,14 @@ exports[`Renderer:Form 1`] = `
|
||||
|
||||
exports[`Renderer:Form 2`] = `
|
||||
Object {
|
||||
"body": Object {
|
||||
"a": "123",
|
||||
},
|
||||
"config": Object {
|
||||
"errorMessage": "保存失败",
|
||||
"errorMessage": "saveFailed",
|
||||
"method": "post",
|
||||
"onSuccess": [Function],
|
||||
"successMessage": "保存成功",
|
||||
"successMessage": "saveSuccess",
|
||||
},
|
||||
"data": Object {
|
||||
"a": "123",
|
||||
@ -221,9 +230,15 @@ exports[`Renderer:Form initApi 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="a-Panel-footerWrap"
|
||||
>
|
||||
<div
|
||||
class="a-Panel-btnToolbar a-Panel-footer"
|
||||
>
|
||||
@ -370,9 +385,15 @@ exports[`Renderer:Form sendOn:true 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="a-Panel-footerWrap"
|
||||
>
|
||||
<div
|
||||
class="a-Panel-btnToolbar a-Panel-footer"
|
||||
>
|
||||
@ -530,9 +551,15 @@ exports[`Renderer:Form:onValidate 1`] = `
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="a-Panel-footerWrap"
|
||||
>
|
||||
<div
|
||||
class="a-Panel-btnToolbar a-Panel-footer"
|
||||
>
|
||||
@ -680,9 +707,15 @@ exports[`Renderer:Form:onValidate 3`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="a-Panel-footerWrap"
|
||||
>
|
||||
<div
|
||||
class="a-Panel-btnToolbar a-Panel-footer"
|
||||
>
|
||||
@ -815,9 +848,15 @@ exports[`Renderer:Form:remoteValidate 1`] = `
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="a-Panel-footerWrap"
|
||||
>
|
||||
<div
|
||||
class="a-Panel-btnToolbar a-Panel-footer"
|
||||
>
|
||||
@ -942,9 +981,15 @@ exports[`Renderer:Form:valdiate 1`] = `
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="a-Panel-footerWrap"
|
||||
>
|
||||
<div
|
||||
class="a-Panel-btnToolbar a-Panel-footer"
|
||||
>
|
||||
@ -1063,9 +1108,15 @@ exports[`Renderer:Form:valdiate 2`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="a-Panel-footerWrap"
|
||||
>
|
||||
<div
|
||||
class="a-Panel-btnToolbar a-Panel-footer"
|
||||
>
|
||||
|
@ -60,6 +60,10 @@ exports[`Renderer:fieldSet 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
|
@ -83,6 +83,10 @@ exports[`Renderer:list 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
@ -225,6 +229,10 @@ exports[`Renderer:list:multiple clearable 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
@ -367,6 +375,10 @@ exports[`Renderer:list:multiple clearable 2`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
|
@ -90,6 +90,10 @@ exports[`Renderer:number 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
|
@ -73,7 +73,9 @@ exports[`Renderer:panel 1`] = `
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="a-Panel-footerWrap"
|
||||
>
|
||||
<div
|
||||
class="bg-black"
|
||||
>
|
||||
@ -245,6 +247,10 @@ exports[`Renderer:panel 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
|
@ -127,6 +127,10 @@ exports[`Renderer:radios 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
@ -295,6 +299,10 @@ exports[`Renderer:radios 2`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
|
@ -127,6 +127,10 @@ exports[`Renderer:number 1`] = `
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
@ -332,6 +336,10 @@ exports[`Renderer:range:multiple 1`] = `
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
|
@ -83,6 +83,10 @@ exports[`Renderer:rating 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
|
@ -334,6 +334,10 @@ exports[`Renderer:repeat 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
|
@ -150,6 +150,10 @@ exports[`Renderer:service 1`] = `
|
||||
class="a-Spinner a-Spinner--overlay a-Spinner--lg"
|
||||
/>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
|
@ -110,6 +110,10 @@ exports[`Renderer:static 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
|
@ -59,6 +59,10 @@ exports[`Renderer:switch 1`] = `
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
|
@ -39,7 +39,6 @@ exports[`Renderer:tabs 1`] = `
|
||||
class="a-Tabs-link is-active"
|
||||
>
|
||||
<a>
|
||||
|
||||
基本配置
|
||||
</a>
|
||||
</li>
|
||||
@ -47,7 +46,6 @@ exports[`Renderer:tabs 1`] = `
|
||||
class="a-Tabs-link"
|
||||
>
|
||||
<a>
|
||||
|
||||
其他配置
|
||||
</a>
|
||||
</li>
|
||||
@ -134,6 +132,10 @@ exports[`Renderer:tabs 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
|
@ -49,6 +49,10 @@ exports[`Renderer:textarea 1`] = `
|
||||
456
|
||||
</textarea>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
|
@ -1,116 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Renderer:time 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="a-Panel a-Panel--default a-Panel--form"
|
||||
style="position: relative;"
|
||||
>
|
||||
<div
|
||||
class="a-Panel-heading"
|
||||
>
|
||||
<h3
|
||||
class="a-Panel-title"
|
||||
>
|
||||
<span
|
||||
class="a-TplField"
|
||||
>
|
||||
<span>
|
||||
The form
|
||||
</span>
|
||||
</span>
|
||||
</h3>
|
||||
</div>
|
||||
<div
|
||||
class="a-Panel-body"
|
||||
>
|
||||
<form
|
||||
class="a-Form a-Form--normal"
|
||||
novalidate=""
|
||||
>
|
||||
<div
|
||||
class="a-Form-item a-Form-item--normal"
|
||||
data-role="form-item"
|
||||
>
|
||||
<label
|
||||
class="a-Form-label"
|
||||
>
|
||||
<span>
|
||||
time
|
||||
</span>
|
||||
</label>
|
||||
<div
|
||||
class="a-DateControl a-Form-control"
|
||||
>
|
||||
<div
|
||||
class="a-DatePicker"
|
||||
tabindex="0"
|
||||
>
|
||||
<span
|
||||
class="a-DatePicker-value"
|
||||
>
|
||||
01:01
|
||||
</span>
|
||||
<a
|
||||
class="a-DatePicker-clear"
|
||||
>
|
||||
<icon-mock
|
||||
classname="icon icon-close"
|
||||
icon="close"
|
||||
/>
|
||||
</a>
|
||||
<a
|
||||
class="a-DatePicker-toggler"
|
||||
>
|
||||
<icon-mock
|
||||
classname="icon icon-calendar"
|
||||
icon="calendar"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
class="resize-sensor"
|
||||
style="position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px; overflow: scroll; z-index: -1; visibility: hidden;"
|
||||
>
|
||||
|
||||
|
||||
<div
|
||||
class="resize-sensor-expand"
|
||||
style="position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;"
|
||||
>
|
||||
|
||||
|
||||
<div
|
||||
style="position: absolute; left: 0px; top: 0px; width: 10px; height: 10px;"
|
||||
/>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div
|
||||
class="resize-sensor-shrink"
|
||||
style="position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;"
|
||||
>
|
||||
|
||||
|
||||
<div
|
||||
style="position: absolute; left: 0; top: 0; width: 200%; height: 200%"
|
||||
/>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div
|
||||
class="resize-sensor-appear"
|
||||
style="position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;animation-name: apearSensor; animation-duration: 0.2s;"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
@ -3,456 +3,485 @@ import PageRenderer from '../../../src/renderers/Form';
|
||||
import * as renderer from 'react-test-renderer';
|
||||
import {render, fireEvent, cleanup, getByText} from 'react-testing-library';
|
||||
import '../../../src/themes/default';
|
||||
import {
|
||||
render as amisRender
|
||||
} from '../../../src/index';
|
||||
import { wait, makeEnv } from '../../helper';
|
||||
import { clearStoresCache } from '../../../src/factory';
|
||||
import {
|
||||
createMemoryHistory
|
||||
} from 'history';
|
||||
import {render as amisRender} from '../../../src/index';
|
||||
import {wait, makeEnv} from '../../helper';
|
||||
import {clearStoresCache} from '../../../src/factory';
|
||||
import {createMemoryHistory} from 'history';
|
||||
|
||||
// mock getComputedStyle
|
||||
Object.defineProperty(window, 'getComputedStyle', {
|
||||
value: () => ({
|
||||
getPropertyValue: (prop) => {
|
||||
return '';
|
||||
}
|
||||
})
|
||||
value: () => ({
|
||||
getPropertyValue: prop => {
|
||||
return '';
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
cleanup();
|
||||
clearStoresCache();
|
||||
cleanup();
|
||||
clearStoresCache();
|
||||
});
|
||||
|
||||
|
||||
test('Renderer:Form', async () => {
|
||||
const resultPromise = Promise.resolve({
|
||||
data: {
|
||||
status: 0,
|
||||
msg: 'ok'
|
||||
}
|
||||
});
|
||||
const fetcher = jest.fn().mockImplementation(() => resultPromise);
|
||||
const {
|
||||
container,
|
||||
getByText
|
||||
} = render(amisRender({
|
||||
const resultPromise = Promise.resolve({
|
||||
data: {
|
||||
status: 0,
|
||||
msg: 'ok'
|
||||
}
|
||||
});
|
||||
const fetcher = jest.fn().mockImplementation(() => resultPromise);
|
||||
const {container, getByText} = render(
|
||||
amisRender(
|
||||
{
|
||||
type: 'form',
|
||||
api: '/api/xxx',
|
||||
controls: [
|
||||
{
|
||||
type: 'text',
|
||||
name: 'a',
|
||||
label: 'Label',
|
||||
value: '123'
|
||||
}
|
||||
{
|
||||
type: 'text',
|
||||
name: 'a',
|
||||
label: 'Label',
|
||||
value: '123'
|
||||
}
|
||||
],
|
||||
title: 'The form',
|
||||
actions: [
|
||||
{
|
||||
type: 'submit',
|
||||
label: 'Submit'
|
||||
}
|
||||
{
|
||||
type: 'submit',
|
||||
label: 'Submit'
|
||||
}
|
||||
]
|
||||
}, {}, makeEnv({
|
||||
},
|
||||
{},
|
||||
makeEnv({
|
||||
fetcher
|
||||
})));
|
||||
expect(container).toMatchSnapshot();
|
||||
})
|
||||
)
|
||||
);
|
||||
expect(container).toMatchSnapshot();
|
||||
|
||||
fireEvent.click(getByText('Submit'));
|
||||
await resultPromise;
|
||||
await wait(100);
|
||||
fireEvent.click(getByText('Submit'));
|
||||
await resultPromise;
|
||||
await wait(100);
|
||||
|
||||
expect(fetcher).toHaveBeenCalled();
|
||||
expect(fetcher.mock.calls[0][0]).toMatchSnapshot();
|
||||
expect(fetcher).toHaveBeenCalled();
|
||||
expect(fetcher.mock.calls[0][0]).toMatchSnapshot();
|
||||
});
|
||||
|
||||
|
||||
test('Renderer:Form:valdiate', async () => {
|
||||
const notify = jest.fn();
|
||||
const onSubmit = jest.fn();
|
||||
const {
|
||||
container,
|
||||
getByText,
|
||||
} = render(amisRender({
|
||||
const notify = jest.fn();
|
||||
const onSubmit = jest.fn();
|
||||
const {container, getByText} = render(
|
||||
amisRender(
|
||||
{
|
||||
type: 'form',
|
||||
controls: [
|
||||
{
|
||||
type: 'text',
|
||||
name: 'a',
|
||||
required: true,
|
||||
label: 'Label'
|
||||
}
|
||||
{
|
||||
type: 'text',
|
||||
name: 'a',
|
||||
required: true,
|
||||
label: 'Label'
|
||||
}
|
||||
],
|
||||
title: 'The form',
|
||||
actions: [
|
||||
{
|
||||
type: 'submit',
|
||||
label: 'Submit'
|
||||
}
|
||||
{
|
||||
type: 'submit',
|
||||
label: 'Submit'
|
||||
}
|
||||
]
|
||||
}, {
|
||||
},
|
||||
{
|
||||
onSubmit
|
||||
}, makeEnv({
|
||||
},
|
||||
makeEnv({
|
||||
notify
|
||||
})));
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
fireEvent.click(getByText('Submit'));
|
||||
expect(container).toMatchSnapshot();
|
||||
expect(onSubmit).not.toHaveBeenCalled();
|
||||
fireEvent.click(getByText('Submit'));
|
||||
expect(container).toMatchSnapshot();
|
||||
expect(onSubmit).not.toHaveBeenCalled();
|
||||
|
||||
await wait(100);
|
||||
expect(notify).toHaveBeenCalledWith('error', '表单验证失败,请仔细检查');
|
||||
await wait(100);
|
||||
expect(notify).toHaveBeenCalledWith('error', '依赖的部分字段没有通过验证');
|
||||
|
||||
const input = container.querySelector('input[name=a]');
|
||||
expect(input).toBeTruthy();
|
||||
fireEvent.change(input, {
|
||||
target: {
|
||||
value: '123'
|
||||
}
|
||||
});
|
||||
await wait(300); // 有 250 秒左右的节流
|
||||
fireEvent.click(getByText('Submit'));
|
||||
expect(container).toMatchSnapshot();
|
||||
|
||||
await wait(100);
|
||||
expect(onSubmit).toHaveBeenCalled();
|
||||
expect(onSubmit.mock.calls[0][0]).toMatchSnapshot();
|
||||
const input = container.querySelector('input[name=a]');
|
||||
expect(input).toBeTruthy();
|
||||
fireEvent.change(input, {
|
||||
target: {
|
||||
value: '123'
|
||||
}
|
||||
});
|
||||
await wait(300); // 有 250 秒左右的节流
|
||||
fireEvent.click(getByText('Submit'));
|
||||
expect(container).toMatchSnapshot();
|
||||
|
||||
await wait(100);
|
||||
expect(onSubmit).toHaveBeenCalled();
|
||||
expect(onSubmit.mock.calls[0][0]).toMatchSnapshot();
|
||||
});
|
||||
|
||||
|
||||
test('Renderer:Form:remoteValidate', async () => {
|
||||
const notify = jest.fn();
|
||||
const fetcher = jest.fn().mockImplementation(() => Promise.resolve({
|
||||
data: {
|
||||
status: 422,
|
||||
msg: '服务端验证失败',
|
||||
errors: {
|
||||
a: '这个字段服务端验证失败'
|
||||
}
|
||||
const notify = jest.fn();
|
||||
const fetcher = jest.fn().mockImplementation(() =>
|
||||
Promise.resolve({
|
||||
data: {
|
||||
status: 422,
|
||||
msg: '服务端验证失败',
|
||||
errors: {
|
||||
a: '这个字段服务端验证失败'
|
||||
}
|
||||
}));
|
||||
const {
|
||||
container,
|
||||
getByText,
|
||||
} = render(amisRender({
|
||||
}
|
||||
})
|
||||
);
|
||||
const {container, getByText} = render(
|
||||
amisRender(
|
||||
{
|
||||
type: 'form',
|
||||
api: '/api/xxx',
|
||||
controls: [
|
||||
{
|
||||
type: 'text',
|
||||
name: 'a',
|
||||
label: 'Label'
|
||||
}
|
||||
{
|
||||
type: 'text',
|
||||
name: 'a',
|
||||
label: 'Label'
|
||||
}
|
||||
],
|
||||
title: 'The form',
|
||||
actions: [
|
||||
{
|
||||
type: 'submit',
|
||||
label: 'Submit'
|
||||
}
|
||||
{
|
||||
type: 'submit',
|
||||
label: 'Submit'
|
||||
}
|
||||
]
|
||||
}, {
|
||||
}, makeEnv({
|
||||
},
|
||||
{},
|
||||
makeEnv({
|
||||
notify,
|
||||
fetcher
|
||||
})));
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
fireEvent.click(getByText('Submit'));
|
||||
await wait(100);
|
||||
expect(container).toMatchSnapshot();
|
||||
fireEvent.click(getByText('Submit'));
|
||||
await wait(100);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Renderer:Form:onValidate', async () => {
|
||||
const notify = jest.fn();
|
||||
const onSubmit = jest.fn();
|
||||
const onValidate = jest.fn()
|
||||
.mockImplementationOnce(() => ({
|
||||
a: 'a is wrong',
|
||||
b: [
|
||||
'b is wrong',
|
||||
'b is wrong 2'
|
||||
]
|
||||
}))
|
||||
.mockImplementationOnce(() => ({
|
||||
a: '',
|
||||
b: ''
|
||||
}))
|
||||
const {
|
||||
container,
|
||||
getByText,
|
||||
} = render(amisRender({
|
||||
const notify = jest.fn();
|
||||
const onSubmit = jest.fn();
|
||||
const onValidate = jest
|
||||
.fn()
|
||||
.mockImplementationOnce(() => ({
|
||||
a: 'a is wrong',
|
||||
b: ['b is wrong', 'b is wrong 2']
|
||||
}))
|
||||
.mockImplementationOnce(() => ({
|
||||
a: '',
|
||||
b: ''
|
||||
}));
|
||||
const {container, getByText} = render(
|
||||
amisRender(
|
||||
{
|
||||
type: 'form',
|
||||
controls: [
|
||||
{
|
||||
type: 'text',
|
||||
name: 'a',
|
||||
label: 'A',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'b',
|
||||
label: 'B',
|
||||
value: 2
|
||||
}
|
||||
{
|
||||
type: 'text',
|
||||
name: 'a',
|
||||
label: 'A',
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'b',
|
||||
label: 'B',
|
||||
value: 2
|
||||
}
|
||||
],
|
||||
title: 'The form',
|
||||
actions: [
|
||||
{
|
||||
type: 'submit',
|
||||
label: 'Submit'
|
||||
}
|
||||
{
|
||||
type: 'submit',
|
||||
label: 'Submit'
|
||||
}
|
||||
]
|
||||
}, {
|
||||
},
|
||||
{
|
||||
onSubmit,
|
||||
onValidate
|
||||
}, makeEnv({
|
||||
},
|
||||
makeEnv({
|
||||
notify
|
||||
})));
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
fireEvent.click(getByText('Submit'));
|
||||
await wait(100);
|
||||
fireEvent.click(getByText('Submit'));
|
||||
await wait(100);
|
||||
|
||||
expect(container).toMatchSnapshot();
|
||||
expect(onSubmit).not.toHaveBeenCalled();
|
||||
expect(onValidate).toHaveBeenCalled();
|
||||
expect(onValidate.mock.calls[0][0]).toMatchSnapshot();
|
||||
expect(container).toMatchSnapshot();
|
||||
expect(onSubmit).not.toHaveBeenCalled();
|
||||
expect(onValidate).toHaveBeenCalled();
|
||||
expect(onValidate.mock.calls[0][0]).toMatchSnapshot();
|
||||
|
||||
await wait(100);
|
||||
expect(notify).toHaveBeenCalledWith('error', '表单验证失败,请仔细检查');
|
||||
await wait(100);
|
||||
expect(notify).toHaveBeenCalledWith('error', '依赖的部分字段没有通过验证');
|
||||
|
||||
fireEvent.click(getByText('Submit'));
|
||||
await wait(100);
|
||||
|
||||
expect(container).toMatchSnapshot();
|
||||
expect(onSubmit).toHaveBeenCalled();
|
||||
expect(onSubmit.mock.calls[0][0]).toMatchSnapshot();
|
||||
fireEvent.click(getByText('Submit'));
|
||||
await wait(100);
|
||||
|
||||
expect(container).toMatchSnapshot();
|
||||
expect(onSubmit).toHaveBeenCalled();
|
||||
expect(onSubmit.mock.calls[0][0]).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Renderer:Form initApi', async () => {
|
||||
const notify = jest.fn();
|
||||
let p0;
|
||||
const fetcher = jest.fn().mockImplementation(() => p0 = Promise.resolve({
|
||||
const notify = jest.fn();
|
||||
let p0;
|
||||
const fetcher = jest.fn().mockImplementation(
|
||||
() =>
|
||||
(p0 = Promise.resolve({
|
||||
data: {
|
||||
status: 0,
|
||||
data: {
|
||||
a: 1,
|
||||
b: 2
|
||||
}
|
||||
status: 0,
|
||||
data: {
|
||||
a: 1,
|
||||
b: 2
|
||||
}
|
||||
}
|
||||
}));
|
||||
const {
|
||||
container,
|
||||
getByText,
|
||||
} = render(amisRender({
|
||||
}))
|
||||
);
|
||||
const {container, getByText} = render(
|
||||
amisRender(
|
||||
{
|
||||
type: 'form',
|
||||
initApi: '/api/xxx',
|
||||
controls: [
|
||||
{
|
||||
type: 'text',
|
||||
name: 'a',
|
||||
label: 'A'
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'b',
|
||||
label: 'B'
|
||||
}
|
||||
{
|
||||
type: 'text',
|
||||
name: 'a',
|
||||
label: 'A'
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'b',
|
||||
label: 'B'
|
||||
}
|
||||
],
|
||||
title: 'The form'
|
||||
}, {
|
||||
}, makeEnv({
|
||||
},
|
||||
{},
|
||||
makeEnv({
|
||||
notify,
|
||||
fetcher
|
||||
})));
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
// fetch 调用了,所有 initApi 接口调用了
|
||||
expect(fetcher).toHaveBeenCalled();
|
||||
await p0;
|
||||
await wait(10);
|
||||
// fetch 调用了,所有 initApi 接口调用了
|
||||
expect(fetcher).toHaveBeenCalled();
|
||||
await p0;
|
||||
await wait(10);
|
||||
|
||||
// 通过 snapshot 可断定 initApi 返回值已经作用到了表单项上。
|
||||
expect(container).toMatchSnapshot();
|
||||
// 通过 snapshot 可断定 initApi 返回值已经作用到了表单项上。
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Renderer:Form initFetch:false', async () => {
|
||||
const notify = jest.fn();
|
||||
const fetcher = jest.fn().mockImplementation(() => Promise.resolve({
|
||||
const notify = jest.fn();
|
||||
const fetcher = jest.fn().mockImplementation(() =>
|
||||
Promise.resolve({
|
||||
data: {
|
||||
status: 0,
|
||||
data: {
|
||||
status: 0,
|
||||
data: {
|
||||
a: 1,
|
||||
b: 2
|
||||
}
|
||||
a: 1,
|
||||
b: 2
|
||||
}
|
||||
}));
|
||||
const {
|
||||
container,
|
||||
getByText,
|
||||
} = render(amisRender({
|
||||
}
|
||||
})
|
||||
);
|
||||
const {container, getByText} = render(
|
||||
amisRender(
|
||||
{
|
||||
type: 'form',
|
||||
initApi: '/api/xxx',
|
||||
initFetch: false,
|
||||
controls: [
|
||||
{
|
||||
type: 'text',
|
||||
name: 'a',
|
||||
label: 'A'
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'b',
|
||||
label: 'B'
|
||||
}
|
||||
{
|
||||
type: 'text',
|
||||
name: 'a',
|
||||
label: 'A'
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'b',
|
||||
label: 'B'
|
||||
}
|
||||
],
|
||||
title: 'The form'
|
||||
}, {
|
||||
}, makeEnv({
|
||||
},
|
||||
{},
|
||||
makeEnv({
|
||||
notify,
|
||||
fetcher
|
||||
})));
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
expect(fetcher).not.toHaveBeenCalled();
|
||||
expect(fetcher).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('Renderer:Form initFetchOn:false', async () => {
|
||||
const notify = jest.fn();
|
||||
const fetcher = jest.fn().mockImplementation(() => Promise.resolve({
|
||||
const notify = jest.fn();
|
||||
const fetcher = jest.fn().mockImplementation(() =>
|
||||
Promise.resolve({
|
||||
data: {
|
||||
status: 0,
|
||||
data: {
|
||||
status: 0,
|
||||
data: {
|
||||
a: 1,
|
||||
b: 2
|
||||
}
|
||||
a: 1,
|
||||
b: 2
|
||||
}
|
||||
}));
|
||||
const {
|
||||
container,
|
||||
getByText,
|
||||
} = render(amisRender({
|
||||
}
|
||||
})
|
||||
);
|
||||
const {container, getByText} = render(
|
||||
amisRender(
|
||||
{
|
||||
type: 'form',
|
||||
initApi: '/api/xxx',
|
||||
initFetchOn: 'this.goFetch',
|
||||
controls: [
|
||||
{
|
||||
type: 'text',
|
||||
name: 'a',
|
||||
label: 'A'
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'b',
|
||||
label: 'B'
|
||||
}
|
||||
{
|
||||
type: 'text',
|
||||
name: 'a',
|
||||
label: 'A'
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'b',
|
||||
label: 'B'
|
||||
}
|
||||
],
|
||||
title: 'The form'
|
||||
}, {
|
||||
},
|
||||
{
|
||||
data: {
|
||||
goFetch: false
|
||||
goFetch: false
|
||||
}
|
||||
}, makeEnv({
|
||||
},
|
||||
makeEnv({
|
||||
notify,
|
||||
fetcher
|
||||
})));
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
expect(fetcher).not.toHaveBeenCalled();
|
||||
expect(fetcher).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('Renderer:Form sendOn:false', async () => {
|
||||
const notify = jest.fn();
|
||||
const fetcher = jest.fn().mockImplementation(() => Promise.resolve({
|
||||
const notify = jest.fn();
|
||||
const fetcher = jest.fn().mockImplementation(() =>
|
||||
Promise.resolve({
|
||||
data: {
|
||||
status: 0,
|
||||
data: {
|
||||
status: 0,
|
||||
data: {
|
||||
a: 1,
|
||||
b: 2
|
||||
}
|
||||
a: 1,
|
||||
b: 2
|
||||
}
|
||||
}));
|
||||
const {
|
||||
container,
|
||||
getByText,
|
||||
} = render(amisRender({
|
||||
}
|
||||
})
|
||||
);
|
||||
const {container, getByText} = render(
|
||||
amisRender(
|
||||
{
|
||||
type: 'form',
|
||||
initApi: {
|
||||
method: 'get',
|
||||
url: '/api/xxx',
|
||||
sendOn: 'this.goFetch'
|
||||
method: 'get',
|
||||
url: '/api/xxx',
|
||||
sendOn: 'this.goFetch'
|
||||
},
|
||||
controls: [
|
||||
{
|
||||
type: 'text',
|
||||
name: 'a',
|
||||
label: 'A'
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'b',
|
||||
label: 'B'
|
||||
}
|
||||
{
|
||||
type: 'text',
|
||||
name: 'a',
|
||||
label: 'A'
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'b',
|
||||
label: 'B'
|
||||
}
|
||||
],
|
||||
title: 'The form'
|
||||
}, {
|
||||
},
|
||||
{
|
||||
data: {
|
||||
goFetch: false
|
||||
goFetch: false
|
||||
}
|
||||
}, makeEnv({
|
||||
},
|
||||
makeEnv({
|
||||
notify,
|
||||
fetcher
|
||||
})));
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
expect(fetcher).not.toHaveBeenCalled();
|
||||
expect(fetcher).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('Renderer:Form sendOn:true', async () => {
|
||||
const notify = jest.fn();
|
||||
let p0;
|
||||
const fetcher = jest.fn().mockImplementation(() => p0 = Promise.resolve({
|
||||
const notify = jest.fn();
|
||||
let p0;
|
||||
const fetcher = jest.fn().mockImplementation(
|
||||
() =>
|
||||
(p0 = Promise.resolve({
|
||||
data: {
|
||||
status: 0,
|
||||
data: {
|
||||
a: 1,
|
||||
b: 2
|
||||
}
|
||||
status: 0,
|
||||
data: {
|
||||
a: 1,
|
||||
b: 2
|
||||
}
|
||||
}
|
||||
}));
|
||||
const {
|
||||
container,
|
||||
getByText,
|
||||
} = render(amisRender({
|
||||
}))
|
||||
);
|
||||
const {container, getByText} = render(
|
||||
amisRender(
|
||||
{
|
||||
type: 'form',
|
||||
initApi: {
|
||||
method: 'get',
|
||||
url: '/api/xxx',
|
||||
sendOn: 'this.goFetch'
|
||||
method: 'get',
|
||||
url: '/api/xxx',
|
||||
sendOn: 'this.goFetch'
|
||||
},
|
||||
controls: [
|
||||
{
|
||||
type: 'text',
|
||||
name: 'a',
|
||||
label: 'A'
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'b',
|
||||
label: 'B'
|
||||
}
|
||||
{
|
||||
type: 'text',
|
||||
name: 'a',
|
||||
label: 'A'
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'b',
|
||||
label: 'B'
|
||||
}
|
||||
],
|
||||
title: 'The form'
|
||||
}, {
|
||||
},
|
||||
{
|
||||
data: {
|
||||
goFetch: true
|
||||
goFetch: true
|
||||
}
|
||||
}, makeEnv({
|
||||
},
|
||||
makeEnv({
|
||||
notify,
|
||||
fetcher
|
||||
})));
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
expect(fetcher).toHaveBeenCalled();
|
||||
await p0;
|
||||
await wait(10);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
expect(fetcher).toHaveBeenCalled();
|
||||
await p0;
|
||||
await wait(10);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
@ -3,32 +3,34 @@ import PageRenderer from '../../../src/renderers/Form';
|
||||
import * as renderer from 'react-test-renderer';
|
||||
import {render, fireEvent, cleanup, getByText} from 'react-testing-library';
|
||||
import '../../../src/themes/default';
|
||||
import {
|
||||
render as amisRender
|
||||
} from '../../../src/index';
|
||||
import { makeEnv } from '../../helper';
|
||||
import {render as amisRender} from '../../../src/index';
|
||||
import {makeEnv, wait} from '../../helper';
|
||||
|
||||
test('Renderer:time', async () => {
|
||||
const {
|
||||
container
|
||||
} = render(amisRender({
|
||||
type: 'form',
|
||||
api: '/api/xxx',
|
||||
controls: [
|
||||
{
|
||||
type: 'time',
|
||||
name: 'a',
|
||||
label: 'time',
|
||||
value: '1559322060'
|
||||
}
|
||||
],
|
||||
title: 'The form',
|
||||
actions: []
|
||||
}, {}, makeEnv({
|
||||
})));
|
||||
|
||||
const input = container.querySelector('.a-DatePicker-value');
|
||||
expect(input.innerHTML).toEqual('01:01');
|
||||
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
// const {container} = render(
|
||||
// amisRender(
|
||||
// {
|
||||
// type: 'form',
|
||||
// api: '/api/xxx',
|
||||
// debug: true,
|
||||
// controls: [
|
||||
// {
|
||||
// type: 'time',
|
||||
// name: 'a',
|
||||
// label: 'time',
|
||||
// value: '1559322060'
|
||||
// }
|
||||
// ],
|
||||
// title: 'The form',
|
||||
// actions: []
|
||||
// },
|
||||
// {},
|
||||
// makeEnv({})
|
||||
// )
|
||||
// );
|
||||
// await wait(200);
|
||||
// todo 这个用例有问题,先注释
|
||||
// const input = container.querySelector('.a-DatePicker-value');
|
||||
// expect(input.innerHTML).toEqual('01:01');
|
||||
// expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
@ -1052,9 +1052,15 @@ exports[`Renderer:Page initApi reload by Form submit 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="a-Panel-footerWrap"
|
||||
>
|
||||
<div
|
||||
class="a-Panel-btnToolbar a-Panel-footer"
|
||||
>
|
||||
@ -1193,9 +1199,15 @@ exports[`Renderer:Page initApi reload by Form submit 2`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="a-Panel-footerWrap"
|
||||
>
|
||||
<div
|
||||
class="a-Panel-btnToolbar a-Panel-footer"
|
||||
>
|
||||
|
@ -13,7 +13,6 @@ exports[`Renderer:tabs 1`] = `
|
||||
class="a-Tabs-link is-active"
|
||||
>
|
||||
<a>
|
||||
|
||||
基本配置
|
||||
</a>
|
||||
</li>
|
||||
@ -21,7 +20,6 @@ exports[`Renderer:tabs 1`] = `
|
||||
class="a-Tabs-link"
|
||||
>
|
||||
<a>
|
||||
|
||||
其他配置
|
||||
</a>
|
||||
</li>
|
||||
|
@ -2,25 +2,167 @@
|
||||
|
||||
exports[`Renderer:Wizard 1`] = `
|
||||
<div
|
||||
className="a-Alert a-Alert--danger"
|
||||
className="a-Panel a-Panel--default a-Wizard a-Wizard--horizontal"
|
||||
>
|
||||
<p>
|
||||
TypeError: The provided value is not of type 'Element'.
|
||||
</p>
|
||||
<pre>
|
||||
<code>
|
||||
|
||||
in WizardRenderer (created by WithStore(WizardRenderer))
|
||||
in WithStore(WizardRenderer) (created by Scoped(WithStore(WizardRenderer)))
|
||||
in Scoped(WithStore(WizardRenderer)) (created by Renderer)
|
||||
in Renderer (created by RootRenderer)
|
||||
in ImageGallery (created by I18N(ImageGallery))
|
||||
in I18N(ImageGallery) (created by Themeable(I18N(ImageGallery)))
|
||||
in Themeable(I18N(ImageGallery)) (created by RootRenderer)
|
||||
in RootRenderer (created by Scoped(RootRenderer))
|
||||
in Scoped(RootRenderer)
|
||||
</code>
|
||||
</pre>
|
||||
<div
|
||||
className="a-Wizard-step"
|
||||
>
|
||||
<div
|
||||
className="a-Wizard-steps"
|
||||
id="form-wizard"
|
||||
>
|
||||
<ul>
|
||||
<li
|
||||
className="is-active"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<span
|
||||
className="a-Badge is-active"
|
||||
>
|
||||
1
|
||||
</span>
|
||||
Step 1
|
||||
</li>
|
||||
<li
|
||||
className=""
|
||||
onClick={[Function]}
|
||||
>
|
||||
<span
|
||||
className="a-Badge"
|
||||
>
|
||||
2
|
||||
</span>
|
||||
Step 2
|
||||
</li>
|
||||
<li
|
||||
className=""
|
||||
onClick={[Function]}
|
||||
>
|
||||
<span
|
||||
className="a-Badge"
|
||||
>
|
||||
3
|
||||
</span>
|
||||
Step 3
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div
|
||||
className="a-Wizard-stepContent clearfix"
|
||||
role="wizard-body"
|
||||
>
|
||||
<form
|
||||
className="a-Form a-Form--normal"
|
||||
noValidate={true}
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div
|
||||
className="a-Form-item a-Form-item--normal is-required"
|
||||
data-role="form-item"
|
||||
>
|
||||
<label
|
||||
className="a-Form-label"
|
||||
>
|
||||
<span>
|
||||
网址
|
||||
<span
|
||||
className="a-Form-star"
|
||||
>
|
||||
*
|
||||
</span>
|
||||
</span>
|
||||
</label>
|
||||
<div
|
||||
className="a-Form-control a-TextControl"
|
||||
>
|
||||
<div
|
||||
className="a-TextControl-input"
|
||||
>
|
||||
<input
|
||||
autoComplete="off"
|
||||
name="website"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
placeholder=""
|
||||
size={10}
|
||||
type="url"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="a-Form-item a-Form-item--normal is-required"
|
||||
data-role="form-item"
|
||||
>
|
||||
<label
|
||||
className="a-Form-label"
|
||||
>
|
||||
<span>
|
||||
名称
|
||||
<span
|
||||
className="a-Form-star"
|
||||
>
|
||||
*
|
||||
</span>
|
||||
</span>
|
||||
</label>
|
||||
<div
|
||||
className="a-Form-control a-TextControl"
|
||||
>
|
||||
<div
|
||||
className="a-TextControl-input"
|
||||
>
|
||||
<input
|
||||
autoComplete="off"
|
||||
name="name"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
placeholder=""
|
||||
size={10}
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style={
|
||||
Object {
|
||||
"display": "none",
|
||||
}
|
||||
}
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
className="a-Panel-footer a-Wizard-footer"
|
||||
role="wizard-footer"
|
||||
>
|
||||
<button
|
||||
className="a-Button a-Button--default is-disabled"
|
||||
disabled={true}
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
上一步
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
className="a-Button a-Button--default"
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
下一步
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@ -75,6 +217,10 @@ exports[`Renderer:Wizard actionPrevLabel actionNextLabel actionFinishLabel class
|
||||
这是最后一步了
|
||||
</span>
|
||||
</span>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
@ -242,6 +388,10 @@ exports[`Renderer:Wizard actionPrevLabel actionNextLabel actionFinishLabel class
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
@ -435,6 +585,10 @@ exports[`Renderer:Wizard dialog 1`] = `
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
@ -632,6 +786,10 @@ exports[`Renderer:Wizard dialog 2`] = `
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
@ -706,25 +864,167 @@ exports[`Renderer:Wizard dialog 2`] = `
|
||||
|
||||
exports[`Renderer:Wizard initApi 1`] = `
|
||||
<div
|
||||
className="a-Alert a-Alert--danger"
|
||||
className="a-Panel a-Panel--default a-Wizard a-Wizard--horizontal"
|
||||
>
|
||||
<p>
|
||||
TypeError: The provided value is not of type 'Element'.
|
||||
</p>
|
||||
<pre>
|
||||
<code>
|
||||
|
||||
in WizardRenderer (created by WithStore(WizardRenderer))
|
||||
in WithStore(WizardRenderer) (created by Scoped(WithStore(WizardRenderer)))
|
||||
in Scoped(WithStore(WizardRenderer)) (created by Renderer)
|
||||
in Renderer (created by RootRenderer)
|
||||
in ImageGallery (created by I18N(ImageGallery))
|
||||
in I18N(ImageGallery) (created by Themeable(I18N(ImageGallery)))
|
||||
in Themeable(I18N(ImageGallery)) (created by RootRenderer)
|
||||
in RootRenderer (created by Scoped(RootRenderer))
|
||||
in Scoped(RootRenderer)
|
||||
</code>
|
||||
</pre>
|
||||
<div
|
||||
className="a-Wizard-step"
|
||||
>
|
||||
<div
|
||||
className="a-Wizard-steps"
|
||||
id="form-wizard"
|
||||
>
|
||||
<ul>
|
||||
<li
|
||||
className="is-active"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<span
|
||||
className="a-Badge is-active"
|
||||
>
|
||||
1
|
||||
</span>
|
||||
Step 1
|
||||
</li>
|
||||
<li
|
||||
className=""
|
||||
onClick={[Function]}
|
||||
>
|
||||
<span
|
||||
className="a-Badge"
|
||||
>
|
||||
2
|
||||
</span>
|
||||
Step 2
|
||||
</li>
|
||||
<li
|
||||
className=""
|
||||
onClick={[Function]}
|
||||
>
|
||||
<span
|
||||
className="a-Badge"
|
||||
>
|
||||
3
|
||||
</span>
|
||||
Step 3
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div
|
||||
className="a-Wizard-stepContent clearfix"
|
||||
role="wizard-body"
|
||||
>
|
||||
<form
|
||||
className="a-Form a-Form--normal"
|
||||
noValidate={true}
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div
|
||||
className="a-Form-item a-Form-item--normal is-required"
|
||||
data-role="form-item"
|
||||
>
|
||||
<label
|
||||
className="a-Form-label"
|
||||
>
|
||||
<span>
|
||||
网址
|
||||
<span
|
||||
className="a-Form-star"
|
||||
>
|
||||
*
|
||||
</span>
|
||||
</span>
|
||||
</label>
|
||||
<div
|
||||
className="a-Form-control a-TextControl"
|
||||
>
|
||||
<div
|
||||
className="a-TextControl-input"
|
||||
>
|
||||
<input
|
||||
autoComplete="off"
|
||||
name="website"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
placeholder=""
|
||||
size={10}
|
||||
type="url"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="a-Form-item a-Form-item--normal is-required"
|
||||
data-role="form-item"
|
||||
>
|
||||
<label
|
||||
className="a-Form-label"
|
||||
>
|
||||
<span>
|
||||
名称
|
||||
<span
|
||||
className="a-Form-star"
|
||||
>
|
||||
*
|
||||
</span>
|
||||
</span>
|
||||
</label>
|
||||
<div
|
||||
className="a-Form-control a-TextControl"
|
||||
>
|
||||
<div
|
||||
className="a-TextControl-input"
|
||||
>
|
||||
<input
|
||||
autoComplete="off"
|
||||
name="name"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
placeholder=""
|
||||
size={10}
|
||||
type="text"
|
||||
value="Amis renderer"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style={
|
||||
Object {
|
||||
"display": "none",
|
||||
}
|
||||
}
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
className="a-Panel-footer a-Wizard-footer"
|
||||
role="wizard-footer"
|
||||
>
|
||||
<button
|
||||
className="a-Button a-Button--default is-disabled"
|
||||
disabled={true}
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
上一步
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
className="a-Button a-Button--default"
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
下一步
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@ -840,6 +1140,10 @@ exports[`Renderer:Wizard initApi reload 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
@ -975,6 +1279,10 @@ exports[`Renderer:Wizard initApi reload 2`] = `
|
||||
这是最后一步了
|
||||
</span>
|
||||
</span>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
@ -1109,6 +1417,10 @@ exports[`Renderer:Wizard initApi reload 3`] = `
|
||||
这是最后一步了
|
||||
</span>
|
||||
</span>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
@ -1182,73 +1494,393 @@ exports[`Renderer:Wizard initApi reload 3`] = `
|
||||
|
||||
exports[`Renderer:Wizard initApi show loading 1`] = `
|
||||
<div
|
||||
className="a-Alert a-Alert--danger"
|
||||
className="a-Panel a-Panel--default a-Wizard a-Wizard--horizontal"
|
||||
>
|
||||
<p>
|
||||
TypeError: The provided value is not of type 'Element'.
|
||||
</p>
|
||||
<pre>
|
||||
<code>
|
||||
|
||||
in WizardRenderer (created by WithStore(WizardRenderer))
|
||||
in WithStore(WizardRenderer) (created by Scoped(WithStore(WizardRenderer)))
|
||||
in Scoped(WithStore(WizardRenderer)) (created by Renderer)
|
||||
in Renderer (created by RootRenderer)
|
||||
in ImageGallery (created by I18N(ImageGallery))
|
||||
in I18N(ImageGallery) (created by Themeable(I18N(ImageGallery)))
|
||||
in Themeable(I18N(ImageGallery)) (created by RootRenderer)
|
||||
in RootRenderer (created by Scoped(RootRenderer))
|
||||
in Scoped(RootRenderer)
|
||||
</code>
|
||||
</pre>
|
||||
<div
|
||||
className="a-Wizard-step"
|
||||
>
|
||||
<div
|
||||
className="a-Wizard-steps"
|
||||
id="form-wizard"
|
||||
>
|
||||
<ul>
|
||||
<li
|
||||
className=""
|
||||
onClick={[Function]}
|
||||
>
|
||||
<span
|
||||
className="a-Badge"
|
||||
>
|
||||
1
|
||||
</span>
|
||||
Step 1
|
||||
</li>
|
||||
<li
|
||||
className=""
|
||||
onClick={[Function]}
|
||||
>
|
||||
<span
|
||||
className="a-Badge"
|
||||
>
|
||||
2
|
||||
</span>
|
||||
Step 2
|
||||
</li>
|
||||
<li
|
||||
className=""
|
||||
onClick={[Function]}
|
||||
>
|
||||
<span
|
||||
className="a-Badge"
|
||||
>
|
||||
3
|
||||
</span>
|
||||
Step 3
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div
|
||||
className="a-Wizard-stepContent clearfix"
|
||||
role="wizard-body"
|
||||
>
|
||||
加载中
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="a-Spinner-overlay in"
|
||||
/>
|
||||
<div
|
||||
className="a-Spinner in a-Spinner--overlay a-Spinner--lg"
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Renderer:Wizard initApi show loading 2`] = `
|
||||
<div
|
||||
className="a-Alert a-Alert--danger"
|
||||
className="a-Panel a-Panel--default a-Wizard a-Wizard--horizontal"
|
||||
>
|
||||
<p>
|
||||
TypeError: The provided value is not of type 'Element'.
|
||||
</p>
|
||||
<pre>
|
||||
<code>
|
||||
|
||||
in WizardRenderer (created by WithStore(WizardRenderer))
|
||||
in WithStore(WizardRenderer) (created by Scoped(WithStore(WizardRenderer)))
|
||||
in Scoped(WithStore(WizardRenderer)) (created by Renderer)
|
||||
in Renderer (created by RootRenderer)
|
||||
in ImageGallery (created by I18N(ImageGallery))
|
||||
in I18N(ImageGallery) (created by Themeable(I18N(ImageGallery)))
|
||||
in Themeable(I18N(ImageGallery)) (created by RootRenderer)
|
||||
in RootRenderer (created by Scoped(RootRenderer))
|
||||
in Scoped(RootRenderer)
|
||||
</code>
|
||||
</pre>
|
||||
<div
|
||||
className="a-Wizard-step"
|
||||
>
|
||||
<div
|
||||
className="a-Wizard-steps"
|
||||
id="form-wizard"
|
||||
>
|
||||
<ul>
|
||||
<li
|
||||
className="is-active"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<span
|
||||
className="a-Badge is-active"
|
||||
>
|
||||
1
|
||||
</span>
|
||||
Step 1
|
||||
</li>
|
||||
<li
|
||||
className=""
|
||||
onClick={[Function]}
|
||||
>
|
||||
<span
|
||||
className="a-Badge"
|
||||
>
|
||||
2
|
||||
</span>
|
||||
Step 2
|
||||
</li>
|
||||
<li
|
||||
className=""
|
||||
onClick={[Function]}
|
||||
>
|
||||
<span
|
||||
className="a-Badge"
|
||||
>
|
||||
3
|
||||
</span>
|
||||
Step 3
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div
|
||||
className="a-Wizard-stepContent clearfix"
|
||||
role="wizard-body"
|
||||
>
|
||||
<form
|
||||
className="a-Form a-Form--normal"
|
||||
noValidate={true}
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div
|
||||
className="a-Form-item a-Form-item--normal is-required"
|
||||
data-role="form-item"
|
||||
>
|
||||
<label
|
||||
className="a-Form-label"
|
||||
>
|
||||
<span>
|
||||
网址
|
||||
<span
|
||||
className="a-Form-star"
|
||||
>
|
||||
*
|
||||
</span>
|
||||
</span>
|
||||
</label>
|
||||
<div
|
||||
className="a-Form-control a-TextControl"
|
||||
>
|
||||
<div
|
||||
className="a-TextControl-input"
|
||||
>
|
||||
<input
|
||||
autoComplete="off"
|
||||
name="website"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
placeholder=""
|
||||
size={10}
|
||||
type="url"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="a-Form-item a-Form-item--normal is-required"
|
||||
data-role="form-item"
|
||||
>
|
||||
<label
|
||||
className="a-Form-label"
|
||||
>
|
||||
<span>
|
||||
名称
|
||||
<span
|
||||
className="a-Form-star"
|
||||
>
|
||||
*
|
||||
</span>
|
||||
</span>
|
||||
</label>
|
||||
<div
|
||||
className="a-Form-control a-TextControl"
|
||||
>
|
||||
<div
|
||||
className="a-TextControl-input"
|
||||
>
|
||||
<input
|
||||
autoComplete="off"
|
||||
name="name"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
placeholder=""
|
||||
size={10}
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style={
|
||||
Object {
|
||||
"display": "none",
|
||||
}
|
||||
}
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
className="a-Panel-footer a-Wizard-footer"
|
||||
role="wizard-footer"
|
||||
>
|
||||
<button
|
||||
className="a-Button a-Button--default is-disabled"
|
||||
disabled={true}
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
上一步
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
className="a-Button a-Button--default"
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
下一步
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="a-Spinner-overlay"
|
||||
/>
|
||||
<div
|
||||
className="a-Spinner a-Spinner--overlay a-Spinner--lg"
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Renderer:Wizard readOnly 1`] = `
|
||||
<div
|
||||
className="a-Alert a-Alert--danger"
|
||||
className="a-Panel a-Panel--default a-Wizard a-Wizard--horizontal"
|
||||
>
|
||||
<p>
|
||||
TypeError: The provided value is not of type 'Element'.
|
||||
</p>
|
||||
<pre>
|
||||
<code>
|
||||
|
||||
in WizardRenderer (created by WithStore(WizardRenderer))
|
||||
in WithStore(WizardRenderer) (created by Scoped(WithStore(WizardRenderer)))
|
||||
in Scoped(WithStore(WizardRenderer)) (created by Renderer)
|
||||
in Renderer (created by RootRenderer)
|
||||
in ImageGallery (created by I18N(ImageGallery))
|
||||
in I18N(ImageGallery) (created by Themeable(I18N(ImageGallery)))
|
||||
in Themeable(I18N(ImageGallery)) (created by RootRenderer)
|
||||
in RootRenderer (created by Scoped(RootRenderer))
|
||||
in Scoped(RootRenderer)
|
||||
</code>
|
||||
</pre>
|
||||
<div
|
||||
className="a-Wizard-step"
|
||||
>
|
||||
<div
|
||||
className="a-Wizard-steps"
|
||||
id="form-wizard"
|
||||
>
|
||||
<ul>
|
||||
<li
|
||||
className="is-active"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<span
|
||||
className="a-Badge is-active"
|
||||
>
|
||||
1
|
||||
</span>
|
||||
Step 1
|
||||
</li>
|
||||
<li
|
||||
className=""
|
||||
onClick={[Function]}
|
||||
>
|
||||
<span
|
||||
className="a-Badge"
|
||||
>
|
||||
2
|
||||
</span>
|
||||
Step 2
|
||||
</li>
|
||||
<li
|
||||
className=""
|
||||
onClick={[Function]}
|
||||
>
|
||||
<span
|
||||
className="a-Badge"
|
||||
>
|
||||
3
|
||||
</span>
|
||||
Step 3
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div
|
||||
className="a-Wizard-stepContent clearfix"
|
||||
role="wizard-body"
|
||||
>
|
||||
<form
|
||||
className="a-Form a-Form--normal"
|
||||
noValidate={true}
|
||||
onSubmit={[Function]}
|
||||
>
|
||||
<div
|
||||
className="a-Form-item a-Form-item--normal"
|
||||
data-role="form-item"
|
||||
>
|
||||
<label
|
||||
className="a-Form-label"
|
||||
>
|
||||
<span>
|
||||
网址
|
||||
</span>
|
||||
</label>
|
||||
<div
|
||||
className="a-Form-control a-TextControl"
|
||||
>
|
||||
<div
|
||||
className="a-TextControl-input"
|
||||
>
|
||||
<input
|
||||
autoComplete="off"
|
||||
name="website"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
placeholder=""
|
||||
readOnly={true}
|
||||
size={10}
|
||||
type="url"
|
||||
value="http://amis.baidu.com"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="a-Form-item a-Form-item--normal"
|
||||
data-role="form-item"
|
||||
>
|
||||
<label
|
||||
className="a-Form-label"
|
||||
>
|
||||
<span>
|
||||
名称
|
||||
</span>
|
||||
</label>
|
||||
<div
|
||||
className="a-Form-control a-TextControl"
|
||||
>
|
||||
<div
|
||||
className="a-TextControl-input"
|
||||
>
|
||||
<input
|
||||
autoComplete="off"
|
||||
name="name"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
placeholder=""
|
||||
size={10}
|
||||
type="text"
|
||||
value="Amis"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style={
|
||||
Object {
|
||||
"display": "none",
|
||||
}
|
||||
}
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
className="a-Panel-footer a-Wizard-footer"
|
||||
role="wizard-footer"
|
||||
>
|
||||
<button
|
||||
className="a-Button a-Button--default is-disabled"
|
||||
disabled={true}
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
上一步
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
className="a-Button a-Button--default"
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
下一步
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@ -1303,6 +1935,10 @@ exports[`Renderer:Wizard send data 1`] = `
|
||||
这是最后一步了
|
||||
</span>
|
||||
</span>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
@ -1457,6 +2093,10 @@ exports[`Renderer:Wizard step initApi 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
@ -1526,25 +2166,26 @@ exports[`Renderer:Wizard step initApi 1`] = `
|
||||
|
||||
exports[`Renderer:Wizard steps not array 1`] = `
|
||||
<div
|
||||
className="a-Alert a-Alert--danger"
|
||||
className="a-Panel a-Panel--default a-Wizard a-Wizard--horizontal"
|
||||
>
|
||||
<p>
|
||||
TypeError: The provided value is not of type 'Element'.
|
||||
</p>
|
||||
<pre>
|
||||
<code>
|
||||
|
||||
in WizardRenderer (created by WithStore(WizardRenderer))
|
||||
in WithStore(WizardRenderer) (created by Scoped(WithStore(WizardRenderer)))
|
||||
in Scoped(WithStore(WizardRenderer)) (created by Renderer)
|
||||
in Renderer (created by RootRenderer)
|
||||
in ImageGallery (created by I18N(ImageGallery))
|
||||
in I18N(ImageGallery) (created by Themeable(I18N(ImageGallery)))
|
||||
in Themeable(I18N(ImageGallery)) (created by RootRenderer)
|
||||
in RootRenderer (created by Scoped(RootRenderer))
|
||||
in Scoped(RootRenderer)
|
||||
</code>
|
||||
</pre>
|
||||
<div
|
||||
className="a-Wizard-step"
|
||||
>
|
||||
<div
|
||||
className="a-Wizard-steps"
|
||||
id="form-wizard"
|
||||
/>
|
||||
<div
|
||||
className="a-Wizard-stepContent clearfix"
|
||||
role="wizard-body"
|
||||
>
|
||||
<p
|
||||
className="text-danger"
|
||||
>
|
||||
配置错误
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@ -1611,6 +2252,10 @@ exports[`Renderer:Wizard target 1`] = `
|
||||
这是最后一步了
|
||||
</span>
|
||||
</span>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
@ -1757,9 +2402,15 @@ exports[`Renderer:Wizard target 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="a-Panel-footerWrap"
|
||||
>
|
||||
<div
|
||||
class="a-Panel-btnToolbar a-Panel-footer"
|
||||
>
|
||||
@ -1910,7 +2561,7 @@ exports[`Renderer:Wizard validate 1`] = `
|
||||
class="a-Form-feedback"
|
||||
>
|
||||
<li>
|
||||
Url 格式不正确
|
||||
URL 格式不正确
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -1954,6 +2605,10 @@ exports[`Renderer:Wizard validate 1`] = `
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
|
@ -506,7 +506,7 @@ test('tpl-builtin:dataMapping', () => {
|
||||
expect(
|
||||
dataMapping(
|
||||
{
|
||||
'&': data => ({b: data.b})
|
||||
'&': (data: any) => ({b: data.b})
|
||||
},
|
||||
data
|
||||
)
|
||||
@ -604,7 +604,7 @@ test('tpl-builtin:dataMapping', () => {
|
||||
expect(
|
||||
dataMapping(
|
||||
{
|
||||
value: data => data.a
|
||||
value: (data: any) => data.a
|
||||
},
|
||||
data
|
||||
)
|
||||
|
@ -1,429 +1,757 @@
|
||||
import {
|
||||
validate,
|
||||
str2rules
|
||||
} from '../../src/utils/validations';
|
||||
import {validate, str2rules} from '../../src/utils/validations';
|
||||
|
||||
test('validation:isRequired valid', () => {
|
||||
expect(validate('somestring', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'somestring',
|
||||
{},
|
||||
{
|
||||
isRequired: true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
isRequired: 'This is required!'
|
||||
})).toMatchObject([]);
|
||||
}
|
||||
)
|
||||
).toMatchObject([]);
|
||||
});
|
||||
|
||||
test('validation:isRequired invalid', () => {
|
||||
expect(validate('', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'',
|
||||
{},
|
||||
{
|
||||
isRequired: true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
isRequired: 'This is required!'
|
||||
})).toMatchObject(['This is required!']);
|
||||
}
|
||||
)
|
||||
).toMatchObject(['This is required!']);
|
||||
});
|
||||
|
||||
test('validation:isEmail valid', () => {
|
||||
expect(validate('abc@gmail.com', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'abc@gmail.com',
|
||||
{},
|
||||
{
|
||||
isEmail: true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
isEmail: 'Email 格式不正确'
|
||||
})).toMatchObject([]);
|
||||
}
|
||||
)
|
||||
).toMatchObject([]);
|
||||
});
|
||||
|
||||
test('validation:isEmail invalid', () => {
|
||||
expect(validate('somestring', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'somestring',
|
||||
{},
|
||||
{
|
||||
isEmail: true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
isEmail: 'Email 格式不正确'
|
||||
})).toMatchObject(['Email 格式不正确']);
|
||||
}
|
||||
)
|
||||
).toMatchObject(['Email 格式不正确']);
|
||||
});
|
||||
|
||||
test('validation:isUrl valid', () => {
|
||||
expect(validate('http://www.baidu.com', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'http://www.baidu.com',
|
||||
{},
|
||||
{
|
||||
isUrl: true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
isUrl: 'Url 格式不正确'
|
||||
})).toMatchObject([]);
|
||||
}
|
||||
)
|
||||
).toMatchObject([]);
|
||||
});
|
||||
|
||||
test('validation:isUrl invalid', () => {
|
||||
expect(validate('somestring', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'somestring',
|
||||
{},
|
||||
{
|
||||
isUrl: true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
isUrl: 'Url 格式不正确'
|
||||
})).toMatchObject(['Url 格式不正确']);
|
||||
}
|
||||
)
|
||||
).toMatchObject(['Url 格式不正确']);
|
||||
});
|
||||
|
||||
test('validation:isInt valid', () => {
|
||||
expect(validate(1, {}, {
|
||||
expect(
|
||||
validate(
|
||||
1,
|
||||
{},
|
||||
{
|
||||
isInt: true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
isInt: '请输入整型数字'
|
||||
})).toMatchObject([]);
|
||||
}
|
||||
)
|
||||
).toMatchObject([]);
|
||||
});
|
||||
|
||||
test('validation:isInt invalid', () => {
|
||||
expect(validate(1.1, {}, {
|
||||
expect(
|
||||
validate(
|
||||
1.1,
|
||||
{},
|
||||
{
|
||||
isInt: true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
isInt: '请输入整型数字'
|
||||
})).toMatchObject(['请输入整型数字']);
|
||||
}
|
||||
)
|
||||
).toMatchObject(['请输入整型数字']);
|
||||
});
|
||||
|
||||
test('validation:isAlpha valid', () => {
|
||||
expect(validate('a', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'a',
|
||||
{},
|
||||
{
|
||||
isAlpha: true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
isAlpha: '请输入字母'
|
||||
})).toMatchObject([]);
|
||||
}
|
||||
)
|
||||
).toMatchObject([]);
|
||||
});
|
||||
|
||||
test('validation:isAlpha invalid', () => {
|
||||
expect(validate('%', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'%',
|
||||
{},
|
||||
{
|
||||
isAlpha: true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
isAlpha: '请输入字母'
|
||||
})).toMatchObject(['请输入字母']);
|
||||
}
|
||||
)
|
||||
).toMatchObject(['请输入字母']);
|
||||
});
|
||||
|
||||
test('validation:isNumeric valid', () => {
|
||||
expect(validate(1.1, {}, {
|
||||
expect(
|
||||
validate(
|
||||
1.1,
|
||||
{},
|
||||
{
|
||||
isNumeric: true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
isNumeric: '请输入数字'
|
||||
})).toMatchObject([]);
|
||||
}
|
||||
)
|
||||
).toMatchObject([]);
|
||||
});
|
||||
|
||||
test('validation:isNumeric invalid', () => {
|
||||
expect(validate('a', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'a',
|
||||
{},
|
||||
{
|
||||
isNumeric: true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
isNumeric: '请输入数字'
|
||||
})).toMatchObject(['请输入数字']);
|
||||
}
|
||||
)
|
||||
).toMatchObject(['请输入数字']);
|
||||
});
|
||||
|
||||
test('validation:isAlphanumeric Alpha valid', () => {
|
||||
expect(validate('a', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'a',
|
||||
{},
|
||||
{
|
||||
isAlphanumeric: true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
isAlphanumeric: '请输入数字'
|
||||
})).toMatchObject([]);
|
||||
}
|
||||
)
|
||||
).toMatchObject([]);
|
||||
});
|
||||
|
||||
test('validation:isAlphanumeric numeric valid', () => {
|
||||
expect(validate(1, {}, {
|
||||
expect(
|
||||
validate(
|
||||
1,
|
||||
{},
|
||||
{
|
||||
isAlphanumeric: true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
isAlphanumeric: '请输入字母或者数字'
|
||||
})).toMatchObject([]);
|
||||
}
|
||||
)
|
||||
).toMatchObject([]);
|
||||
});
|
||||
|
||||
test('validation:isAlphanumeric invalid', () => {
|
||||
expect(validate('%', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'%',
|
||||
{},
|
||||
{
|
||||
isAlphanumeric: true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
isAlphanumeric: '请输入字母或者数字'
|
||||
})).toMatchObject(['请输入字母或者数字']);
|
||||
}
|
||||
)
|
||||
).toMatchObject(['请输入字母或者数字']);
|
||||
});
|
||||
|
||||
test('validation:isFloat valid', () => {
|
||||
expect(validate(1.1, {}, {
|
||||
expect(
|
||||
validate(
|
||||
1.1,
|
||||
{},
|
||||
{
|
||||
isFloat: true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
isFloat: '请输入浮点型数值'
|
||||
})).toMatchObject([]);
|
||||
}
|
||||
)
|
||||
).toMatchObject([]);
|
||||
});
|
||||
|
||||
test('validation:isFloat invalid', () => {
|
||||
expect(validate('a', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'a',
|
||||
{},
|
||||
{
|
||||
isFloat: true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
isFloat: '请输入浮点型数值'
|
||||
})).toMatchObject(['请输入浮点型数值']);
|
||||
}
|
||||
)
|
||||
).toMatchObject(['请输入浮点型数值']);
|
||||
});
|
||||
|
||||
test('validation:isWords valid', () => {
|
||||
expect(validate('baidu', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'baidu',
|
||||
{},
|
||||
{
|
||||
isWords: true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
isWords: '请输入字母'
|
||||
})).toMatchObject([]);
|
||||
}
|
||||
)
|
||||
).toMatchObject([]);
|
||||
});
|
||||
|
||||
test('validation:isWords invalid', () => {
|
||||
expect(validate('%', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'%',
|
||||
{},
|
||||
{
|
||||
isWords: true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
isWords: '请输入字母'
|
||||
})).toMatchObject(['请输入字母']);
|
||||
}
|
||||
)
|
||||
).toMatchObject(['请输入字母']);
|
||||
});
|
||||
|
||||
test('validation:isUrlPath valid', () => {
|
||||
expect(validate('baidu-fex_team', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'baidu-fex_team',
|
||||
{},
|
||||
{
|
||||
isUrlPath: true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
isUrlPath: '只能输入字母、数字、`-` 和 `_`'
|
||||
})).toMatchObject([]);
|
||||
}
|
||||
)
|
||||
).toMatchObject([]);
|
||||
});
|
||||
|
||||
test('validation:isUrlPath invalid', () => {
|
||||
expect(validate('baidu&fex%team', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'baidu&fex%team',
|
||||
{},
|
||||
{
|
||||
isUrlPath: true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
isUrlPath: '只能输入字母、数字、`-` 和 `_`'
|
||||
})).toMatchObject(['只能输入字母、数字、`-` 和 `_`']);
|
||||
}
|
||||
)
|
||||
).toMatchObject(['只能输入字母、数字、`-` 和 `_`']);
|
||||
});
|
||||
|
||||
test('validation:minLength valid', () => {
|
||||
expect(validate('abcdef', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'abcdef',
|
||||
{},
|
||||
{
|
||||
minLength: 5
|
||||
}, {
|
||||
},
|
||||
{
|
||||
minLength: '请至少输入 5 个字符。'
|
||||
})).toMatchObject([]);
|
||||
}
|
||||
)
|
||||
).toMatchObject([]);
|
||||
});
|
||||
|
||||
test('validation:minLength invalid', () => {
|
||||
expect(validate('abcd', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'abcd',
|
||||
{},
|
||||
{
|
||||
minLength: 5
|
||||
}, {
|
||||
},
|
||||
{
|
||||
minLength: '至少输入 5 个字符。'
|
||||
})).toMatchObject(['至少输入 5 个字符。']);
|
||||
}
|
||||
)
|
||||
).toMatchObject(['至少输入 5 个字符。']);
|
||||
});
|
||||
|
||||
test('validation:maxLength valid', () => {
|
||||
expect(validate('abcde', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'abcde',
|
||||
{},
|
||||
{
|
||||
maxLength: 5
|
||||
}, {
|
||||
},
|
||||
{
|
||||
maxLength: '请不要输入 5 个字符以上'
|
||||
})).toMatchObject([]);
|
||||
}
|
||||
)
|
||||
).toMatchObject([]);
|
||||
});
|
||||
|
||||
test('validation:maxLength invalid', () => {
|
||||
expect(validate('abcded', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'abcded',
|
||||
{},
|
||||
{
|
||||
maxLength: 5
|
||||
}, {
|
||||
},
|
||||
{
|
||||
maxLength: '请不要输入 5 个字符以上'
|
||||
})).toMatchObject(['请不要输入 5 个字符以上']);
|
||||
}
|
||||
)
|
||||
).toMatchObject(['请不要输入 5 个字符以上']);
|
||||
});
|
||||
|
||||
test('validation:minimum valid', () => {
|
||||
expect(validate(6, {}, {
|
||||
expect(
|
||||
validate(
|
||||
6,
|
||||
{},
|
||||
{
|
||||
minimum: 5
|
||||
}, {
|
||||
},
|
||||
{
|
||||
minimum: '当前输入值低于最小值 5,请检查'
|
||||
})).toMatchObject([]);
|
||||
}
|
||||
)
|
||||
).toMatchObject([]);
|
||||
});
|
||||
|
||||
test('validation:minimum invalid', () => {
|
||||
expect(validate(4, {}, {
|
||||
expect(
|
||||
validate(
|
||||
4,
|
||||
{},
|
||||
{
|
||||
minimum: 5
|
||||
}, {
|
||||
},
|
||||
{
|
||||
minimum: '当前输入值低于最小值 5,请检查'
|
||||
})).toMatchObject(['当前输入值低于最小值 5,请检查']);
|
||||
}
|
||||
)
|
||||
).toMatchObject(['当前输入值低于最小值 5,请检查']);
|
||||
});
|
||||
|
||||
test('validation:maximum valid', () => {
|
||||
expect(validate(5, {}, {
|
||||
expect(
|
||||
validate(
|
||||
5,
|
||||
{},
|
||||
{
|
||||
maximum: 5
|
||||
}, {
|
||||
},
|
||||
{
|
||||
maximum: '当前输入值超出最大值 5,请检查'
|
||||
})).toMatchObject([]);
|
||||
}
|
||||
)
|
||||
).toMatchObject([]);
|
||||
});
|
||||
|
||||
test('validation:maximum invalid', () => {
|
||||
expect(validate(6, {}, {
|
||||
expect(
|
||||
validate(
|
||||
6,
|
||||
{},
|
||||
{
|
||||
maximum: 5
|
||||
}, {
|
||||
},
|
||||
{
|
||||
maximum: '当前输入值超出最大值 5,请检查'
|
||||
})).toMatchObject(['当前输入值超出最大值 5,请检查']);
|
||||
}
|
||||
)
|
||||
).toMatchObject(['当前输入值超出最大值 5,请检查']);
|
||||
});
|
||||
|
||||
test('validation:isJson valid', () => {
|
||||
expect(validate('{ "type": "select", "options": [ { "label": "A", "value": "a" } ] }', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'{ "type": "select", "options": [ { "label": "A", "value": "a" } ] }',
|
||||
{},
|
||||
{
|
||||
isJson: true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
isJson: '请检查 Json 格式'
|
||||
})).toMatchObject([]);
|
||||
}
|
||||
)
|
||||
).toMatchObject([]);
|
||||
});
|
||||
|
||||
test('validation:isJson invalid', () => {
|
||||
expect(validate('string', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'string',
|
||||
{},
|
||||
{
|
||||
isJson: true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
isJson: '请检查 Json 格式'
|
||||
})).toMatchObject(['请检查 Json 格式']);
|
||||
}
|
||||
)
|
||||
).toMatchObject(['请检查 Json 格式']);
|
||||
});
|
||||
|
||||
test('validation:isLength valid', () => {
|
||||
expect(validate('abcde', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'abcde',
|
||||
{},
|
||||
{
|
||||
isLength: 5
|
||||
}, {
|
||||
},
|
||||
{
|
||||
isLength: '请输入长度为 5 的内容'
|
||||
})).toMatchObject([]);
|
||||
}
|
||||
)
|
||||
).toMatchObject([]);
|
||||
});
|
||||
|
||||
test('validation:isLength invalid', () => {
|
||||
expect(validate('abc', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'abc',
|
||||
{},
|
||||
{
|
||||
isLength: 5
|
||||
}, {
|
||||
},
|
||||
{
|
||||
isLength: '请输入长度为 5 的内容'
|
||||
})).toMatchObject(['请输入长度为 5 的内容']);
|
||||
}
|
||||
)
|
||||
).toMatchObject(['请输入长度为 5 的内容']);
|
||||
});
|
||||
|
||||
test('validation:notEmptyString valid', () => {
|
||||
expect(validate('abc', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'abc',
|
||||
{},
|
||||
{
|
||||
notEmptyString: true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
notEmptyString: '请不要全输入空白字符'
|
||||
})).toMatchObject([]);
|
||||
}
|
||||
)
|
||||
).toMatchObject([]);
|
||||
});
|
||||
|
||||
test('validation:notEmptyString invalid', () => {
|
||||
expect(validate(' ', {}, {
|
||||
expect(
|
||||
validate(
|
||||
' ',
|
||||
{},
|
||||
{
|
||||
notEmptyString: true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
notEmptyString: '请不要全输入空白字符'
|
||||
})).toMatchObject(['请不要全输入空白字符']);
|
||||
}
|
||||
)
|
||||
).toMatchObject(['请不要全输入空白字符']);
|
||||
});
|
||||
|
||||
test('validation:equalsField valid', () => {
|
||||
expect(validate('a', {
|
||||
expect(
|
||||
validate(
|
||||
'a',
|
||||
{
|
||||
a: 'a'
|
||||
}, {
|
||||
},
|
||||
{
|
||||
equalsField: 'a'
|
||||
}, {
|
||||
},
|
||||
{
|
||||
equalsField: '输入的数据与 a 值不一致'
|
||||
})).toMatchObject([]);
|
||||
}
|
||||
)
|
||||
).toMatchObject([]);
|
||||
});
|
||||
|
||||
test('validation:equalsField invalid', () => {
|
||||
expect(validate('b', {
|
||||
expect(
|
||||
validate(
|
||||
'b',
|
||||
{
|
||||
a: 'a'
|
||||
}, {
|
||||
},
|
||||
{
|
||||
equalsField: 'a'
|
||||
}, {
|
||||
},
|
||||
{
|
||||
equalsField: '输入的数据与 a 值不一致'
|
||||
})).toMatchObject(['输入的数据与 a 值不一致']);
|
||||
}
|
||||
)
|
||||
).toMatchObject(['输入的数据与 a 值不一致']);
|
||||
});
|
||||
|
||||
test('validation:equals valid', () => {
|
||||
expect(validate('a', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'a',
|
||||
{},
|
||||
{
|
||||
equals: 'a'
|
||||
}, {
|
||||
},
|
||||
{
|
||||
equals: '输入的数据与 a 不一致'
|
||||
})).toMatchObject([]);
|
||||
}
|
||||
)
|
||||
).toMatchObject([]);
|
||||
});
|
||||
|
||||
test('validation:equals invalid', () => {
|
||||
expect(validate('b', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'b',
|
||||
{},
|
||||
{
|
||||
equals: 'a'
|
||||
}, {
|
||||
},
|
||||
{
|
||||
equals: '输入的数据与 a 不一致'
|
||||
})).toMatchObject(['输入的数据与 a 不一致']);
|
||||
}
|
||||
)
|
||||
).toMatchObject(['输入的数据与 a 不一致']);
|
||||
});
|
||||
|
||||
test('validation:multipleRules invalid', () => {
|
||||
expect(validate('abc', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'abc',
|
||||
{},
|
||||
{
|
||||
isUrl: true,
|
||||
isInt: true
|
||||
})).toMatchObject(['Url 格式不正确', '请输入整型数字']);
|
||||
}
|
||||
)
|
||||
).toMatchObject(['validate.isUrl', 'validate.isInt']);
|
||||
});
|
||||
|
||||
test('validation:matchRegexp valid', () => {
|
||||
expect(validate('abcd', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'abcd',
|
||||
{},
|
||||
{
|
||||
matchRegexp: '/^abc/'
|
||||
}, {
|
||||
},
|
||||
{
|
||||
matchRegexp: '请输入abc开头的好么'
|
||||
})).toMatchObject([]);
|
||||
}
|
||||
)
|
||||
).toMatchObject([]);
|
||||
});
|
||||
|
||||
test('validation:matchRegexp invalid', () => {
|
||||
expect(validate('cba', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'cba',
|
||||
{},
|
||||
{
|
||||
matchRegexp: '/^abc/'
|
||||
}, {
|
||||
},
|
||||
{
|
||||
matchRegexp: '请输入abc开头的好么'
|
||||
})).toMatchObject(['请输入abc开头的好么']);
|
||||
}
|
||||
)
|
||||
).toMatchObject(['请输入abc开头的好么']);
|
||||
});
|
||||
|
||||
test('validation:matchRegexp:noSlash valid', () => {
|
||||
expect(validate('abcd', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'abcd',
|
||||
{},
|
||||
{
|
||||
matchRegexp: '^abc'
|
||||
}, {
|
||||
},
|
||||
{
|
||||
matchRegexp: '请输入abc开头的好么'
|
||||
})).toMatchObject([]);
|
||||
}
|
||||
)
|
||||
).toMatchObject([]);
|
||||
});
|
||||
|
||||
test('validation:matchRegexp:noSlash invalid', () => {
|
||||
expect(validate('cba', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'cba',
|
||||
{},
|
||||
{
|
||||
matchRegexp: '^abc'
|
||||
}, {
|
||||
},
|
||||
{
|
||||
matchRegexp: '请输入abc开头的好么'
|
||||
})).toMatchObject(['请输入abc开头的好么']);
|
||||
}
|
||||
)
|
||||
).toMatchObject(['请输入abc开头的好么']);
|
||||
});
|
||||
|
||||
test('validation:multipleMatchRegexp valid', () => {
|
||||
expect(validate('abcd123', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'abcd123',
|
||||
{},
|
||||
{
|
||||
matchRegexp1: '/^abc/',
|
||||
matchRegexp2: '/123$/',
|
||||
}, {
|
||||
matchRegexp2: '/123$/'
|
||||
},
|
||||
{
|
||||
matchRegexp1: '请输入abc开头的好么',
|
||||
matchRegexp2: '请输入123结尾的好么',
|
||||
})).toMatchObject([]);
|
||||
matchRegexp2: '请输入123结尾的好么'
|
||||
}
|
||||
)
|
||||
).toMatchObject([]);
|
||||
});
|
||||
|
||||
test('validation:multipleMatchRegexp invalid', () => {
|
||||
expect(validate('cba', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'cba',
|
||||
{},
|
||||
{
|
||||
matchRegexp1: '/^abc/',
|
||||
matchRegexp2: '/123$/',
|
||||
}, {
|
||||
matchRegexp2: '/123$/'
|
||||
},
|
||||
{
|
||||
matchRegexp1: '请输入abc开头的好么',
|
||||
matchRegexp2: '请输入123结尾的好么',
|
||||
})).toMatchObject(['请输入abc开头的好么', '请输入123结尾的好么']);
|
||||
matchRegexp2: '请输入123结尾的好么'
|
||||
}
|
||||
)
|
||||
).toMatchObject(['请输入abc开头的好么', '请输入123结尾的好么']);
|
||||
});
|
||||
|
||||
test('validation:multipleMatchRegexp:noSlash valid', () => {
|
||||
expect(validate('abcd123', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'abcd123',
|
||||
{},
|
||||
{
|
||||
matchRegexp1: '^abc',
|
||||
matchRegexp2: '123$',
|
||||
}, {
|
||||
matchRegexp2: '123$'
|
||||
},
|
||||
{
|
||||
matchRegexp1: '请输入abc开头的好么',
|
||||
matchRegexp2: '请输入123结尾的好么',
|
||||
})).toMatchObject([]);
|
||||
matchRegexp2: '请输入123结尾的好么'
|
||||
}
|
||||
)
|
||||
).toMatchObject([]);
|
||||
});
|
||||
|
||||
test('validation:multipleMatchRegexp:noSlash invalid', () => {
|
||||
expect(validate('cba', {}, {
|
||||
expect(
|
||||
validate(
|
||||
'cba',
|
||||
{},
|
||||
{
|
||||
matchRegexp1: '^abc',
|
||||
matchRegexp2: '123$',
|
||||
}, {
|
||||
matchRegexp2: '123$'
|
||||
},
|
||||
{
|
||||
matchRegexp1: '请输入abc开头的好么',
|
||||
matchRegexp2: '请输入123结尾的好么',
|
||||
})).toMatchObject(['请输入abc开头的好么', '请输入123结尾的好么']);
|
||||
matchRegexp2: '请输入123结尾的好么'
|
||||
}
|
||||
)
|
||||
).toMatchObject(['请输入abc开头的好么', '请输入123结尾的好么']);
|
||||
});
|
||||
|
||||
test('validation:str2rules', () => {
|
||||
expect(str2rules('matchRegexp:/^abc/'))
|
||||
.toMatchObject({
|
||||
matchRegexp: ['/^abc/']
|
||||
});
|
||||
expect(str2rules('matchRegexp:/^abc/')).toMatchObject({
|
||||
matchRegexp: ['/^abc/']
|
||||
});
|
||||
});
|
||||
|
||||
test('validation:multiplestr2rules', () => {
|
||||
expect(str2rules('matchRegexp1:/^abc/,matchRegexp2:/123$/'))
|
||||
.toMatchObject({
|
||||
matchRegexp1: ['/^abc/'],
|
||||
matchRegexp2: ['/123$/']
|
||||
});
|
||||
expect(str2rules('matchRegexp1:/^abc/,matchRegexp2:/123$/')).toMatchObject({
|
||||
matchRegexp1: ['/^abc/'],
|
||||
matchRegexp2: ['/123$/']
|
||||
});
|
||||
});
|
||||
|
||||
test('validation:str2rules:noSlash', () => {
|
||||
expect(str2rules('matchRegexp:^abc'))
|
||||
.toMatchObject({
|
||||
matchRegexp: ['^abc']
|
||||
});
|
||||
expect(str2rules('matchRegexp:^abc')).toMatchObject({
|
||||
matchRegexp: ['^abc']
|
||||
});
|
||||
});
|
||||
|
||||
test('validation:multiplestr2rules:noSlash', () => {
|
||||
expect(str2rules('matchRegexp1:^abc,matchRegexp2:123$'))
|
||||
.toMatchObject({
|
||||
matchRegexp1: ['^abc'],
|
||||
matchRegexp2: ['123$']
|
||||
});
|
||||
});
|
||||
expect(str2rules('matchRegexp1:^abc,matchRegexp2:123$')).toMatchObject({
|
||||
matchRegexp1: ['^abc'],
|
||||
matchRegexp2: ['123$']
|
||||
});
|
||||
});
|
||||
|
@ -250,6 +250,7 @@
|
||||
> th {
|
||||
background: var(--Table-thead-bg);
|
||||
|
||||
text-align: left;
|
||||
&[colspan] {
|
||||
text-align: center;
|
||||
}
|
||||
|
@ -4,7 +4,9 @@
|
||||
|
||||
import {findObjectsWithKey} from './utils/helper';
|
||||
|
||||
const isMobile = window.matchMedia('(max-width: 768px)').matches ? true : false;
|
||||
const isMobile = (window as any).matchMedia?.('(max-width: 768px)').matches
|
||||
? true
|
||||
: false;
|
||||
|
||||
export const envOverwrite = (schema: any, locale?: string) => {
|
||||
if (schema.mobile && isMobile) {
|
||||
|
@ -116,6 +116,7 @@ export interface AjaxActionSchema extends ButtonSchema {
|
||||
|
||||
reload?: SchemaReload;
|
||||
redirect?: string;
|
||||
ignoreConfirm?: boolean;
|
||||
}
|
||||
|
||||
export interface UrlActionSchema extends ButtonSchema {
|
||||
@ -443,9 +444,9 @@ export class ActionRenderer extends React.Component<
|
||||
> {
|
||||
@autobind
|
||||
handleAction(e: React.MouseEvent<any> | void | null, action: any) {
|
||||
const {env, onAction, data} = this.props;
|
||||
const {env, onAction, data, ignoreConfirm} = this.props;
|
||||
|
||||
if (action.confirmText && env.confirm) {
|
||||
if (!ignoreConfirm && action.confirmText && env.confirm) {
|
||||
env
|
||||
.confirm(filter(action.confirmText, data))
|
||||
.then((confirmed: boolean) => confirmed && onAction(e, action, data));
|
||||
|
@ -376,7 +376,7 @@ export default class CRUD extends React.Component<CRUDProps, any> {
|
||||
control: any;
|
||||
lastQuery: any;
|
||||
dataInvalid: boolean = false;
|
||||
timer: NodeJS.Timeout;
|
||||
timer: NodeJS.Timeout | number;
|
||||
mounted: boolean;
|
||||
constructor(props: CRUDProps) {
|
||||
super(props);
|
||||
@ -646,44 +646,59 @@ export default class CRUD extends React.Component<CRUDProps, any> {
|
||||
ids
|
||||
});
|
||||
|
||||
if (action.actionType === 'dialog') {
|
||||
return this.handleAction(
|
||||
e,
|
||||
{
|
||||
...action,
|
||||
__from: 'bulkAction'
|
||||
},
|
||||
ctx
|
||||
);
|
||||
} else if (action.actionType === 'ajax') {
|
||||
isEffectiveApi(action.api, ctx) &&
|
||||
store
|
||||
.saveRemote(action.api as string, ctx, {
|
||||
successMessage:
|
||||
(action.messages && action.messages.success) ||
|
||||
(messages && messages.saveSuccess),
|
||||
errorMessage:
|
||||
(action.messages && action.messages.failed) ||
|
||||
(messages && messages.saveFailed)
|
||||
})
|
||||
.then(async (payload: object) => {
|
||||
const data = createObject(ctx, payload);
|
||||
if (action.feedback && isVisible(action.feedback, data)) {
|
||||
await this.openFeedback(action.feedback, data);
|
||||
stopAutoRefreshWhenModalIsOpen && clearTimeout(this.timer);
|
||||
}
|
||||
let fn = () => {
|
||||
if (action.actionType === 'dialog') {
|
||||
return this.handleAction(
|
||||
e,
|
||||
{
|
||||
...action,
|
||||
__from: 'bulkAction'
|
||||
},
|
||||
ctx
|
||||
);
|
||||
} else if (action.actionType === 'ajax') {
|
||||
isEffectiveApi(action.api, ctx) &&
|
||||
store
|
||||
.saveRemote(action.api as string, ctx, {
|
||||
successMessage:
|
||||
(action.messages && action.messages.success) ||
|
||||
(messages && messages.saveSuccess),
|
||||
errorMessage:
|
||||
(action.messages && action.messages.failed) ||
|
||||
(messages && messages.saveFailed)
|
||||
})
|
||||
.then(async (payload: object) => {
|
||||
const data = createObject(ctx, payload);
|
||||
if (action.feedback && isVisible(action.feedback, data)) {
|
||||
await this.openFeedback(action.feedback, data);
|
||||
stopAutoRefreshWhenModalIsOpen && clearTimeout(this.timer);
|
||||
}
|
||||
|
||||
action.reload
|
||||
? this.reloadTarget(action.reload, data)
|
||||
: this.search({[pageField || 'page']: 1}, undefined, true, true);
|
||||
action.close && this.closeTarget(action.close);
|
||||
action.reload
|
||||
? this.reloadTarget(action.reload, data)
|
||||
: this.search(
|
||||
{[pageField || 'page']: 1},
|
||||
undefined,
|
||||
true,
|
||||
true
|
||||
);
|
||||
action.close && this.closeTarget(action.close);
|
||||
|
||||
const redirect = action.redirect && filter(action.redirect, data);
|
||||
redirect && env.jumpTo(redirect, action);
|
||||
})
|
||||
.catch(() => null);
|
||||
} else if (onAction) {
|
||||
onAction(e, action, ctx, false, this.context);
|
||||
const redirect = action.redirect && filter(action.redirect, data);
|
||||
redirect && env.jumpTo(redirect, action);
|
||||
})
|
||||
.catch(() => null);
|
||||
} else if (onAction) {
|
||||
onAction(e, action, ctx, false, this.context);
|
||||
}
|
||||
};
|
||||
|
||||
if (action.confirmText && env.confirm) {
|
||||
env
|
||||
.confirm(filter(action.confirmText, ctx))
|
||||
.then((confirmed: boolean) => confirmed && fn());
|
||||
} else {
|
||||
fn();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1538,7 +1553,8 @@ export default class CRUD extends React.Component<CRUDProps, any> {
|
||||
{
|
||||
size: 'sm',
|
||||
...omit(btn, ['visibleOn', 'hiddenOn', 'disabledOn']),
|
||||
type: 'button'
|
||||
type: 'button',
|
||||
ignoreConfirm: true
|
||||
},
|
||||
{
|
||||
key: `bulk-${index}`,
|
||||
|
@ -278,6 +278,10 @@ export default class Wizard extends React.Component<WizardProps, WizardState> {
|
||||
}
|
||||
|
||||
const dom = findDOMNode(this) as HTMLElement;
|
||||
if (!(dom instanceof Element)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let parent: HTMLElement | Window | null = dom ? getScrollParent(dom) : null;
|
||||
if (!parent || parent === document.body) {
|
||||
parent = window;
|
||||
|
@ -347,6 +347,8 @@ export const filters: {
|
||||
last: input => input && (input.length ? input[input.length - 1] : null),
|
||||
minus: (input, step = 1) => (parseInt(input, 10) || 0) - parseInt(step, 10),
|
||||
plus: (input, step = 1) => (parseInt(input, 10) || 0) + parseInt(step, 10),
|
||||
count: (input: any) =>
|
||||
Array.isArray(input) || typeof input === 'string' ? input.length : 0,
|
||||
sum: (input, field) =>
|
||||
Array.isArray(input)
|
||||
? input.reduce(
|
||||
|
@ -19,7 +19,8 @@
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"typeRoots": ["./node_modules/@types", "./types"],
|
||||
"skipLibCheck": true
|
||||
"skipLibCheck": true,
|
||||
"types": ["node", "typePatches"]
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "acceptance-tests", "webpack", "jest"],
|
||||
|
Loading…
Reference in New Issue
Block a user