oak-frontend-base/lib/page.common.js

488 lines
19 KiB
JavaScript

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.makePageMethods = exports.makeListComponentMethods = exports.makeCommonComponentMethods = exports.makeHiddenComponentMethods = void 0;
const assert_1 = __importDefault(require("assert"));
const lodash_1 = require("lodash");
const types_1 = require("oak-domain/lib/types");
const Feature_1 = require("./types/Feature");
function makeHiddenComponentMethods() {
return {
subscribe() {
if (!this.subscribed) {
this.subscribed = (0, Feature_1.subscribe)(() => this.reRender());
}
},
unsubscribe() {
if (this.subscribed) {
this.subscribed();
this.subscribed = undefined;
}
},
};
}
exports.makeHiddenComponentMethods = makeHiddenComponentMethods;
function makeCommonComponentMethods(features, exceptionRouterDict, formData) {
return {
sub(type, callback) {
features.eventBus.sub(type, callback);
},
unsub(type, callback) {
features.eventBus.unsub(type, callback);
},
pub(type, options) {
features.eventBus.pub(type, options);
},
unsubAll(type) {
features.eventBus.unsubAll(type);
},
save(key, item) {
features.localStorage.save(key, item);
},
load(key) {
return features.localStorage.load(key);
},
clear() {
features.localStorage.clear();
},
async reRender(extra) {
if (this.state.oakFullpath) {
const rows = features.runningTree.getFreshValue(this.state.oakFullpath);
const dirty = features.runningTree.isDirty(this.state.oakFullpath);
const oakLegalActions = [];
if (this.state.newOakActions) {
for (const action of this.state.newOakActions) {
try {
await features.runningTree.testAction(this.state.oakFullpath, action);
oakLegalActions.push(action);
}
catch (e) {
if (e instanceof types_1.OakInputIllegalException) {
oakLegalActions.push(action);
}
}
}
}
const data = formData ? await formData.call(this, {
data: rows,
features,
props: this.props,
legalActions: oakLegalActions,
}) : {};
for (const k in data) {
if (data[k] === undefined) {
(0, lodash_1.assign)(data, {
[k]: null,
});
}
}
(0, lodash_1.assign)(data, { oakDirty: dirty });
if (extra) {
(0, lodash_1.assign)(data, extra);
}
(0, lodash_1.assign)(data, {
oakLegalActions,
});
this.setState(data);
}
},
callPicker(attr, params) {
if (this.state.oakExecuting) {
return;
}
const relation = features.cache.judgeRelation(this.state.oakEntity, attr);
let subEntity;
if (relation === 2) {
subEntity = attr;
}
else {
(0, assert_1.default)(typeof relation === 'string');
subEntity = relation;
}
let url = `/pickers/${subEntity}?oakIsPicker=true&oakParentEntity=${this.state.oakEntity}&oakParent=${this.state.oakFullpath}&oakPath=${attr}`;
for (const k in params) {
url += `&${k}=${JSON.stringify(params[k])}`;
}
this.navigateTo({
url,
});
},
setForeignKey(id, goBackDelta = -1) {
if (this.state.oakExecuting) {
return;
}
const { oakIsPicker, oakParent, oakPath } = this.state;
(0, assert_1.default)(oakIsPicker);
features.runningTree.setForeignKey(oakParent, oakPath, id);
if (goBackDelta !== 0) {
this.navigateBack({
delta: goBackDelta,
});
}
},
addForeignKeys(ids, goBackDelta = -1) {
if (this.state.oakExecuting) {
return;
}
const { oakIsPicker, oakParent, oakPath } = this.state;
(0, assert_1.default)(oakIsPicker);
features.runningTree.addForeignKeys(oakParent, oakPath, ids);
if (goBackDelta !== 0) {
this.navigateBack({
delta: goBackDelta,
});
}
},
setUniqueForeignKeys(ids, goBackDelta = -1) {
if (this.state.oakExecuting) {
return;
}
const { oakIsPicker, oakParent, oakPath } = this.state;
(0, assert_1.default)(oakIsPicker);
features.runningTree.setUniqueForeignKeys(oakParent, oakPath, ids);
if (goBackDelta !== 0) {
this.navigateBack({
delta: goBackDelta,
});
}
},
toggleNode(nodeData, checked, path) {
const fullpath = path
? `${this.state.oakFullpath}.${path}`
: this.state.oakFullpath;
features.runningTree.toggleNode(fullpath, nodeData, checked);
},
async execute(action, legalExceptions) {
if (this.state.oakExecuting) {
return;
}
this.setState({
oakExecuting: true,
oakFocused: {},
});
try {
const result = await features.runningTree.execute(this.state.oakFullpath, action);
this.setState({ oakExecuting: false });
this.setState({
oakError: {
type: 'success',
msg: '操作成功',
},
});
return result;
}
catch (err) {
if (err instanceof types_1.OakException) {
if (err instanceof types_1.OakInputIllegalException) {
const attr = err.getAttributes()[0];
this.setState({
oakFocused: {
[attr]: true,
},
oakExecuting: false,
oakError: {
type: 'warning',
msg: err.message,
},
});
}
else {
const { name } = err.constructor;
const handler = exceptionRouterDict[name];
if (legalExceptions && legalExceptions.includes(name)) {
// 如果调用时就知道有异常,直接抛出
this.setState({
oakExecuting: false,
});
throw err;
}
else if (handler) {
const { hidden, level, handler: fn, router, } = handler;
if (!hidden) {
this.setState({
oakExecuting: false,
oakError: {
type: level,
msg: err.message,
},
});
}
else {
this.setState({
oakExecuting: false,
});
}
if (fn) {
fn(err);
return;
}
else if (router) {
this.setState({
oakExecuting: false,
});
this.navigateTo({
url: router,
});
}
}
else {
this.setState({
oakExecuting: false,
oakError: {
type: 'warning',
msg: err.message,
},
});
}
}
}
else {
this.setState({
oakExecuting: false,
oakError: {
type: 'error',
msg: err.message,
},
});
}
throw err;
}
},
resetUpdateData() {
return features.runningTree.resetUpdateData(this.state.oakFullpath);
},
setUpdateData(attr, value) {
if (this.state.oakExecuting) {
return;
}
return features.runningTree.setUpdateData(this.state.oakFullpath, attr, value);
},
};
}
exports.makeCommonComponentMethods = makeCommonComponentMethods;
function makeListComponentMethods(features) {
return {
pushNode(path, options) {
const path2 = path
? `${this.state.oakFullpath}.${path}`
: this.state.oakFullpath;
features.runningTree.pushNode(path2, options || {});
},
removeNode(parent, path) {
features.runningTree.removeNode(parent, path);
},
async getFilters() {
const namedFilters = features.runningTree.getNamedFilters(this.state.oakFullpath);
const filters = await Promise.all(namedFilters.map(({ filter }) => {
if (typeof filter === 'function') {
return filter();
}
return filter;
}));
return filters;
},
async getFilterByName(name) {
const filter = features.runningTree.getNamedFilterByName(this.state.oakFullpath, name);
if (filter?.filter) {
if (typeof filter.filter === 'function') {
return filter.filter();
}
return filter.filter;
}
return;
},
addNamedFilter(namedFilter, refresh = false) {
return features.runningTree.addNamedFilter(this.state.oakFullpath, namedFilter, refresh);
},
removeNamedFilter(namedFilter, refresh = false) {
return features.runningTree.removeNamedFilter(this.state.oakFullpath, namedFilter, refresh);
},
removeNamedFilterByName(name, refresh = false) {
return features.runningTree.removeNamedFilterByName(this.state.oakFullpath, name, refresh);
},
setNamedSorters(namedSorters) {
return features.runningTree.setNamedSorters(this.state.oakFullpath, namedSorters);
},
async getSorters() {
const namedSorters = features.runningTree.getNamedSorters(this.state.oakFullpath);
const sorters = (await Promise.all(namedSorters.map(({ sorter }) => {
if (typeof sorter === 'function') {
return sorter();
}
return sorter;
}))).filter((ele) => !!ele);
return sorters;
},
async getSorterByName(name) {
const sorter = features.runningTree.getNamedSorterByName(this.state.oakFullpath, name);
if (sorter?.sorter) {
if (typeof sorter.sorter === 'function') {
return sorter.sorter();
}
return sorter.sorter;
}
return;
},
addNamedSorter(namedSorter, refresh = false) {
return features.runningTree.addNamedSorter(this.state.oakFullpath, namedSorter, refresh);
},
removeNamedSorter(namedSorter, refresh = false) {
return features.runningTree.removeNamedSorter(this.state.oakFullpath, namedSorter, refresh);
},
removeNamedSorterByName(name, refresh = false) {
return features.runningTree.removeNamedSorterByName(this.state.oakFullpath, name, refresh);
},
setFilters(filters) {
return features.runningTree.setNamedFilters(this.state.oakFullpath, filters);
},
};
}
exports.makeListComponentMethods = makeListComponentMethods;
function makePageMethods(features, options) {
return {
async refresh() {
if (this.state.oakFullpath) {
this.setState({
oakLoading: true,
});
try {
await features.runningTree.refresh(this.state.oakFullpath);
this.setState({
oakLoading: false,
});
}
catch (err) {
this.setState({
oakLoading: false,
oakError: {
type: 'error',
msg: err.message,
},
});
}
}
},
async onPullDownRefresh() {
await this.refresh();
},
async onReachBottom() {
if (options.isList && options.append && options.projection) {
this.setState({
oakMoreLoading: true,
});
try {
await features.runningTree.loadMore(this.state.oakFullpath);
this.setState({
oakMoreLoading: false,
});
}
catch (err) {
this.setState({
oakMoreLoading: false,
oakError: {
type: 'error',
msg: err.message,
},
});
}
}
},
async onLoad(pageOption) {
return new Promise(async (resolve, reject) => {
try {
const { oakId, oakEntity, oakPath, oakProjection, oakParent, oakSorters, oakFilters, oakIsPicker, oakFrom, oakActions, ...props } = this.props;
(0, assert_1.default)(!(options.isList && oakId));
const filters = [];
if (oakFilters?.length > 0) {
// 这里在跳页面的时候用this.navigate应该可以限制传过来的filter的格式
const oakFilters2 = JSON.parse(oakFilters);
filters.push(...oakFilters2);
}
else if (options.filters) {
for (const ele of options.filters) {
const { filter, '#name': name } = ele;
filters.push({
filter: typeof filter === 'function'
? () => filter({
features,
props: this.props,
onLoadOptions: pageOption,
})
: filter,
['#name']: name,
});
}
}
let proj = oakProjection && JSON.parse(oakProjection);
if (!proj && options.projection) {
const { projection } = options;
proj =
typeof projection === 'function'
? () => projection({
features,
props: this.props,
onLoadOptions: pageOption,
})
: projection;
}
let sorters = [];
if (oakSorters?.length > 0) {
// 这里在跳页面的时候用this.navigate应该可以限制传过来的sorter的格式
const oakSorters2 = JSON.parse(oakSorters);
sorters.push(...oakSorters2);
}
else if (options.sorters) {
for (const ele of options.sorters) {
const { sorter, '#name': name } = ele;
sorters.push({
sorter: typeof sorter === 'function'
? () => sorter({
features,
props: this.props,
onLoadOptions: pageOption,
})
: sorter,
['#name']: name,
});
}
}
const path2 = oakParent
? `${oakParent}:${oakPath || options.path}`
: oakPath || options.path;
const node = await features.runningTree.createNode({
path: path2,
entity: (oakEntity || options.entity),
isList: options.isList,
isPicker: oakIsPicker,
projection: proj,
pagination: options.pagination,
filters,
sorters,
id: oakId,
});
// const oakFullpath = oakParent ? `${oakParent}.${oakPath || options.path}` : oakPath || options.path;
await this.setState({
oakEntity: node.getEntity(),
oakFullpath: path2,
oakFrom,
newOakActions: oakActions && JSON.parse(oakActions).length > 0
? JSON.parse(oakActions)
: options.actions || [],
}, () => {
this.refresh();
options.methods?.onLoad &&
options.methods.onLoad.call(this, pageOption);
resolve();
});
}
catch (e) {
reject(e);
}
});
},
};
}
exports.makePageMethods = makePageMethods;