mirror of
https://github.com/getrebuild/rebuild.git
synced 2024-09-20 07:25:54 +08:00
better FROM/LIST
This commit is contained in:
parent
c87381e5fe
commit
29cc020b63
1934
package-lock.json
generated
1934
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -412,7 +412,7 @@ class ApprovalApproveForm extends ApprovalUsersForm {
|
|||
|
||||
_renderEditableForm() {
|
||||
const fake = {
|
||||
state: { id: this.props.id, __formModel: {} },
|
||||
state: { id: this.props.id },
|
||||
}
|
||||
return (
|
||||
<div className="form-group">
|
||||
|
@ -478,7 +478,7 @@ class ApprovalApproveForm extends ApprovalUsersForm {
|
|||
// eslint-disable-next-line no-undef
|
||||
class EditableForm extends RbForm {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
super({ ...props, rawModel: {} })
|
||||
}
|
||||
|
||||
renderFormAction() {
|
||||
|
|
|
@ -1058,7 +1058,7 @@ class RbGritter extends React.Component {
|
|||
*
|
||||
* @param {*} jsx
|
||||
* @param {*} target id or object of element (or function of callback)
|
||||
* @param {*} call callback
|
||||
* @param {*} call callback on mounted
|
||||
*/
|
||||
const renderRbcomp = function (jsx, target, call) {
|
||||
if (typeof target === 'function') {
|
||||
|
@ -1079,6 +1079,8 @@ const renderRbcomp = function (jsx, target, call) {
|
|||
} else if (target instanceof $) {
|
||||
target = target[0]
|
||||
}
|
||||
|
||||
// ReactDOM.render(<React.StrictMode>{jsx}</React.StrictMode>, target, call)
|
||||
ReactDOM.render(jsx, target, call)
|
||||
return target
|
||||
}
|
||||
|
|
|
@ -7,6 +7,10 @@ See LICENSE and COMMERCIAL in the project root for license information.
|
|||
/* global FieldValueSet */
|
||||
// 列表公共操作
|
||||
|
||||
const _RbList = function () {
|
||||
return RbListPage._RbList || {}
|
||||
}
|
||||
|
||||
// ~~ 高级查询操作类
|
||||
|
||||
const AdvFilters = {
|
||||
|
@ -18,18 +22,18 @@ const AdvFilters = {
|
|||
this.__el = $(el)
|
||||
this.__entity = entity
|
||||
|
||||
this.__el.find('.J_advfilter').click(() => {
|
||||
this.__el.find('.J_advfilter').on('click', () => {
|
||||
this.showAdvFilter(null, this.current)
|
||||
this.current = null
|
||||
})
|
||||
const $all = $('.adv-search .dropdown-item:eq(0)')
|
||||
$all.click(() => this._effectFilter($all, 'aside'))
|
||||
$all.on('click', () => this._effectFilter($all, 'aside'))
|
||||
|
||||
this.loadFilters()
|
||||
},
|
||||
|
||||
loadFilters() {
|
||||
const lastFilter = $storage.get(RbListPage._RbList.__defaultFilterKey)
|
||||
const lastFilter = $storage.get(_RbList().__defaultFilterKey)
|
||||
|
||||
const that = this
|
||||
let $defaultFilter
|
||||
|
@ -43,7 +47,7 @@ const AdvFilters = {
|
|||
$(res.data).each(function () {
|
||||
const item = this
|
||||
const $item = $(`<div class="dropdown-item J_custom" data-id="${item.id}"><a class="text-truncate">${item.name}</a></div>`).appendTo($menu)
|
||||
$item.click(() => that._effectFilter($item, 'aside'))
|
||||
$item.on('click', () => that._effectFilter($item, 'aside'))
|
||||
|
||||
if (lastFilter === item.id) $defaultFilter = $item
|
||||
|
||||
|
@ -53,13 +57,13 @@ const AdvFilters = {
|
|||
`<div class="action"><a title="${$L('修改')}"><i class="zmdi zmdi-edit"></i></a><a title="${$L('删除')}" class="danger-hover"><i class="zmdi zmdi-delete"></i></a></div>`
|
||||
).appendTo($item)
|
||||
|
||||
$action.find('a:eq(0)').click(function () {
|
||||
$action.find('a:eq(0)').on('click', function () {
|
||||
that.showAdvFilter(item.id)
|
||||
$('.adv-search .btn.dropdown-toggle').dropdown('toggle')
|
||||
return false
|
||||
})
|
||||
|
||||
$action.find('a:eq(1)').click(function () {
|
||||
$action.find('a:eq(1)').on('click', function () {
|
||||
RbAlert.create($L('确认删除此高级查询?'), {
|
||||
type: 'danger',
|
||||
confirmText: $L('删除'),
|
||||
|
@ -70,7 +74,7 @@ const AdvFilters = {
|
|||
this.hide()
|
||||
that.loadFilters()
|
||||
if (lastFilter === item.id) {
|
||||
RbListPage._RbList.setAdvFilter(null)
|
||||
_RbList().setAdvFilter(null)
|
||||
$('.adv-search .J_name').text($L('全部数据'))
|
||||
}
|
||||
} else {
|
||||
|
@ -91,7 +95,7 @@ const AdvFilters = {
|
|||
$ghost.removeAttr('style')
|
||||
$ghost.removeAttr('data-ps-id')
|
||||
$ghost.find('.ps-scrollbar-x-rail, .ps-scrollbar-y-rail').remove()
|
||||
$ghost.find('.dropdown-item').click(function () {
|
||||
$ghost.find('.dropdown-item').on('click', function () {
|
||||
$ghost.find('.dropdown-item').removeClass('active')
|
||||
$(this).addClass('active')
|
||||
that._effectFilter($(this), 'aside')
|
||||
|
@ -120,7 +124,7 @@ const AdvFilters = {
|
|||
}
|
||||
|
||||
if (this.current === '$ALL$') this.current = null
|
||||
RbListPage._RbList.setAdvFilter(this.current)
|
||||
_RbList().setAdvFilter(this.current)
|
||||
},
|
||||
|
||||
showAdvFilter(id, useCopyId) {
|
||||
|
@ -165,7 +169,7 @@ const AdvFilters = {
|
|||
|
||||
$.post(url, JSON.stringify(filter), (res) => {
|
||||
if (res.error_code === 0) {
|
||||
$storage.set(RbListPage._RbList.__defaultFilterKey, res.data.id)
|
||||
$storage.set(_RbList().__defaultFilterKey, res.data.id)
|
||||
that.loadFilters()
|
||||
} else {
|
||||
RbHighbar.error(res.error_msg)
|
||||
|
@ -564,7 +568,7 @@ const RbListCommon = {
|
|||
// 快速查询
|
||||
const $btn = $('.input-search .input-group-btn .btn'),
|
||||
$input = $('.input-search input')
|
||||
$btn.on('click', () => RbListPage._RbList.searchQuick())
|
||||
$btn.on('click', () => _RbList().searchQuick())
|
||||
$input.on('keydown', (e) => {
|
||||
e.which === 13 && $btn.trigger('click')
|
||||
})
|
||||
|
@ -578,7 +582,7 @@ const RbListCommon = {
|
|||
if (via) {
|
||||
wpc.protocolFilter = `via:${via}`
|
||||
const $cleanVia = $(`<div class="badge filter-badge">${$L('当前数据已过滤')}<a class="close" title="${$L('查看全部数据')}">×</a></div>`).appendTo('.dataTables_filter')
|
||||
$cleanVia.find('a').click(() => {
|
||||
$cleanVia.find('a').on('click', () => {
|
||||
wpc.protocolFilter = null
|
||||
RbListPage.reload()
|
||||
$cleanVia.remove()
|
||||
|
@ -593,9 +597,9 @@ const RbListCommon = {
|
|||
// 新建
|
||||
$('.J_new').on('click', () => RbFormModal.create({ title: $L('新建%s', entity[1]), entity: entity[0], icon: entity[2] }))
|
||||
// 导出
|
||||
$('.J_export').on('click', () => renderRbcomp(<DataExport listRef={RbListPage._RbList} entity={entity[0]} />))
|
||||
$('.J_export').on('click', () => renderRbcomp(<DataExport listRef={_RbList()} entity={entity[0]} />))
|
||||
// 批量修改
|
||||
$('.J_batch').on('click', () => renderRbcomp(<BatchUpdate listRef={RbListPage._RbList} entity={entity[0]} />))
|
||||
$('.J_batch').on('click', () => renderRbcomp(<BatchUpdate listRef={_RbList()} entity={entity[0]} />))
|
||||
|
||||
// 自动打开新建
|
||||
if (location.hash === '#!/New') {
|
||||
|
|
|
@ -20,12 +20,12 @@ class RbList extends React.Component {
|
|||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
this.__defaultFilterKey = `AdvFilter-${this.props.config.entity}`
|
||||
this.__sortFieldKey = `SortField-${this.props.config.entity}`
|
||||
this.__columnWidthKey = `ColumnWidth-${this.props.config.entity}.`
|
||||
this.__defaultFilterKey = `AdvFilter-${props.config.entity}`
|
||||
this.__sortFieldKey = `SortField-${props.config.entity}`
|
||||
this.__columnWidthKey = `ColumnWidth-${props.config.entity}.`
|
||||
|
||||
const sort = ($storage.get(this.__sortFieldKey) || ':').split(':')
|
||||
const fields = props.config.fields
|
||||
const fields = props.config.fields || []
|
||||
for (let i = 0; i < fields.length; i++) {
|
||||
const cw = $storage.get(this.__columnWidthKey + fields[i].field)
|
||||
if (!!cw && ~~cw >= COLUMN_MIN_WIDTH) fields[i].width = ~~cw
|
||||
|
@ -34,7 +34,7 @@ class RbList extends React.Component {
|
|||
if (['SIGN', 'N2NREFERENCE', 'MULTISELECT', 'FILE', 'IMAGE', 'AVATAR'].includes(fields[i].type)) fields[i].unsort = true
|
||||
}
|
||||
|
||||
props.config.fields = null
|
||||
delete props.config.fields
|
||||
this.state = { ...props, fields: fields, rowsData: [], pageNo: 1, pageSize: 20, inLoad: true }
|
||||
|
||||
this.__defaultColumnWidth = $('#react-list').width() / 10
|
||||
|
@ -955,27 +955,27 @@ const RbListPage = {
|
|||
class RbViewModal extends React.Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = { ...props, inLoad: true, isHide: true, isDestroy: false }
|
||||
this.state = { ...props, inLoad: true, isHide: true, destroy: false }
|
||||
this.mcWidth = this.props.subView === true ? 1344 : 1404
|
||||
if ($(window).width() < 1464) this.mcWidth -= 184
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.destroy) return null
|
||||
|
||||
return (
|
||||
!this.state.isDestroy && (
|
||||
<div className="modal-wrapper">
|
||||
<div className="modal rbview" ref={(c) => (this._rbview = c)}>
|
||||
<div className="modal-dialog">
|
||||
<div className="modal-content" style={{ width: this.mcWidth }}>
|
||||
<div className={'modal-body iframe rb-loading ' + (this.state.inLoad === true && 'rb-loading-active')}>
|
||||
<iframe ref={(c) => (this._iframe = c)} className={this.state.isHide ? 'invisible' : ''} src={this.state.showAfterUrl || 'about:blank'} frameBorder="0" scrolling="no" />
|
||||
<RbSpinner />
|
||||
</div>
|
||||
<div className="modal-wrapper">
|
||||
<div className="modal rbview" ref={(c) => (this._rbview = c)}>
|
||||
<div className="modal-dialog">
|
||||
<div className="modal-content" style={{ width: this.mcWidth }}>
|
||||
<div className={'modal-body iframe rb-loading ' + (this.state.inLoad === true && 'rb-loading-active')}>
|
||||
<iframe ref={(c) => (this._iframe = c)} className={this.state.isHide ? 'invisible' : ''} src={this.state.showAfterUrl || 'about:blank'} frameBorder="0" scrolling="no" />
|
||||
<RbSpinner />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -993,7 +993,7 @@ class RbViewModal extends React.Component {
|
|||
// SubView 子视图不保持
|
||||
if (that.state.disposeOnHide === true) {
|
||||
$root.modal('dispose')
|
||||
that.setState({ isDestroy: true }, () => {
|
||||
that.setState({ destroy: true }, () => {
|
||||
RbViewModal.holder(that.state.id, 'DISPOSE')
|
||||
$unmount(rootWrap)
|
||||
})
|
||||
|
@ -1029,6 +1029,7 @@ class RbViewModal extends React.Component {
|
|||
if (url && url === this.state.url) urlChanged = false
|
||||
ext = ext || {}
|
||||
url = url || this.state.url
|
||||
|
||||
this.__urlChanged = urlChanged
|
||||
this.setState({ ...ext, url: url, inLoad: urlChanged, isHide: urlChanged }, () => {
|
||||
$(this._rbview).modal({ show: true, backdrop: true, keyboard: false })
|
||||
|
|
|
@ -4,10 +4,11 @@ Copyright (c) REBUILD <https://getrebuild.com/> and/or its owners. All rights re
|
|||
rebuild is dual-licensed under commercial and open source licenses (GPLv3).
|
||||
See LICENSE and COMMERCIAL in the project root for license information.
|
||||
*/
|
||||
/* eslint-disable no-unused-vars */
|
||||
// 表单附加操作,可在其他页面独立引入
|
||||
|
||||
// 分类数据选择
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
// ~~ 分类数据选择
|
||||
|
||||
class ClassificationSelector extends React.Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
@ -154,14 +155,12 @@ class ClassificationSelector extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
// ~~ 引用字段搜索
|
||||
|
||||
window.referenceSearch__call = function (selected) {}
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
window.referenceSearch__dlg
|
||||
|
||||
// ~~ 引用字段搜索
|
||||
// see `reference-search.html`
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
class ReferenceSearcher extends RbModal {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
@ -189,7 +188,6 @@ class ReferenceSearcher extends RbModal {
|
|||
|
||||
componentDidMount() {
|
||||
super.componentDidMount()
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
window.referenceSearch__dlg = this
|
||||
}
|
||||
|
||||
|
@ -198,8 +196,8 @@ class ReferenceSearcher extends RbModal {
|
|||
}
|
||||
}
|
||||
|
||||
// 删除确认
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
// ~~ 删除确认
|
||||
|
||||
class DeleteConfirm extends RbAlert {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
@ -300,7 +298,8 @@ class DeleteConfirm extends RbAlert {
|
|||
}
|
||||
}
|
||||
|
||||
// 百度地图
|
||||
// ~~ 百度地图
|
||||
|
||||
// https://mapopen-pub-jsapi.bj.bcebos.com/jsapi/reference/jsapi_webgl_1_0.html#a1b0
|
||||
class BaiduMap extends React.Component {
|
||||
render() {
|
||||
|
@ -400,7 +399,6 @@ class BaiduMap extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
class BaiduMapModal extends RbModal {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
@ -510,8 +508,8 @@ class BaiduMapModal extends RbModal {
|
|||
}
|
||||
}
|
||||
|
||||
// 签名板
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
// ~~ 签名板
|
||||
|
||||
class SignPad extends React.Component {
|
||||
state = { ...this.props }
|
||||
|
||||
|
@ -585,3 +583,57 @@ class SignPad extends React.Component {
|
|||
$(this._$dlg).modal('show')
|
||||
}
|
||||
}
|
||||
|
||||
// ~~ 重复记录查看
|
||||
|
||||
class RepeatedViewer extends RbModalHandler {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
}
|
||||
|
||||
render() {
|
||||
const data = this.props.data
|
||||
return (
|
||||
<RbModal ref={(c) => (this._dlg = c)} title={$L('存在 %d 条重复记录', this.props.data.length - 1)} disposeOnHide={true} colored="warning">
|
||||
<table className="table table-striped table-hover table-sm dialog-table">
|
||||
<thead>
|
||||
<tr>
|
||||
{data[0].map((item, idx) => {
|
||||
if (idx === 0) return null
|
||||
return <th key={`field-${idx}`}>{item}</th>
|
||||
})}
|
||||
<th width="30" />
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{data.map((item, idx) => {
|
||||
if (idx === 0) return null
|
||||
return this.renderRow(item, idx)
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</RbModal>
|
||||
)
|
||||
}
|
||||
|
||||
renderRow(item, idx) {
|
||||
return (
|
||||
<tr key={`row-${idx}`}>
|
||||
{item.map((o, i) => {
|
||||
if (i === 0) return null
|
||||
return <td key={`col-${idx}-${i}`}>{o || <span className="text-muted">{$L('无')}</span>}</td>
|
||||
})}
|
||||
<td className="actions">
|
||||
<a className="icon" onClick={() => this.openView(item[0])} title={$L('查看详情')}>
|
||||
<i className="zmdi zmdi-open-in-new" />
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
}
|
||||
|
||||
openView(id) {
|
||||
if (window.RbViewModal) window.RbViewModal.create({ id: id, entity: this.props.entity })
|
||||
else window.open(`${rb.baseUrl}/app/list-and-view?id=${id}`)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ Copyright (c) REBUILD <https://getrebuild.com/> and/or its owners. All rights re
|
|||
rebuild is dual-licensed under commercial and open source licenses (GPLv3).
|
||||
See LICENSE and COMMERCIAL in the project root for license information.
|
||||
*/
|
||||
/* global SimpleMDE */
|
||||
/* global SimpleMDE, RepeatedViewer */
|
||||
|
||||
const TYPE_DIVIDER = '$DIVIDER$'
|
||||
|
||||
|
@ -17,36 +17,35 @@ class RbFormModal extends React.Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
const maxWidth = { maxWidth: this.props.width || 1064 }
|
||||
if (this.state.destroy) return null
|
||||
|
||||
const mw = { maxWidth: this.props.width || 1064 }
|
||||
return (
|
||||
this.state.isDestroy !== true && (
|
||||
<div className="modal-wrapper">
|
||||
<div className="modal rbmodal colored-header colored-header-primary" ref={(c) => (this._rbmodal = c)}>
|
||||
<div className="modal-dialog" style={maxWidth}>
|
||||
<div className="modal-content" style={maxWidth}>
|
||||
<div className="modal-header modal-header-colored">
|
||||
{this.state.icon && <span className={'icon zmdi zmdi-' + this.state.icon} />}
|
||||
<h3 className="modal-title">{this.state.title || $L('新建')}</h3>
|
||||
{rb.isAdminUser && (
|
||||
<a className="close s" href={`${rb.baseUrl}/admin/entity/${this.state.entity}/form-design`} title={$L('表单设计')} target="_blank">
|
||||
<span className="zmdi zmdi-settings" />
|
||||
</a>
|
||||
)}
|
||||
<button className="close md-close" type="button" onClick={() => this.hide()}>
|
||||
<span className="zmdi zmdi-close" />
|
||||
</button>
|
||||
</div>
|
||||
<div className={'modal-body rb-loading' + (this.state.inLoad ? ' rb-loading-active' : '')}>
|
||||
{this.state.alertMessage && <div className="alert alert-warning rbform-alert">{this.state.alertMessage}</div>}
|
||||
{this.state.formComponent}
|
||||
{this.state.inLoad && <RbSpinner />}
|
||||
</div>
|
||||
<div className="modal-wrapper">
|
||||
<div className="modal rbmodal colored-header colored-header-primary" ref={(c) => (this._rbmodal = c)}>
|
||||
<div className="modal-dialog" style={mw}>
|
||||
<div className="modal-content" style={mw}>
|
||||
<div className="modal-header modal-header-colored">
|
||||
{this.state.icon && <span className={`icon zmdi zmdi-${this.state.icon}`} />}
|
||||
<h3 className="modal-title">{this.state.title || $L('新建')}</h3>
|
||||
{rb.isAdminUser && (
|
||||
<a className="close s" href={`${rb.baseUrl}/admin/entity/${this.state.entity}/form-design`} title={$L('表单设计')} target="_blank">
|
||||
<span className="zmdi zmdi-settings" />
|
||||
</a>
|
||||
)}
|
||||
<button className="close md-close" type="button" onClick={() => this.hide()}>
|
||||
<span className="zmdi zmdi-close" />
|
||||
</button>
|
||||
</div>
|
||||
<div className={`modal-body rb-loading ${this.state.inLoad ? 'rb-loading-active' : ''}`}>
|
||||
{this.state.alertMessage && <div className="alert alert-warning rbform-alert">{this.state.alertMessage}</div>}
|
||||
{this.state.formComponent}
|
||||
{this.state.inLoad && <RbSpinner />}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -73,29 +72,32 @@ class RbFormModal extends React.Component {
|
|||
const id = this.state.id || ''
|
||||
const initialValue = this.state.initialValue || {} // 默认值填充(仅新建有效)
|
||||
|
||||
const that = this
|
||||
$.post(`/app/${entity}/form-model?id=${id}`, JSON.stringify(initialValue), function (res) {
|
||||
$.post(`/app/${entity}/form-model?id=${id}`, JSON.stringify(initialValue), (res) => {
|
||||
// 包含错误
|
||||
if (res.error_code > 0 || !!res.data.error) {
|
||||
const error = (res.data || {}).error || res.error_msg
|
||||
that.renderFromError(error)
|
||||
this.renderFromError(error)
|
||||
return
|
||||
}
|
||||
|
||||
const formModel = res.data
|
||||
|
||||
const FORM = (
|
||||
<RbForm entity={entity} id={id} $$$parent={that}>
|
||||
{res.data.elements.map((item) => {
|
||||
<RbForm entity={entity} id={id} $$$parent={this} rawModel={formModel}>
|
||||
{formModel.elements.map((item) => {
|
||||
return detectElement(item)
|
||||
})}
|
||||
</RbForm>
|
||||
)
|
||||
that.setState({ formComponent: FORM, __formModel: res.data }, () => {
|
||||
that.setState({ inLoad: false })
|
||||
|
||||
this.setState({ formComponent: FORM }, () => {
|
||||
this.setState({ inLoad: false })
|
||||
if (window.FrontJS) {
|
||||
window.FrontJS.Form._trigger('open', [res.data])
|
||||
}
|
||||
})
|
||||
that.__lastModified = res.data.lastModified || 0
|
||||
|
||||
this.__lastModified = res.data.lastModified || 0
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -105,7 +107,7 @@ class RbFormModal extends React.Component {
|
|||
<div className="icon">
|
||||
<i className="zmdi zmdi-alert-triangle" />
|
||||
</div>
|
||||
<div className="message" dangerouslySetInnerHTML={{ __html: `<strong>${$L('抱歉!')}</strong> ` + message }} />
|
||||
<div className="message" dangerouslySetInnerHTML={{ __html: `<strong>${$L('抱歉!')}</strong> ${message}` }} />
|
||||
</div>
|
||||
)
|
||||
this.setState({ formComponent: error }, () => this.setState({ inLoad: false }))
|
||||
|
@ -119,11 +121,11 @@ class RbFormModal extends React.Component {
|
|||
const stateNew = [state.id, state.entity, state.initialValue]
|
||||
const stateOld = [this.state.id, this.state.entity, this.state.initialValue]
|
||||
|
||||
if (this.state.isDestroy === true || JSON.stringify(stateNew) !== JSON.stringify(stateOld)) {
|
||||
if (this.state.destroy === true || JSON.stringify(stateNew) !== JSON.stringify(stateOld)) {
|
||||
state = { formComponent: null, initialValue: null, inLoad: true, ...state }
|
||||
this.setState(state, () => this.showAfter({ isDestroy: false }, true))
|
||||
this.setState(state, () => this.showAfter({ destroy: false }, true))
|
||||
} else {
|
||||
this.showAfter({ ...state, isDestroy: false })
|
||||
this.showAfter({ ...state, destroy: false })
|
||||
this.checkDrityData()
|
||||
}
|
||||
}
|
||||
|
@ -137,10 +139,11 @@ class RbFormModal extends React.Component {
|
|||
|
||||
checkDrityData() {
|
||||
if (!this.__lastModified || !this.state.id) return
|
||||
|
||||
$.get(`/app/entity/extras/record-last-modified?id=${this.state.id}`, (res) => {
|
||||
if (res.error_code === 0) {
|
||||
if (res.data.lastModified !== this.__lastModified) {
|
||||
// this.setState({ alertMessage: <p>记录已由其他用户编辑过,<a onClick={() => this.__refresh()}>点击此处</a>查看最新数据</p> })
|
||||
// this.setState({ alertMessage: <p>记录已由其他用户编辑过,<a onClick={() => this._refresh()}>点击此处</a>查看最新数据</p> })
|
||||
this._refresh()
|
||||
}
|
||||
} else if (res.error_msg === 'NO_EXISTS') {
|
||||
|
@ -150,15 +153,16 @@ class RbFormModal extends React.Component {
|
|||
}
|
||||
|
||||
_refresh() {
|
||||
const hold = { id: this.state.id, entity: this.state.entity }
|
||||
const hs = { id: this.state.id, entity: this.state.entity }
|
||||
this.setState({ id: null, alertMessage: null }, () => {
|
||||
this.show(hold)
|
||||
this.show(hs)
|
||||
})
|
||||
}
|
||||
|
||||
hide(destroy) {
|
||||
$(this._rbmodal).modal('hide')
|
||||
const state = { isDestroy: destroy === true }
|
||||
|
||||
const state = { destroy: destroy === true }
|
||||
if (destroy === true) state.id = null
|
||||
this.setState(state)
|
||||
}
|
||||
|
@ -166,10 +170,10 @@ class RbFormModal extends React.Component {
|
|||
// -- Usage
|
||||
/**
|
||||
* @param {*} props
|
||||
* @param {*} newDlg
|
||||
* @param {*} forceNew
|
||||
*/
|
||||
static create(props, newDlg) {
|
||||
if (newDlg === true) {
|
||||
static create(props, forceNew) {
|
||||
if (forceNew === true) {
|
||||
renderRbcomp(<RbFormModal {...props} />)
|
||||
return
|
||||
}
|
||||
|
@ -192,7 +196,7 @@ class RbForm extends React.Component {
|
|||
this.state = { ...props }
|
||||
|
||||
this.__FormData = {}
|
||||
const iv = props.$$$parent.state.__formModel.initialValue
|
||||
const iv = props.rawModel.initialValue
|
||||
if (iv) {
|
||||
for (let k in iv) {
|
||||
const val = iv[k]
|
||||
|
@ -201,7 +205,7 @@ class RbForm extends React.Component {
|
|||
}
|
||||
|
||||
this.isNew = !props.$$$parent.state.id
|
||||
this.setFieldValue = this.setFieldValue.bind(this)
|
||||
// this.setFieldValue = this.setFieldValue.bind(this)
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -219,10 +223,8 @@ class RbForm extends React.Component {
|
|||
}
|
||||
|
||||
renderFormAction() {
|
||||
const pmodel = this.props.$$$parent.state.__formModel
|
||||
|
||||
const moreActions = []
|
||||
if (pmodel.isDetail === true) {
|
||||
if (this.props.rawModel.isDetail === true) {
|
||||
moreActions.push(
|
||||
<a key="Action101" className="dropdown-item" onClick={() => this.post(RbForm.__NEXT_ADDDETAIL)}>
|
||||
{$L('保存并继续添加')}
|
||||
|
@ -306,7 +308,9 @@ class RbForm extends React.Component {
|
|||
/**
|
||||
* @next {Number}
|
||||
*/
|
||||
post = (next) => setTimeout(() => this._post(next), 30)
|
||||
post(next) {
|
||||
setTimeout(() => this._post(next), 30)
|
||||
}
|
||||
|
||||
_post(next) {
|
||||
const data = {}
|
||||
|
@ -336,11 +340,10 @@ class RbForm extends React.Component {
|
|||
RbForm.postAfter({ ...res.data, isNew: !this.state.id }, next)
|
||||
|
||||
const recordId = res.data.id
|
||||
const pState = this.props.$$$parent.state
|
||||
|
||||
if (next === RbForm.__NEXT_ADDDETAIL) {
|
||||
const iv = { $MAINID$: recordId }
|
||||
const dm = pState.__formModel.detailMeta
|
||||
const iv = { '$MAINID$': recordId }
|
||||
const dm = this.props.rawModel.detailMeta
|
||||
RbFormModal.create({
|
||||
title: $L('添加%s', dm.entityLabel),
|
||||
entity: dm.entity,
|
||||
|
@ -348,7 +351,7 @@ class RbForm extends React.Component {
|
|||
initialValue: iv,
|
||||
})
|
||||
} else if (next === RbForm.__NEXT_VIEW && window.RbViewModal) {
|
||||
window.RbViewModal.create({ id: recordId, entity: pState.entity })
|
||||
window.RbViewModal.create({ id: recordId, entity: this.state.entity })
|
||||
}
|
||||
|
||||
// ...
|
||||
|
@ -456,6 +459,7 @@ class RbFormElement extends React.Component {
|
|||
*/
|
||||
renderElement() {
|
||||
const value = arguments.length > 0 ? arguments[0] : this.state.value
|
||||
|
||||
return (
|
||||
<input
|
||||
ref={(c) => (this._fieldValue = c)}
|
||||
|
@ -477,18 +481,15 @@ class RbFormElement extends React.Component {
|
|||
renderViewElement() {
|
||||
let value = arguments.length > 0 ? arguments[0] : this.state.value
|
||||
if (value && $empty(value)) value = null
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div className="form-control-plaintext">{value || <span className="text-muted">{$L('无')}</span>}</div>
|
||||
</React.Fragment>
|
||||
)
|
||||
|
||||
return <div className="form-control-plaintext">{value || <span className="text-muted">{$L('无')}</span>}</div>
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改值(表单组件(字段)值变化应调用此方法)
|
||||
*
|
||||
* @param {*} e
|
||||
* @param {*} checkValue
|
||||
* @param {Event} e
|
||||
* @param {Boolean} checkValue
|
||||
*/
|
||||
handleChange(e, checkValue) {
|
||||
const val = e.target.value
|
||||
|
@ -540,7 +541,7 @@ class RbFormElement extends React.Component {
|
|||
/**
|
||||
* 视图编辑-编辑状态改变
|
||||
*
|
||||
* @param {*} destroy
|
||||
* @param {Boolean} destroy
|
||||
*/
|
||||
onEditModeChanged(destroy) {
|
||||
if (destroy) {
|
||||
|
@ -560,7 +561,7 @@ class RbFormElement extends React.Component {
|
|||
/**
|
||||
* 视图编辑-编辑模式
|
||||
*
|
||||
* @param {*} editMode
|
||||
* @param {Boolean} editMode
|
||||
*/
|
||||
toggleEditMode(editMode) {
|
||||
// if (editMode) {
|
||||
|
@ -2043,56 +2044,3 @@ const __addRecentlyUse = function (id) {
|
|||
if (!id) return
|
||||
$.post(`/commons/search/recently-add?id=${id}`)
|
||||
}
|
||||
|
||||
// ~ 重复记录查看
|
||||
class RepeatedViewer extends RbModalHandler {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
}
|
||||
|
||||
render() {
|
||||
const data = this.props.data
|
||||
return (
|
||||
<RbModal ref={(c) => (this._dlg = c)} title={$L('存在 %d 条重复记录', this.props.data.length - 1)} disposeOnHide={true} colored="warning">
|
||||
<table className="table table-striped table-hover table-sm dialog-table">
|
||||
<thead>
|
||||
<tr>
|
||||
{data[0].map((item, idx) => {
|
||||
if (idx === 0) return null
|
||||
return <th key={`field-${idx}`}>{item}</th>
|
||||
})}
|
||||
<th width="30" />
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{data.map((item, idx) => {
|
||||
if (idx === 0) return null
|
||||
return this.renderRow(item, idx)
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</RbModal>
|
||||
)
|
||||
}
|
||||
|
||||
renderRow(item, idx) {
|
||||
return (
|
||||
<tr key={`row-${idx}`}>
|
||||
{item.map((o, i) => {
|
||||
if (i === 0) return null
|
||||
return <td key={`col-${idx}-${i}`}>{o || <span className="text-muted">{$L('无')}</span>}</td>
|
||||
})}
|
||||
<td className="actions">
|
||||
<a className="icon" onClick={() => this.openView(item[0])} title={$L('查看详情')}>
|
||||
<i className="zmdi zmdi-open-in-new" />
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
}
|
||||
|
||||
openView(id) {
|
||||
if (window.RbViewModal) window.RbViewModal.create({ id: id, entity: this.props.entity })
|
||||
else window.open(`${rb.baseUrl}/app/list-and-view?id=${id}`)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,2 @@
|
|||
/*!
|
||||
* Beagle v1.5.0
|
||||
* https://foxythemes.net
|
||||
*
|
||||
* Copyright (c) 2018 Foxy Themes
|
||||
*/
|
||||
|
||||
/* perfect-scrollbar v0.6.16 */
|
||||
.ps-container{-ms-touch-action:auto;touch-action:auto;overflow:hidden !important;-ms-overflow-style:none}@supports (-ms-overflow-style: none){.ps-container{overflow:auto !important}}@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none){.ps-container{overflow:auto !important}}.ps-container.ps-active-x>.ps-scrollbar-x-rail,.ps-container.ps-active-y>.ps-scrollbar-y-rail{display:block;background-color:transparent}.ps-container.ps-in-scrolling.ps-x>.ps-scrollbar-x-rail{background-color:#eee;opacity:.9}.ps-container.ps-in-scrolling.ps-x>.ps-scrollbar-x-rail>.ps-scrollbar-x{background-color:#999;height:11px}.ps-container.ps-in-scrolling.ps-y>.ps-scrollbar-y-rail{background-color:#eee;opacity:.9}.ps-container.ps-in-scrolling.ps-y>.ps-scrollbar-y-rail>.ps-scrollbar-y{background-color:#999;width:11px}.ps-container>.ps-scrollbar-x-rail{display:none;position:absolute;opacity:0;-webkit-transition:background-color .2s linear, opacity .2s linear;-o-transition:background-color .2s linear, opacity .2s linear;-moz-transition:background-color .2s linear, opacity .2s linear;transition:background-color .2s linear, opacity .2s linear;bottom:0px;height:15px}.ps-container>.ps-scrollbar-x-rail>.ps-scrollbar-x{position:absolute;background-color:#aaa;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;-o-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;-moz-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -webkit-border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;bottom:2px;height:6px}.ps-container>.ps-scrollbar-x-rail:hover>.ps-scrollbar-x,.ps-container>.ps-scrollbar-x-rail:active>.ps-scrollbar-x{height:11px}.ps-container>.ps-scrollbar-y-rail{display:none;position:absolute;opacity:0;-webkit-transition:background-color .2s linear, opacity .2s linear;-o-transition:background-color .2s linear, opacity .2s linear;-moz-transition:background-color .2s linear, opacity .2s linear;transition:background-color .2s linear, opacity .2s linear;right:0;width:15px}.ps-container>.ps-scrollbar-y-rail>.ps-scrollbar-y{position:absolute;background-color:#aaa;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;-o-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;-moz-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -webkit-border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;right:2px;width:6px}.ps-container>.ps-scrollbar-y-rail:hover>.ps-scrollbar-y,.ps-container>.ps-scrollbar-y-rail:active>.ps-scrollbar-y{width:11px}.ps-container:hover.ps-in-scrolling.ps-x>.ps-scrollbar-x-rail{background-color:#eee;opacity:.9}.ps-container:hover.ps-in-scrolling.ps-x>.ps-scrollbar-x-rail>.ps-scrollbar-x{background-color:#999;height:11px}.ps-container:hover.ps-in-scrolling.ps-y>.ps-scrollbar-y-rail{background-color:#eee;opacity:.9}.ps-container:hover.ps-in-scrolling.ps-y>.ps-scrollbar-y-rail>.ps-scrollbar-y{background-color:#999;width:11px}.ps-container:hover>.ps-scrollbar-x-rail,.ps-container:hover>.ps-scrollbar-y-rail{opacity:.6}.ps-container:hover>.ps-scrollbar-x-rail:hover{background-color:#eee;opacity:.9}.ps-container:hover>.ps-scrollbar-x-rail:hover>.ps-scrollbar-x{background-color:#999}.ps-container:hover>.ps-scrollbar-y-rail:hover{background-color:#eee;opacity:.9}.ps-container:hover>.ps-scrollbar-y-rail:hover>.ps-scrollbar-y{background-color:#999}
|
||||
|
|
Loading…
Reference in a new issue