mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 13:00:39 +03:00
R: Remove redundant useEffect
This commit is contained in:
parent
77479fb6fe
commit
e96ce964ca
|
@ -1,7 +1,7 @@
|
|||
'use client';
|
||||
|
||||
import clsx from 'clsx';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useState } from 'react';
|
||||
|
||||
import BadgeConstituenta from '@/components/info/BadgeConstituenta';
|
||||
import { CProps } from '@/components/props';
|
||||
|
@ -41,12 +41,13 @@ function PickMultiConstituenta({
|
|||
className,
|
||||
...restProps
|
||||
}: PickMultiConstituentaProps) {
|
||||
const [rowSelection, setRowSelection] = useState<RowSelectionState>({});
|
||||
const [filterText, setFilterText] = useState('');
|
||||
|
||||
const [filtered, setFiltered] = useState<IConstituenta[]>(items);
|
||||
const filtered = filterText ? items.filter(cst => matchConstituenta(cst, filterText, CstMatchMode.ALL)) : items;
|
||||
const rowSelection: RowSelectionState = Object.fromEntries(
|
||||
filtered.map((cst, index) => [String(index), value.includes(cst.id)])
|
||||
);
|
||||
|
||||
// TODO: extract graph fold logic to separate function
|
||||
const foldedGraph = (() => {
|
||||
if (items.length === schema.items.length) {
|
||||
return schema.graph;
|
||||
|
@ -66,28 +67,6 @@ function PickMultiConstituenta({
|
|||
return newGraph;
|
||||
})();
|
||||
|
||||
useEffect(() => {
|
||||
if (filtered.length === 0) {
|
||||
setRowSelection({});
|
||||
return;
|
||||
}
|
||||
const newRowSelection: RowSelectionState = {};
|
||||
filtered.forEach((cst, index) => {
|
||||
newRowSelection[String(index)] = value.includes(cst.id);
|
||||
});
|
||||
setRowSelection(newRowSelection);
|
||||
}, [filtered, setRowSelection, value]);
|
||||
|
||||
useEffect(() => {
|
||||
if (items.length === 0) {
|
||||
setFiltered([]);
|
||||
} else if (filterText) {
|
||||
setFiltered(items.filter(cst => matchConstituenta(cst, filterText, CstMatchMode.ALL)));
|
||||
} else {
|
||||
setFiltered(items);
|
||||
}
|
||||
}, [filterText, items]);
|
||||
|
||||
function handleRowSelection(updater: React.SetStateAction<RowSelectionState>) {
|
||||
if (!items) {
|
||||
onChange([]);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import clsx from 'clsx';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useState } from 'react';
|
||||
import { useIntl } from 'react-intl';
|
||||
|
||||
import { IconClose, IconFolderTree } from '@/components/Icons';
|
||||
|
@ -45,22 +45,18 @@ function PickSchema({
|
|||
...restProps
|
||||
}: PickSchemaProps) {
|
||||
const intl = useIntl();
|
||||
const [filterText, setFilterText] = useState(initialFilter);
|
||||
const [filterLocation, setFilterLocation] = useState('');
|
||||
const [filtered, setFiltered] = useState<ILibraryItem[]>([]);
|
||||
const baseFiltered = items.filter(item => item.item_type === itemType && (!baseFilter || baseFilter(item)));
|
||||
|
||||
const locationMenu = useDropdown();
|
||||
|
||||
useEffect(() => {
|
||||
let newFiltered = baseFiltered.filter(item => matchLibraryItem(item, filterText));
|
||||
if (filterLocation.length > 0) {
|
||||
newFiltered = newFiltered.filter(
|
||||
item => item.location === filterLocation || item.location.startsWith(`${filterLocation}/`)
|
||||
);
|
||||
}
|
||||
setFiltered(newFiltered);
|
||||
}, [filterText, filterLocation, baseFiltered]);
|
||||
const [filterText, setFilterText] = useState(initialFilter);
|
||||
const [filterLocation, setFilterLocation] = useState('');
|
||||
|
||||
const baseFiltered = items
|
||||
.filter(item => item.item_type === itemType && (!baseFilter || baseFilter(item)))
|
||||
.filter(item => matchLibraryItem(item, filterText));
|
||||
const filtered =
|
||||
filterLocation.length > 0
|
||||
? baseFiltered.filter(item => item.location === filterLocation || item.location.startsWith(`${filterLocation}/`))
|
||||
: baseFiltered;
|
||||
|
||||
const columns = [
|
||||
columnHelper.accessor('alias', {
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { CProps } from '@/components/props';
|
||||
import SelectMulti, { SelectMultiProps } from '@/components/ui/SelectMulti';
|
||||
import { Grammeme } from '@/models/language';
|
||||
|
@ -15,14 +13,10 @@ interface SelectMultiGrammemeProps
|
|||
}
|
||||
|
||||
function SelectMultiGrammeme({ value, onChange, ...restProps }: SelectMultiGrammemeProps) {
|
||||
const [options, setOptions] = useState<IGrammemeOption[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
const compatible = getCompatibleGrams(
|
||||
value.filter(data => Object.values(Grammeme).includes(data.value as Grammeme)).map(data => data.value as Grammeme)
|
||||
);
|
||||
setOptions(SelectorGrammemes.filter(({ value }) => compatible.includes(value as Grammeme)));
|
||||
}, [value]);
|
||||
const compatible = getCompatibleGrams(
|
||||
value.filter(data => Object.values(Grammeme).includes(data.value as Grammeme)).map(data => data.value as Grammeme)
|
||||
);
|
||||
const options = SelectorGrammemes.filter(({ value }) => compatible.includes(value as Grammeme));
|
||||
|
||||
return (
|
||||
<SelectMulti
|
||||
|
|
|
@ -3,14 +3,14 @@
|
|||
*/
|
||||
import { PARAMETER } from '@/utils/constants';
|
||||
|
||||
import { DependencyMode, Position2D } from './miscellaneous';
|
||||
import { DependencyMode, GraphFilterParams, Position2D } from './miscellaneous';
|
||||
import { IOperationPosition, IOperationSchema, OperationID, OperationType } from './oss';
|
||||
import { IConstituenta, IRSForm } from './rsform';
|
||||
import { ConstituentaID, CstType, IConstituenta, IRSForm } from './rsform';
|
||||
|
||||
/**
|
||||
* Filter list of {@link ILibraryItem} to a given graph query.
|
||||
*/
|
||||
export function applyGraphFilter(target: IRSForm, start: number, mode: DependencyMode): IConstituenta[] {
|
||||
export function applyGraphQuery(target: IRSForm, start: number, mode: DependencyMode): IConstituenta[] {
|
||||
if (mode === DependencyMode.ALL) {
|
||||
return target.items;
|
||||
}
|
||||
|
@ -87,3 +87,62 @@ export function calculateInsertPosition(
|
|||
} while (flagIntersect);
|
||||
return result;
|
||||
}
|
||||
|
||||
export function produceFilteredGraph(schema: IRSForm, params: GraphFilterParams, focusCst: IConstituenta | undefined) {
|
||||
const filtered = schema.graph.clone();
|
||||
const allowedTypes: CstType[] = (() => {
|
||||
const result: CstType[] = [];
|
||||
if (params.allowBase) result.push(CstType.BASE);
|
||||
if (params.allowStruct) result.push(CstType.STRUCTURED);
|
||||
if (params.allowTerm) result.push(CstType.TERM);
|
||||
if (params.allowAxiom) result.push(CstType.AXIOM);
|
||||
if (params.allowFunction) result.push(CstType.FUNCTION);
|
||||
if (params.allowPredicate) result.push(CstType.PREDICATE);
|
||||
if (params.allowConstant) result.push(CstType.CONSTANT);
|
||||
if (params.allowTheorem) result.push(CstType.THEOREM);
|
||||
return result;
|
||||
})();
|
||||
|
||||
if (params.noHermits) {
|
||||
filtered.removeIsolated();
|
||||
}
|
||||
if (params.noTemplates) {
|
||||
schema.items.forEach(cst => {
|
||||
if (cst !== focusCst && cst.is_template) {
|
||||
filtered.foldNode(cst.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (allowedTypes.length < Object.values(CstType).length) {
|
||||
schema.items.forEach(cst => {
|
||||
if (cst !== focusCst && !allowedTypes.includes(cst.cst_type)) {
|
||||
filtered.foldNode(cst.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!focusCst && params.foldDerived) {
|
||||
schema.items.forEach(cst => {
|
||||
if (cst.spawner) {
|
||||
filtered.foldNode(cst.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (focusCst) {
|
||||
const includes: ConstituentaID[] = [
|
||||
focusCst.id,
|
||||
...focusCst.spawn,
|
||||
...(params.focusShowInputs ? schema.graph.expandInputs([focusCst.id]) : []),
|
||||
...(params.focusShowOutputs ? schema.graph.expandOutputs([focusCst.id]) : [])
|
||||
];
|
||||
schema.items.forEach(cst => {
|
||||
if (!includes.includes(cst.id)) {
|
||||
filtered.foldNode(cst.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (params.noTransitive) {
|
||||
filtered.transitiveReduction();
|
||||
}
|
||||
|
||||
return filtered;
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ function FormConstituenta({ disabled, id, toggleReset, schema, activeCst, onOpen
|
|||
} = useForm<ICstUpdateDTO>({ resolver: zodResolver(CstUpdateSchema) });
|
||||
|
||||
const [localParse, setLocalParse] = useState<IExpressionParse | undefined>(undefined);
|
||||
|
||||
const typification = localParse
|
||||
? labelTypification({
|
||||
isValid: localParse.parseResult,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
'use client';
|
||||
|
||||
import fileDownload from 'js-file-download';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useState } from 'react';
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
import { useMutatingRSForm } from '@/backend/rsform/useMutatingRSForm';
|
||||
|
@ -11,7 +11,7 @@ import MiniButton from '@/components/ui/MiniButton';
|
|||
import Overlay from '@/components/ui/Overlay';
|
||||
import SearchBar from '@/components/ui/SearchBar';
|
||||
import { CstMatchMode } from '@/models/miscellaneous';
|
||||
import { ConstituentaID, CstType, IConstituenta } from '@/models/rsform';
|
||||
import { ConstituentaID, CstType } from '@/models/rsform';
|
||||
import { matchConstituenta } from '@/models/rsformAPI';
|
||||
import { useFitHeight } from '@/stores/appLayout';
|
||||
import { information } from '@/utils/labels';
|
||||
|
@ -22,34 +22,18 @@ import TableRSList from './TableRSList';
|
|||
import ToolbarRSList from './ToolbarRSList';
|
||||
|
||||
function EditorRSList() {
|
||||
const [rowSelection, setRowSelection] = useState<RowSelectionState>({});
|
||||
const controller = useRSEdit();
|
||||
const isProcessing = useMutatingRSForm();
|
||||
|
||||
const [filtered, setFiltered] = useState<IConstituenta[]>(controller.schema.items);
|
||||
const [filterText, setFilterText] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
if (filtered.length === 0) {
|
||||
setRowSelection({});
|
||||
return;
|
||||
}
|
||||
const newRowSelection: RowSelectionState = {};
|
||||
filtered.forEach((cst, index) => {
|
||||
newRowSelection[String(index)] = controller.selected.includes(cst.id);
|
||||
});
|
||||
setRowSelection(newRowSelection);
|
||||
}, [filtered, setRowSelection, controller.selected]);
|
||||
const filtered = filterText
|
||||
? controller.schema.items.filter(cst => matchConstituenta(cst, filterText, CstMatchMode.ALL))
|
||||
: controller.schema.items;
|
||||
|
||||
useEffect(() => {
|
||||
if (controller.schema.items.length === 0) {
|
||||
setFiltered([]);
|
||||
} else if (filterText) {
|
||||
setFiltered(controller.schema.items.filter(cst => matchConstituenta(cst, filterText, CstMatchMode.ALL)));
|
||||
} else {
|
||||
setFiltered(controller.schema.items);
|
||||
}
|
||||
}, [filterText, controller.schema.items]);
|
||||
const rowSelection: RowSelectionState = Object.fromEntries(
|
||||
filtered.map((cst, index) => [String(index), controller.selected.includes(cst.id)])
|
||||
);
|
||||
|
||||
function handleDownloadCSV() {
|
||||
if (filtered.length === 0) {
|
||||
|
|
|
@ -25,6 +25,7 @@ import SelectedCounter from '@/components/info/SelectedCounter';
|
|||
import { CProps } from '@/components/props';
|
||||
import ToolbarGraphSelection from '@/components/select/ToolbarGraphSelection';
|
||||
import Overlay from '@/components/ui/Overlay';
|
||||
import { produceFilteredGraph } from '@/models/miscellaneousAPI';
|
||||
import { ConstituentaID, CstType, IConstituenta } from '@/models/rsform';
|
||||
import { isBasicConcept } from '@/models/rsformAPI';
|
||||
import { useMainHeight } from '@/stores/appLayout';
|
||||
|
@ -42,7 +43,6 @@ import { TGNodeTypes } from './graph/TGNodeTypes';
|
|||
import GraphSelectors from './GraphSelectors';
|
||||
import ToolbarFocusedCst from './ToolbarFocusedCst';
|
||||
import ToolbarTermGraph from './ToolbarTermGraph';
|
||||
import useGraphFilter from './useGraphFilter';
|
||||
import ViewHidden from './ViewHidden';
|
||||
|
||||
const ZOOM_MAX = 3;
|
||||
|
@ -67,7 +67,7 @@ function TGFlow() {
|
|||
const [edges, setEdges] = useEdgesState([]);
|
||||
|
||||
const [focusCst, setFocusCst] = useState<IConstituenta | undefined>(undefined);
|
||||
const filteredGraph = useGraphFilter(controller.schema, filter, focusCst);
|
||||
const filteredGraph = produceFilteredGraph(controller.schema, filter, focusCst);
|
||||
const [hidden, setHidden] = useState<ConstituentaID[]>([]);
|
||||
|
||||
const [isDragging, setIsDragging] = useState(false);
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { Graph } from '@/models/Graph';
|
||||
import { GraphFilterParams } from '@/models/miscellaneous';
|
||||
import { ConstituentaID, CstType, IConstituenta, IRSForm } from '@/models/rsform';
|
||||
|
||||
function useGraphFilter(schema: IRSForm | undefined, params: GraphFilterParams, focusCst: IConstituenta | undefined) {
|
||||
const [filtered, setFiltered] = useState<Graph>(new Graph());
|
||||
|
||||
const allowedTypes: CstType[] = (() => {
|
||||
const result: CstType[] = [];
|
||||
if (params.allowBase) result.push(CstType.BASE);
|
||||
if (params.allowStruct) result.push(CstType.STRUCTURED);
|
||||
if (params.allowTerm) result.push(CstType.TERM);
|
||||
if (params.allowAxiom) result.push(CstType.AXIOM);
|
||||
if (params.allowFunction) result.push(CstType.FUNCTION);
|
||||
if (params.allowPredicate) result.push(CstType.PREDICATE);
|
||||
if (params.allowConstant) result.push(CstType.CONSTANT);
|
||||
if (params.allowTheorem) result.push(CstType.THEOREM);
|
||||
return result;
|
||||
})();
|
||||
|
||||
useEffect(() => {
|
||||
if (!schema) {
|
||||
setFiltered(new Graph());
|
||||
return;
|
||||
}
|
||||
const graph = schema.graph.clone();
|
||||
if (params.noHermits) {
|
||||
graph.removeIsolated();
|
||||
}
|
||||
if (params.noTemplates) {
|
||||
schema.items.forEach(cst => {
|
||||
if (cst !== focusCst && cst.is_template) {
|
||||
graph.foldNode(cst.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (allowedTypes.length < Object.values(CstType).length) {
|
||||
schema.items.forEach(cst => {
|
||||
if (cst !== focusCst && !allowedTypes.includes(cst.cst_type)) {
|
||||
graph.foldNode(cst.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!focusCst && params.foldDerived) {
|
||||
schema.items.forEach(cst => {
|
||||
if (cst.spawner) {
|
||||
graph.foldNode(cst.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (focusCst) {
|
||||
const includes: ConstituentaID[] = [
|
||||
focusCst.id,
|
||||
...focusCst.spawn,
|
||||
...(params.focusShowInputs ? schema.graph.expandInputs([focusCst.id]) : []),
|
||||
...(params.focusShowOutputs ? schema.graph.expandOutputs([focusCst.id]) : [])
|
||||
];
|
||||
schema.items.forEach(cst => {
|
||||
if (!includes.includes(cst.id)) {
|
||||
graph.foldNode(cst.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (params.noTransitive) {
|
||||
graph.transitiveReduction();
|
||||
}
|
||||
setFiltered(graph);
|
||||
}, [schema, params, allowedTypes, focusCst]);
|
||||
|
||||
return filtered;
|
||||
}
|
||||
|
||||
export default useGraphFilter;
|
|
@ -7,7 +7,7 @@ import SelectGraphFilter from '@/components/select/SelectGraphFilter';
|
|||
import SelectMatchMode from '@/components/select/SelectMatchMode';
|
||||
import MiniButton from '@/components/ui/MiniButton';
|
||||
import SearchBar from '@/components/ui/SearchBar';
|
||||
import { applyGraphFilter } from '@/models/miscellaneousAPI';
|
||||
import { applyGraphQuery } from '@/models/miscellaneousAPI';
|
||||
import { ConstituentaID, IConstituenta, IRSForm } from '@/models/rsform';
|
||||
import { matchConstituenta } from '@/models/rsformAPI';
|
||||
import { useCstSearchStore } from '@/stores/cstSearch';
|
||||
|
@ -40,7 +40,7 @@ function ConstituentsSearch({ schema, activeID, activeExpression, dense, onChang
|
|||
if (!activeID) {
|
||||
result = schema.items;
|
||||
} else {
|
||||
result = applyGraphFilter(schema, activeID, filterSource);
|
||||
result = applyGraphQuery(schema, activeID, filterSource);
|
||||
}
|
||||
if (query) {
|
||||
result = result.filter(cst => matchConstituenta(cst, query, filterMatch));
|
||||
|
|
Loading…
Reference in New Issue
Block a user