oak-frontend-base/es/components/relation/path/upsert/index.js

195 lines
5.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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();
}
}
});