Конституента {data.alias}
- {data.derived_alias ? (
+ {data.derived_from_alias ? (
- Основана на:
- {data.derived_alias}
+ Основание:
+ {data.derived_from_alias}
) : null}
- {data.derived_children.length > 0 ? (
+ {data.derived_children_alias.length > 0 ? (
Порождает:
- {data.derived_children.join(', ')}
+ {data.derived_children_alias.join(', ')}
) : null}
diff --git a/rsconcept/frontend/src/components/man/HelpConstituenta.tsx b/rsconcept/frontend/src/components/man/HelpConstituenta.tsx
index 5d577dd4..f3238510 100644
--- a/rsconcept/frontend/src/components/man/HelpConstituenta.tsx
+++ b/rsconcept/frontend/src/components/man/HelpConstituenta.tsx
@@ -6,6 +6,7 @@ function HelpConstituenta() {
return (
Редактор конституент
+
При выделении также подсвечиваются производные и основание
Сохранить изменения: Ctrl + S или клик по кнопке Сохранить
Формальное определение
- Ctrl + Пробел дополняет до незанятого имени
diff --git a/rsconcept/frontend/src/dialogs/DlgGraphParams.tsx b/rsconcept/frontend/src/dialogs/DlgGraphParams.tsx
index dde5357f..3f04cf52 100644
--- a/rsconcept/frontend/src/dialogs/DlgGraphParams.tsx
+++ b/rsconcept/frontend/src/dialogs/DlgGraphParams.tsx
@@ -57,7 +57,7 @@ function DlgGraphParams({ hideWindow, initial, onConfirm }: DlgGraphParamsProps)
/>
updateParams({ foldDerived: value })}
/>
diff --git a/rsconcept/frontend/src/models/rsform.ts b/rsconcept/frontend/src/models/rsform.ts
index 08924ea7..d066feff 100644
--- a/rsconcept/frontend/src/models/rsform.ts
+++ b/rsconcept/frontend/src/models/rsform.ts
@@ -97,8 +97,9 @@ export interface IConstituenta extends IConstituentaMeta {
status: ExpressionStatus;
is_template: boolean;
derived_from: ConstituentaID;
- derived_alias?: string;
- derived_children: string[];
+ derived_from_alias?: string;
+ derived_children: number[];
+ derived_children_alias: string[];
parse: {
status: ParsingStatus;
valueClass: ValueClass;
diff --git a/rsconcept/frontend/src/models/rsformAPI.ts b/rsconcept/frontend/src/models/rsformAPI.ts
index 807352b4..05be1929 100644
--- a/rsconcept/frontend/src/models/rsformAPI.ts
+++ b/rsconcept/frontend/src/models/rsformAPI.ts
@@ -37,6 +37,7 @@ export function loadRSFormData(input: IRSFormData): IRSForm {
derivationLookup.set(cst.id, cst.id);
cst.derived_from = cst.id;
cst.derived_children = [];
+ cst.derived_children_alias = [];
cst.status = inferStatus(cst.parse.status, cst.parse.valueClass);
cst.is_template = inferTemplate(cst.definition_formal);
cst.cst_class = inferClass(cst.cst_type, cst.is_template);
@@ -72,8 +73,9 @@ export function loadRSFormData(input: IRSFormData): IRSForm {
if (resolvedInput.size === 1 && isSimpleExpression(definition)) {
const parent = result.items.find(item => item.id === resolvedInput.values().next().value)!;
cst.derived_from = parent.id;
- cst.derived_alias = parent.alias;
- parent.derived_children.push(cst.alias);
+ cst.derived_from_alias = parent.alias;
+ parent.derived_children_alias.push(cst.alias);
+ parent.derived_children.push(cst.id);
derivationLookup.set(cst.id, parent.id);
}
});
@@ -208,6 +210,7 @@ export function createMockConstituenta(id: ConstituentaID, alias: string, commen
id: id,
derived_from: id,
derived_children: [],
+ derived_children_alias: [],
order: -1,
schema: -1,
alias: alias,
diff --git a/rsconcept/frontend/src/models/rslangAPI.test.ts b/rsconcept/frontend/src/models/rslangAPI.test.ts
index 32d61f1b..d1e7a483 100644
--- a/rsconcept/frontend/src/models/rslangAPI.test.ts
+++ b/rsconcept/frontend/src/models/rslangAPI.test.ts
@@ -19,6 +19,8 @@ const simpleExpressionData = [
['pr1(S1)', 'true'],
['red(S1)', 'true'],
['red(Pr1(F1[α,σ]))', 'true'],
+ ['ℬℬ(X1)', 'false'],
+ ['ℬ(X1)', 'false'],
['D{(α,β)∈D6×D6 | α≠β & α∩β≠∅}', 'false'],
['I{(β,α) | α:∈D2; σ:=F5[α]; β:∈σ}', 'false'],
['∀σ∈S1 (F1[σ]×F1[σ])∩D11=∅', 'false']
diff --git a/rsconcept/frontend/src/models/rslangAPI.ts b/rsconcept/frontend/src/models/rslangAPI.ts
index 2cadb795..854bd15f 100644
--- a/rsconcept/frontend/src/models/rslangAPI.ts
+++ b/rsconcept/frontend/src/models/rslangAPI.ts
@@ -24,7 +24,7 @@ export function extractGlobals(expression: string): Set {
* Check if expression is simple derivation.
*/
export function isSimpleExpression(text: string): boolean {
- return !COMPLEX_SYMBOLS_REGEXP.test(text);
+ return !text.match(COMPLEX_SYMBOLS_REGEXP);
}
/**
diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/EditorTermGraph.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/EditorTermGraph.tsx
index 74227e11..defe6c76 100644
--- a/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/EditorTermGraph.tsx
+++ b/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/EditorTermGraph.tsx
@@ -92,7 +92,9 @@ function EditorTermGraph({ onOpenEdit }: EditorTermGraphProps) {
result.push({
id: String(node.id),
fill: colorBgGraphNode(cst, coloringScheme, colors),
- label: cst.term_resolved && !filterParams.noText ? `${cst.alias}: ${cst.term_resolved}` : cst.alias
+ label: cst.alias,
+ subLabel: !filterParams.noText ? cst.term_resolved : undefined,
+ size: cst.derived_from_alias ? 1 : 2
});
}
});
@@ -164,6 +166,16 @@ function EditorTermGraph({ onOpenEdit }: EditorTermGraphProps) {
}
}
+ const handleFoldDerived = useCallback(() => {
+ setFilterParams(prev => ({
+ ...prev,
+ foldDerived: !prev.foldDerived
+ }));
+ setTimeout(() => {
+ setToggleResetView(prev => !prev);
+ }, TIMEOUT_GRAPH_REFRESH);
+ }, [setFilterParams, setToggleResetView]);
+
const graph = useMemo(
() => (
setToggleResetView(prev => !prev)}
toggleOrbit={() => setOrbit(prev => !prev)}
- toggleFoldDerived={() =>
- setFilterParams(prev => ({
- ...prev,
- foldDerived: !prev.foldDerived
- }))
- }
+ toggleFoldDerived={handleFoldDerived}
toggleNoText={() =>
setFilterParams(prev => ({
...prev,
diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/GraphToolbar.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/GraphToolbar.tsx
index 886e5829..35768021 100644
--- a/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/GraphToolbar.tsx
+++ b/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/GraphToolbar.tsx
@@ -74,7 +74,7 @@ function GraphToolbar({
onClick={toggleNoText}
/>
diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/TermGraph.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/TermGraph.tsx
index 769fa59f..3a1cfd77 100644
--- a/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/TermGraph.tsx
+++ b/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/TermGraph.tsx
@@ -45,8 +45,8 @@ function TermGraph({
const { selections, setSelections } = useSelection({
ref: graphRef,
- nodes,
- edges,
+ nodes: nodes,
+ edges: edges,
type: 'multi'
});
@@ -110,6 +110,8 @@ function TermGraph({
onNodeClick={handleNodeClick}
onNodePointerOver={handleHoverIn}
onNodePointerOut={handleHoverOut}
+ minNodeSize={4}
+ maxNodeSize={8}
cameraMode={orbit ? 'orbit' : is3D ? 'rotate' : 'pan'}
layoutOverrides={
layout.includes('tree') ? { nodeLevelRatio: nodes.length < TREE_SIZE_MILESTONE ? 3 : 1 } : undefined
diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/useGraphFilter.ts b/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/useGraphFilter.ts
index 1be288fe..38382b24 100644
--- a/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/useGraphFilter.ts
+++ b/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/useGraphFilter.ts
@@ -48,7 +48,7 @@ function useGraphFilter(schema: IRSForm | undefined, params: GraphFilterParams)
}
if (params.foldDerived) {
schema.items.forEach(cst => {
- if (cst.derived_alias) {
+ if (cst.derived_from_alias) {
graph.foldNode(cst.id);
}
});
diff --git a/rsconcept/frontend/src/pages/RSFormPage/ViewConstituents/ConstituentsTable.tsx b/rsconcept/frontend/src/pages/RSFormPage/ViewConstituents/ConstituentsTable.tsx
index 50b021d2..18c5395a 100644
--- a/rsconcept/frontend/src/pages/RSFormPage/ViewConstituents/ConstituentsTable.tsx
+++ b/rsconcept/frontend/src/pages/RSFormPage/ViewConstituents/ConstituentsTable.tsx
@@ -108,6 +108,18 @@ function ConstituentsTable({ items, activeID, onOpenEdit, maxHeight, denseThresh
style: {
backgroundColor: colors.bgSelected
}
+ },
+ {
+ when: (cst: IConstituenta) => cst.derived_from === activeID && cst.id !== activeID,
+ style: {
+ backgroundColor: colors.bgOrange50
+ }
+ },
+ {
+ when: (cst: IConstituenta) => activeID !== undefined && cst.derived_children.includes(activeID),
+ style: {
+ backgroundColor: colors.bgGreen50
+ }
}
],
[activeID, colors]
diff --git a/rsconcept/frontend/src/styling/color.ts b/rsconcept/frontend/src/styling/color.ts
index 07ccb678..ee850cbd 100644
--- a/rsconcept/frontend/src/styling/color.ts
+++ b/rsconcept/frontend/src/styling/color.ts
@@ -35,6 +35,9 @@ export interface IColorTheme {
bgTeal: string;
bgOrange: string;
+ bgGreen50: string;
+ bgOrange50: string;
+
fgRed: string;
fgGreen: string;
fgBlue: string;
@@ -72,6 +75,9 @@ export const lightT: IColorTheme = {
bgTeal: 'hsl(192, 089%, 081%)',
bgOrange: 'hsl(028, 100%, 075%)',
+ bgGreen50: 'hsl(100, 100%, 090%)',
+ bgOrange50: 'hsl(028, 100%, 095%)',
+
fgRed: 'hsl(000, 090%, 045%)',
fgGreen: 'hsl(100, 090%, 035%)',
fgBlue: 'hsl(235, 100%, 050%)',
@@ -109,6 +115,9 @@ export const darkT: IColorTheme = {
bgTeal: 'hsl(192, 080%, 030%)',
bgOrange: 'hsl(035, 100%, 035%)',
+ bgGreen50: 'hsl(100, 080%, 017%)',
+ bgOrange50: 'hsl(035, 100%, 015%)',
+
fgRed: 'hsl(000, 080%, 045%)',
fgGreen: 'hsl(100, 080%, 035%)',
fgBlue: 'hsl(235, 100%, 080%)',