fastlion-amis
Version:
一种MIS页面生成工具
253 lines (252 loc) • 13.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.withRemoteConfig = exports.Store = void 0;
var tslib_1 = require("tslib");
/**
* 一个可以拉取远程配置的 HOC
*
*/
var react_1 = (0, tslib_1.__importDefault)(require("react"));
var hoist_non_react_statics_1 = (0, tslib_1.__importDefault)(require("hoist-non-react-statics"));
var debounce_1 = (0, tslib_1.__importDefault)(require("lodash/debounce"));
var WithStore_1 = require("./WithStore");
var env_1 = require("../env");
var mobx_state_tree_1 = require("mobx-state-tree");
var api_1 = require("../utils/api");
var tpl_builtin_1 = require("../utils/tpl-builtin");
var mobx_1 = require("mobx");
var helper_1 = require("../utils/helper");
exports.Store = mobx_state_tree_1.types
.model('RemoteConfigStore')
.props({
fetching: false,
errorMsg: '',
config: mobx_state_tree_1.types.frozen(),
data: mobx_state_tree_1.types.frozen({})
})
.actions(function (self) {
var component = undefined;
var load = (0, mobx_state_tree_1.flow)(function (env, api, ctx, config) {
var ret, data, options, e_1;
var _a;
if (config === void 0) { config = {}; }
return (0, tslib_1.__generator)(this, function (_b) {
switch (_b.label) {
case 0:
_b.trys.push([0, 2, 3, 4]);
self.fetching = true;
return [4 /*yield*/, env.fetcher(api, ctx)];
case 1:
ret = _b.sent();
if (!(0, mobx_state_tree_1.isAlive)(self)) {
return [2 /*return*/];
}
if (ret.ok) {
data = (0, api_1.normalizeApiResponseData)(ret.data);
options = config.adaptor
? config.adaptor(data, component.props)
: data;
self.setConfig(options, config, 'remote');
(_a = config.afterLoad) === null || _a === void 0 ? void 0 : _a.call(config, data, self.config, component.props);
return [2 /*return*/, ret];
}
else {
throw new Error(ret.msg || 'fetch error');
}
return [3 /*break*/, 4];
case 2:
e_1 = _b.sent();
(0, mobx_state_tree_1.isAlive)(self) && (self.errorMsg = e_1.message);
return [3 /*break*/, 4];
case 3:
(0, mobx_state_tree_1.isAlive)(self) && (self.fetching = false);
return [7 /*endfinally*/];
case 4: return [2 /*return*/];
}
});
});
return {
setComponent: function (c) {
component = c;
},
load: load,
setData: function (data) {
self.data = data || {};
},
setConfig: function (options, config, motivation) {
if (config.normalizeConfig) {
options =
config.normalizeConfig(options, self.config, component.props, motivation) || options;
}
self.config = options;
}
};
});
function withRemoteConfig(config) {
if (config === void 0) { config = {}; }
return function (ComposedComponent) {
var _a;
var result = (0, hoist_non_react_statics_1.default)((0, WithStore_1.withStore)(function () { return exports.Store.create(); })((_a = /** @class */ (function (_super) {
(0, tslib_1.__extends)(class_1, _super);
function class_1(props) {
var _a;
var _this = _super.call(this, props) || this;
_this.toDispose = [];
_this.loadOptions = (0, debounce_1.default)(_this.loadAutoComplete.bind(_this), 250, {
trailing: true,
leading: false
});
_this.setConfig = _this.setConfig.bind(_this);
props.store.setComponent(_this);
_this.deferLoadConfig = _this.deferLoadConfig.bind(_this);
(_a = props.remoteConfigRef) === null || _a === void 0 ? void 0 : _a.call(props, _this);
return _this;
}
class_1.prototype.componentDidMount = function () {
var _this = this;
var env = this.props.env || this.context;
var _a = this.props, store = _a.store, source = _a.source, data = _a.data;
store.setData(data);
if ((0, tpl_builtin_1.isPureVariable)(source)) {
this.syncConfig();
this.toDispose.push((0, mobx_1.reaction)(function () {
return (0, tpl_builtin_1.resolveVariableAndFilter)(source, store.data, '| raw');
}, function () { return _this.syncConfig(); }));
}
else if (env && (0, api_1.isEffectiveApi)(source, data)) {
this.loadConfig();
source.autoRefresh !== false &&
this.toDispose.push((0, mobx_1.reaction)(function () {
var api = (0, api_1.normalizeApi)(source);
return api.trackExpression
? (0, tpl_builtin_1.tokenize)(api.trackExpression, store.data)
: (0, api_1.buildApi)(api, store.data, {
ignoreData: true
}).url;
}, function () { return _this.loadConfig(); }));
}
};
class_1.prototype.componentDidUpdate = function (prevProps) {
var props = this.props;
if (props.data !== prevProps.data) {
props.store.setData(props.data);
}
};
class_1.prototype.componentWillUnmount = function () {
var _a, _b;
this.toDispose.forEach(function (fn) { return fn(); });
this.toDispose = [];
(_b = (_a = this.props).remoteConfigRef) === null || _b === void 0 ? void 0 : _b.call(_a, undefined);
this.loadOptions.cancel();
};
class_1.prototype.loadConfig = function (ctx) {
if (ctx === void 0) { ctx = this.props.data; }
return (0, tslib_1.__awaiter)(this, void 0, void 0, function () {
var env, _a, store, source;
return (0, tslib_1.__generator)(this, function (_b) {
switch (_b.label) {
case 0:
env = this.props.env || this.context;
_a = this.props, store = _a.store, source = _a.source;
if (!(env && (0, api_1.isEffectiveApi)(source, ctx))) return [3 /*break*/, 2];
return [4 /*yield*/, store.load(env, source, ctx, config)];
case 1:
_b.sent();
_b.label = 2;
case 2: return [2 /*return*/];
}
});
});
};
class_1.prototype.loadAutoComplete = function (input) {
var env = this.props.env || this.context;
var _a = this.props, autoComplete = _a.autoComplete, data = _a.data, store = _a.store;
if (!env || !env.fetcher) {
throw new Error('fetcher is required');
}
var ctx = (0, helper_1.createObject)(data, {
term: input,
value: input
});
if (!(0, api_1.isEffectiveApi)(autoComplete, ctx)) {
return Promise.resolve({
options: []
});
}
return store.load(env, autoComplete, ctx, config);
};
class_1.prototype.setConfig = function (value, ctx) {
var store = this.props.store;
store.setConfig(value, config, ctx);
};
class_1.prototype.syncConfig = function () {
var _a = this.props, store = _a.store, source = _a.source, data = _a.data;
if ((0, tpl_builtin_1.isPureVariable)(source)) {
store.setConfig((0, tpl_builtin_1.resolveVariableAndFilter)(source, data, '| raw') || [], config, 'syncConfig');
}
};
class_1.prototype.deferLoadConfig = function (item) {
var _a, _b;
return (0, tslib_1.__awaiter)(this, void 0, void 0, function () {
var _c, store, source, data, deferApi, env, indexes, ret, response, e_2, ret2;
return (0, tslib_1.__generator)(this, function (_d) {
switch (_d.label) {
case 0:
_c = this.props, store = _c.store, source = _c.source, data = _c.data, deferApi = _c.deferApi;
env = this.props.env || this.context;
indexes = (0, helper_1.findTreeIndex)(store.config, function (a) { return a === item; });
ret = (_a = config.beforeDeferLoad) === null || _a === void 0 ? void 0 : _a.call(config, item, indexes, store.config, this.props);
ret && store.setConfig(ret, config, 'before-defer-load');
_d.label = 1;
case 1:
_d.trys.push([1, 3, , 4]);
if (!(0, api_1.isEffectiveApi)(item.deferApi || deferApi || source)) {
throw new Error('deferApi is required');
}
return [4 /*yield*/, env.fetcher(item.deferApi || deferApi || source, (0, helper_1.createObject)(data, item))];
case 2:
response = _d.sent();
return [3 /*break*/, 4];
case 3:
e_2 = _d.sent();
response = {
ok: false,
msg: e_2.message,
status: 500,
data: undefined
};
return [3 /*break*/, 4];
case 4:
ret2 = (_b = config.afterDeferLoad) === null || _b === void 0 ? void 0 : _b.call(config, item, indexes, // 只能假定还是那个 index 了
response, store.config, this.props);
ret2 && store.setConfig(ret2, config, 'after-defer-load');
return [2 /*return*/];
}
});
});
};
class_1.prototype.render = function () {
var store = this.props.store;
var env = this.props.env || this.context;
var injectedProps = {
config: store.config,
loading: store.fetching,
deferLoad: this.deferLoadConfig,
updateConfig: this.setConfig
};
var _a = this.props, remoteConfigRef = _a.remoteConfigRef, autoComplete = _a.autoComplete, rest = (0, tslib_1.__rest)(_a, ["remoteConfigRef", "autoComplete"]);
return (react_1.default.createElement(ComposedComponent, (0, tslib_1.__assign)({}, rest, (env && (0, api_1.isEffectiveApi)(autoComplete) && this.loadOptions
? { loadOptions: this.loadOptions }
: {}), injectedProps)));
};
return class_1;
}(react_1.default.Component)),
_a.displayName = "WithRemoteConfig(" + (ComposedComponent.displayName || ComposedComponent.name) + ")",
_a.ComposedComponent = ComposedComponent,
_a.contextType = env_1.EnvContext,
_a)), ComposedComponent);
return result;
};
}
exports.withRemoteConfig = withRemoteConfig;
//# sourceMappingURL=./components/WithRemoteConfig.js.map