aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sdnr/wt/odlux/apps/configurationApp/src/actions/deviceActions.ts24
-rw-r--r--sdnr/wt/odlux/apps/configurationApp/src/components/baseProps.ts5
-rw-r--r--sdnr/wt/odlux/apps/configurationApp/src/components/uiElementString.tsx6
-rw-r--r--sdnr/wt/odlux/apps/configurationApp/src/models/uiModels.ts5
-rw-r--r--sdnr/wt/odlux/apps/configurationApp/src/views/configurationApplication.tsx72
-rw-r--r--sdnr/wt/odlux/apps/configurationApp/src/yang/yangParser.ts55
6 files changed, 60 insertions, 107 deletions
diff --git a/sdnr/wt/odlux/apps/configurationApp/src/actions/deviceActions.ts b/sdnr/wt/odlux/apps/configurationApp/src/actions/deviceActions.ts
index 790d2515c..83134fc92 100644
--- a/sdnr/wt/odlux/apps/configurationApp/src/actions/deviceActions.ts
+++ b/sdnr/wt/odlux/apps/configurationApp/src/actions/deviceActions.ts
@@ -182,13 +182,25 @@ const resolveViewDescription = (defaultNS: string | null, vPath: string, view: V
// check if-feature | when | and resolve all references.
view = { ...view };
view.elements = Object.keys(view.elements).reduce<{ [name: string]: ViewElement }>((acc, cur) => {
- const elm = view.elements[cur];
+ const resolveHistory : ViewElement[] = [];
+ let elm = view.elements[cur];
const key = defaultNS && cur.replace(new RegExp(`^${defaultNS}:`, "i"),"") || cur;
- if (isViewElementReference(elm)) {
- acc[key] = { ...(elm.ref(vPath) || elm), id: key };
- } else {
- acc[key] = { ...elm, id: key };
- }
+ while (isViewElementReference(elm)) {
+ const result = (elm.ref(vPath));
+ if (result) {
+ const [referencedElement, referencedPath] = result;
+ if (resolveHistory.some(hist => hist === referencedElement)) {
+ console.error(`Circle reference found at: ${vPath}`, resolveHistory);
+ break;
+ }
+ elm = referencedElement;
+ vPath = referencedPath;
+ resolveHistory.push(elm);
+ }
+ }
+
+ acc[key] = { ...elm, id: key };
+
return acc;
}, {});
return view;
diff --git a/sdnr/wt/odlux/apps/configurationApp/src/components/baseProps.ts b/sdnr/wt/odlux/apps/configurationApp/src/components/baseProps.ts
index 73812a4b8..c08f5c9bc 100644
--- a/sdnr/wt/odlux/apps/configurationApp/src/components/baseProps.ts
+++ b/sdnr/wt/odlux/apps/configurationApp/src/components/baseProps.ts
@@ -23,5 +23,6 @@ export type BaseProps<TValue = string> = {
inputValue: TValue,
readOnly: boolean,
disabled: boolean,
- onChange(newValue: TValue): void
-};
+ onChange(newValue: TValue): void,
+ isKey?: boolean
+}; \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/configurationApp/src/components/uiElementString.tsx b/sdnr/wt/odlux/apps/configurationApp/src/components/uiElementString.tsx
index 95841b75d..122f7150a 100644
--- a/sdnr/wt/odlux/apps/configurationApp/src/components/uiElementString.tsx
+++ b/sdnr/wt/odlux/apps/configurationApp/src/components/uiElementString.tsx
@@ -23,7 +23,7 @@ import { BaseProps } from "./baseProps";
import { IfWhenTextInput } from "./ifWhenTextInput";
import { checkRange, checkPattern } from "./verifyer";
-type stringEntryProps = BaseProps & { isKey: boolean };
+type stringEntryProps = BaseProps;
export const UiElementString = (props: stringEntryProps) => {
@@ -71,7 +71,7 @@ export const UiElementString = (props: stringEntryProps) => {
<Tooltip title={isTooltipVisible ? element.description || '' : ''}>
<IfWhenTextInput element={element} onChangeTooltipVisuability={setTooltipVisibility}
spellCheck={false} autoFocus margin="dense"
- id={element.id} label={props.isKey ? "🔑 " + element.label : element.label} type="text" value={props.inputValue}
+ id={element.id} label={props?.isKey ? "🔑 " + element.label : element.label} type="text" value={props.inputValue}
style={{ width: 485, marginLeft: 20, marginRight: 20 }}
onChange={(e: any) => { verifyValues(e.target.value) }}
error={isError}
@@ -81,4 +81,4 @@ export const UiElementString = (props: stringEntryProps) => {
/>
</Tooltip>
);
-} \ No newline at end of file
+}
diff --git a/sdnr/wt/odlux/apps/configurationApp/src/models/uiModels.ts b/sdnr/wt/odlux/apps/configurationApp/src/models/uiModels.ts
index f0391eebf..a5a52fc2e 100644
--- a/sdnr/wt/odlux/apps/configurationApp/src/models/uiModels.ts
+++ b/sdnr/wt/odlux/apps/configurationApp/src/models/uiModels.ts
@@ -101,7 +101,7 @@ export type ViewElementList = (ViewElementBase & {
export type ViewElementReference = ViewElementBase & {
"uiType": "reference";
"referencePath": string;
- "ref": (currentPath: string) => ViewElement | null;
+ "ref": (currentPath: string) => [ViewElement , string] | undefined;
}
export type ViewElementUnion = ViewElementBase & {
@@ -196,13 +196,14 @@ export const ResolveFunction = Symbol("IsResolved");
export type ViewSpecification = {
"id": string;
+ "ns"?: string;
"name"?: string;
"title"?: string;
"parentView"?: string;
"language": string;
"ifFeature"?: string;
"when"?: string;
- "uses"?: (string[]) & { [ResolveFunction]?: () => void };
+ "uses"?: (string[]) & { [ResolveFunction]?: (parent: string) => void };
"elements": { [name: string]: ViewElement };
readonly "canEdit": boolean;
}
diff --git a/sdnr/wt/odlux/apps/configurationApp/src/views/configurationApplication.tsx b/sdnr/wt/odlux/apps/configurationApp/src/views/configurationApplication.tsx
index fc3c68e88..7b927785d 100644
--- a/sdnr/wt/odlux/apps/configurationApp/src/views/configurationApplication.tsx
+++ b/sdnr/wt/odlux/apps/configurationApp/src/views/configurationApplication.tsx
@@ -332,6 +332,7 @@ class ConfigurationApplicationComponent extends React.Component<ConfigurationApp
? (
<Element
key={uiElement.id}
+ isKey={isKey}
inputValue={viewData[uiElement.id] == null ? '' : viewData[uiElement.id]}
value={uiElement}
readOnly={!canEdit}
@@ -340,75 +341,6 @@ class ConfigurationApplicationComponent extends React.Component<ConfigurationApp
/> )
: null ;
}
-
- // // do not show elements w/o any value from the backend
- // if (viewData[uiElement.id] == null && !editMode) {
- // return null;
- // } else if (isViewElementEmpty(uiElement)) {
- // return null;
- // } else if (uiElement.isList) {
- // /* element is a leaf-list */
- // return <UiElementLeafList
- // key={uiElement.id}
- // inputValue={viewData[uiElement.id] || ''}
- // value={uiElement}
- // readOnly={!canEdit}
- // disabled={editMode && !canEdit}
- // onChange={(e) => { this.changeValueFor(uiElement.id, e) }}
- // />;
- // } else if (isViewElementSelection(uiElement)) {
-
- // return <UiElementSelection
- // key={uiElement.id}
- // inputValue={viewData[uiElement.id] || ''}
- // value={uiElement}
- // readOnly={!canEdit}
- // disabled={editMode && !canEdit}
- // onChange={(e) => { this.changeValueFor(uiElement.id, e) }}
- // />
-
- // } else if (isViewElementBoolean(uiElement)) {
- // return <UiElementBoolean
- // key={uiElement.id}
- // inputValue={viewData[uiElement.id] == null ? '' : viewData[uiElement.id]}
- // value={uiElement}
- // readOnly={!canEdit}
- // disabled={editMode && !canEdit}
- // onChange={(e) => { this.changeValueFor(uiElement.id, e) }} />
-
- // } else if (isViewElementString(uiElement)) {
- // return <UiElementString
- // key={uiElement.id}
- // inputValue={viewData[uiElement.id] == null ? '' : viewData[uiElement.id]}
- // value={uiElement}
- // isKey={isKey}
- // readOnly={!canEdit}
- // disabled={editMode && !canEdit}
- // onChange={(e) => { this.changeValueFor(uiElement.id, e) }} />
-
- // } else if (isViewElementNumber(uiElement)) {
- // return <UiElementNumber
- // key={uiElement.id}
- // value={uiElement}
- // inputValue={viewData[uiElement.id] == null ? '' : viewData[uiElement.id]}
- // readOnly={!canEdit}
- // disabled={editMode && !canEdit}
- // onChange={(e) => { this.changeValueFor(uiElement.id, e) }} />
- // } else if (isViewElementUnion(uiElement)) {
- // return <UIElementUnion
- // key={uiElement.id}
- // isKey={false}
- // value={uiElement}
- // inputValue={viewData[uiElement.id] == null ? '' : viewData[uiElement.id]}
- // readOnly={!canEdit}
- // disabled={editMode && !canEdit}
- // onChange={(e) => { this.changeValueFor(uiElement.id, e) }} />
- // } else {
- // if (process.env.NODE_ENV !== "production") {
- // console.error(`Unknown element type - ${(uiElement as any).uiType} in ${(uiElement as any).id}.`)
- // }
- // return null;
- // }
};
// private renderUIReference = (uiElement: ViewElement, viewData: { [key: string]: any }, keyProperty: string | undefined, editMode: boolean, isNew: boolean) => {
@@ -817,4 +749,4 @@ class ConfigurationApplicationComponent extends React.Component<ConfigurationApp
}
export const ConfigurationApplication = withStyles(styles)(withRouter(connect(mapProps, mapDispatch)(ConfigurationApplicationComponent)));
-export default ConfigurationApplication; \ No newline at end of file
+export default ConfigurationApplication;
diff --git a/sdnr/wt/odlux/apps/configurationApp/src/yang/yangParser.ts b/sdnr/wt/odlux/apps/configurationApp/src/yang/yangParser.ts
index b1c1e7430..0f74297df 100644
--- a/sdnr/wt/odlux/apps/configurationApp/src/yang/yangParser.ts
+++ b/sdnr/wt/odlux/apps/configurationApp/src/yang/yangParser.ts
@@ -437,8 +437,8 @@ export class YangParser {
// process all groupings
this._groupingsToResolve.filter(vs => vs.uses && vs.uses[ResolveFunction]).forEach(vs => {
- try { vs.uses![ResolveFunction]!(); } catch (error) {
- console.warn(`Error resolving: [${error.message}]`);
+ try { vs.uses![ResolveFunction] !== undefined && vs.uses![ResolveFunction]!("|"); } catch (error) {
+ console.warn(`Error resolving: [${vs.name}] [${error.message}]`);
}
});
@@ -660,7 +660,7 @@ export class YangParser {
}
const key = this.extractValue(cur, "key") || undefined;
if (elmConfig && !key) {
- console.error(new Error(`Module: [${context.name}]${currentPath}. Found configurable list without key.`));
+ console.warn(`Module: [${context.name}]${currentPath}. Found configurable list without key. Assume config shell be false.`);
elmConfig = false;
}
const [currentView, subViews] = this.extractSubViews(cur, currentId, context, `${currentPath}/${context.name}:${cur.arg}`);
@@ -821,6 +821,7 @@ export class YangParser {
const viewSpec: ViewSpecification = {
id: String(currentId),
parentView: String(parentId),
+ ns: context.name,
name: statement.arg != null ? statement.arg : undefined,
title: statement.arg != null ? statement.arg : undefined,
language: "en-us",
@@ -848,7 +849,7 @@ export class YangParser {
if (usesRefs && usesRefs.length > 0) {
viewSpec.uses = (viewSpec.uses || []);
- const resolveFunctions : (()=>void)[] = [];
+ const resolveFunctions : ((parentElementPath: string)=>void)[] = [];
for (let i = 0; i < usesRefs.length; ++i) {
const groupingName = usesRefs[i].arg;
@@ -857,14 +858,14 @@ export class YangParser {
}
viewSpec.uses.push(this.resolveReferencePath(groupingName, context));
-
- resolveFunctions.push(() => {
+
+ resolveFunctions.push((parentElementPath: string) => {
const groupingViewSpec = this.resolveGrouping(groupingName, context);
if (groupingViewSpec) {
// resolve recursive
const resolveFunc = groupingViewSpec.uses && groupingViewSpec.uses[ResolveFunction];
- resolveFunc && resolveFunc();
+ resolveFunc && resolveFunc(parentElementPath);
Object.keys(groupingViewSpec.elements).forEach(key => {
const elm = groupingViewSpec.elements[key];
@@ -878,14 +879,16 @@ export class YangParser {
});
}
- viewSpec.uses[ResolveFunction] = () => {
- resolveFunctions.forEach(res => {
- try {
- res();
- } catch (error) {
- console.error(error);
- }
+ viewSpec.uses[ResolveFunction] = (parentElementPath: string) => {
+ const currentElementPath = `${parentElementPath} -> ${viewSpec.ns}:${viewSpec.name}`;
+ resolveFunctions.forEach(resolve => {
+ try {
+ resolve(currentElementPath);
+ } catch (error) {
+ console.error(error);
+ }
});
+ // console.log("Resolved "+currentElementPath, viewSpec);
viewSpec?.uses![ResolveFunction] = undefined;
}
@@ -1136,9 +1139,14 @@ export class YangParser {
uiType: "reference",
referencePath: refPath,
ref(this: ViewElement, currentPath: string) {
- const resolved = resolve(refPath, currentPath);
- return resolved && {
- ...resolved,
+ const elementPath = `${currentPath}/${cur.arg}`;
+
+ const result = resolve(refPath, elementPath);
+ if (!result) return undefined;
+
+ const [resolvedElement, resolvedPath] = result;
+ return resolvedElement && [{
+ ...resolvedElement,
id: this.id,
label: this.label,
config: this.config,
@@ -1146,7 +1154,7 @@ export class YangParser {
isList: this.isList,
default: this.default,
description: this.description,
- } as ViewElement;
+ } as ViewElement , resolvedPath] || undefined;
}
};
return res;
@@ -1309,7 +1317,7 @@ export class YangParser {
const vPathParts = splitVPath(vPath, vPathParser).map(p => ({ ns: p[1], property: p[2], ind: p[3] }));
const resultPathParts = !vPath.startsWith("/")
- ? splitVPath(currentPath, vPathParser).map(p => ({ ns: p[1], property: p[2], ind: p[3] }))
+ ? splitVPath(currentPath, vPathParser).map(p => { moduleName = p[1] || moduleName ; return { ns: moduleName, property: p[2], ind: p[3] } })
: [];
for (let i = 0; i < vPathParts.length; ++i) {
@@ -1333,17 +1341,16 @@ export class YangParser {
const view: ViewSpecification = this._views[+element.viewId];
if (moduleName !== pathPart.ns) {
moduleName = pathPart.ns;
- element = view.elements[`${moduleName}:${pathPart.property}`];
- } else {
- element = view.elements[pathPart.property] || view.elements[`${moduleName}:${pathPart.property}`];
- }
+ }
+ element = view.elements[pathPart.property] || view.elements[`${moduleName}:${pathPart.property}`];
} else {
throw new Error("Could not resolve reference.\r\n" + vPath);
}
if (!element) throw new Error("Could not resolve path [" + pathPart.property + "] in [" + currentPath + "] \r\n" + vPath);
}
- return element;
+ moduleName = ""; // create the vPath for the resolved element, do not add the element itself this will be done later in the res(...) function
+ return [element, resultPathParts.slice(0,-1).map(p => `${moduleName !== p.ns ? `${moduleName=p.ns}:` : ""}${p.property}${p.ind || ''}`).join("/")];
}
private resolveView(vPath: string) {