import assert from 'assert'; import { unset } from 'oak-domain/lib/utils/lodash'; const SystemEntities = [ 'modi', 'modiEntity', 'oper', 'operEntity', 'userEntityGrant', 'relation', 'userRelation', 'actionAuth', 'relationAuth', 'i18n', 'path', 'userEntityClaim' ]; function buildEntityGraph(schema) { const graph = {}; const addToGraph = (entity, path, descendant, type) => { if (graph[entity]) { graph[entity].push({ path, entity: descendant, type, }); } else { graph[entity] = [ { path, entity: descendant, type, } ]; } }; for (const entity in schema) { if (SystemEntities.includes(entity)) { continue; } const { attributes } = schema[entity]; for (const attr in attributes) { const attrDef = attributes[attr]; if (attr === 'entity') { attrDef.ref?.forEach((ele) => { addToGraph(entity, ele, ele, 'entity'); addToGraph(ele, `${entity}$entity`, entity, 'entityOtm'); }); } else if (attrDef.ref) { const attr2 = attr.slice(0, attr.length - 2); addToGraph(entity, attr2, attrDef.ref, 'attr'); addToGraph(attrDef.ref, `${entity}$${attr2}`, entity, 'attrOtm'); } } } unset(graph, 'user'); return graph; } export default OakComponent({ entity: 'path', isList: false, projection: { id: 1, destEntity: 1, value: 1, sourceEntity: 1, desc: 1, recursive: 1, }, formData({ data }) { const { graph } = this.state; const recursivable = data?.sourceEntity && graph && graph[data.sourceEntity]?.find(ele => ele.entity === data.sourceEntity); return { isCreate: data?.$$createAt$$ === 1, path: data, recursivable, oakExecutable: this.tryExecute(), }; }, properties: { onConfirmed: () => undefined, entity: '', }, data: { entities: [], graph: {}, pathChoice: [], pathChosen: [], recursivable: false, legalSourceEntity: false, destEntityFixed: false, }, lifetimes: { ready() { const schema = this.features.cache.getSchema(); const entities = Object.keys(schema).filter(ele => !SystemEntities.includes(ele) && ele !== 'user'); const graph = buildEntityGraph(schema); const { entity } = this.props; this.setState({ entities, graph, destEntityFixed: !!entity, legalSourceEntity: !this.isCreation(), }, () => { this.updateDestEntity(entity); }); } }, methods: { updateDestEntity(de) { const { graph } = this.state; if (de) { const pathChoice = (graph[de] || []).filter(ele => { if (ele.entity === de) { return false; } return true; }); const schema = this.features.cache.getSchema(); const legalSourceEntity = !!schema[de].relation?.length || de === 'user'; this.update({ destEntity: de, sourceEntity: de, value: '', recursive: false, desc: null, }); this.setState({ pathChoice, pathChosen: [], legalSourceEntity, }); } else { this.update({ value: '', }); this.setState({ pathChosen: [], }); } }, selectPath(value) { const { pathChoice, pathChosen } = this.state; const choice = pathChoice.find(ele => ele.path === value); assert(choice); const pathChosen2 = pathChosen.concat([choice]); const { graph } = this.state; const entities = pathChosen2.map(ele => ele.entity); // path按道理不应该产生重复,如果有出现重复再处理 by Xc 20240628 const pathChoice2 = (graph[choice.entity] || []).filter(ele => { if (!entities.includes(ele.entity)) { return true; } return false; }); const schema = this.features.cache.getSchema(); const legalSourceEntity = !!schema[choice.entity].relation?.length || !!choice.entity; this.setState({ pathChoice: pathChoice2, pathChosen: pathChosen2, legalSourceEntity, }); this.update({ sourceEntity: choice.entity, recursive: false, desc: null, }); }, resetPath() { const { path } = this.state; this.updateDestEntity(path.destEntity); }, clearDestEntity() { this.clean(); this.setState({ legalSourceEntity: false, }); }, async confirm() { const { pathChosen, isCreate } = this.state; if (isCreate) { const value = pathChosen.map(ele => ele.path).join('.'); this.update({ value, }); } const { onConfirmed } = this.props; assert(onConfirmed); onConfirmed(); } } });