Compare commits

...

5 Commits

Author SHA1 Message Date
IRBorisov
dbfab8446c Update HelpContributors.tsx
Some checks failed
Frontend CI / build (18.x) (push) Waiting to run
Backend CI / build (3.12) (push) Has been cancelled
2024-06-26 10:10:47 +03:00
IRBorisov
552fb67f09 Fix context loading semantics
Loading is a flag for data loading on context create
Processing is a flag for waiting for response after function call
2024-06-23 19:42:54 +03:00
IRBorisov
9ce0607cc3 Small fixes 2024-06-23 14:20:37 +03:00
IRBorisov
379f70c2b1 Improve help page 2024-06-23 13:44:34 +03:00
IRBorisov
9a009e0131 Small UI fix 2024-06-23 00:12:18 +03:00
16 changed files with 58 additions and 59 deletions

View File

@ -38,6 +38,10 @@
{ {
"name": "django", "name": "django",
"depth": 5 "depth": 5
},
{
"name": "djangorestframework",
"depth": 2
} }
], ],
"colorize.include": [".tsx", ".jsx", ".ts", ".js"], "colorize.include": [".tsx", ".jsx", ".ts", ".js"],

View File

@ -91,7 +91,7 @@ class Graph(Generic[ItemType]):
if len(self.inputs[node_id]) == 0: if len(self.inputs[node_id]) == 0:
continue continue
for parent in self.inputs[node_id]: for parent in self.inputs[node_id]:
result[parent] = result[parent] + [id for id in result[node_id] if not id in result[parent]] result[parent] = result[parent] + [id for id in result[node_id] if id not in result[parent]]
return result return result
def topological_order(self) -> list[ItemType]: def topological_order(self) -> list[ItemType]:

View File

@ -60,12 +60,12 @@ class Editor(Model):
''' Set editors for item. ''' ''' Set editors for item. '''
processed: list[User] = [] processed: list[User] = []
for editor_item in Editor.objects.filter(item=item): for editor_item in Editor.objects.filter(item=item):
if not editor_item.editor in users: if editor_item.editor not in users:
editor_item.delete() editor_item.delete()
else: else:
processed.append(editor_item.editor) processed.append(editor_item.editor)
for user in users: for user in users:
if not user in processed: if user not in processed:
processed.append(user) processed.append(user)
Editor.objects.create(item=item, editor=user) Editor.objects.create(item=item, editor=user)

View File

@ -48,19 +48,9 @@ function Navigation() {
<Logo /> <Logo />
</div> </div>
<div className='flex gap-1 py-[0.3rem]'> <div className='flex gap-1 py-[0.3rem]'>
<NavigationButton <NavigationButton text='Новая схема' icon={<IconNewItem2 size='1.5rem' />} onClick={navigateCreateNew} />
text='Новая схема' <NavigationButton text='Библиотека' icon={<IconLibrary2 size='1.5rem' />} onClick={navigateLibrary} />
title='Создать новую схему' <NavigationButton text='Справка' icon={<IconManuals size='1.5rem' />} onClick={navigateHelp} />
icon={<IconNewItem2 size='1.5rem' />}
onClick={navigateCreateNew}
/>
<NavigationButton
text='Библиотека'
title='Список схем'
icon={<IconLibrary2 size='1.5rem' />}
onClick={navigateLibrary}
/>
<NavigationButton text='Справка' title='Справочные материалы' icon={<IconManuals />} onClick={navigateHelp} />
<UserMenu /> <UserMenu />
</div> </div>
</motion.div> </motion.div>

View File

@ -70,7 +70,7 @@ export const LibraryState = ({ children }: LibraryStateProps) => {
const [items, setItems] = useState<ILibraryItem[]>([]); const [items, setItems] = useState<ILibraryItem[]>([]);
const [templates, setTemplates] = useState<ILibraryItem[]>([]); const [templates, setTemplates] = useState<ILibraryItem[]>([]);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(true);
const [processing, setProcessing] = useState(false); const [processing, setProcessing] = useState(false);
const [loadingError, setLoadingError] = useState<ErrorData>(undefined); const [loadingError, setLoadingError] = useState<ErrorData>(undefined);
const [processingError, setProcessingError] = useState<ErrorData>(undefined); const [processingError, setProcessingError] = useState<ErrorData>(undefined);

View File

@ -36,7 +36,7 @@ interface UserProfileStateProps {
export const UserProfileState = ({ children }: UserProfileStateProps) => { export const UserProfileState = ({ children }: UserProfileStateProps) => {
const { users } = useUsers(); const { users } = useUsers();
const [user, setUser] = useState<IUserProfile | undefined>(undefined); const [user, setUser] = useState<IUserProfile | undefined>(undefined);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(true);
const [processing, setProcessing] = useState(false); const [processing, setProcessing] = useState(false);
const [error, setError] = useState<ErrorData>(undefined); const [error, setError] = useState<ErrorData>(undefined);
const [errorProcessing, setErrorProcessing] = useState<ErrorData>(undefined); const [errorProcessing, setErrorProcessing] = useState<ErrorData>(undefined);

View File

@ -86,11 +86,24 @@ function TemplateTab({ state, partialUpdate }: TemplateTabProps) {
return ( return (
<AnimateFade> <AnimateFade>
<div className='flex border-t divide-x border-x rounded-t-md'> <div className='flex border-t border-x rounded-t-md clr-input'>
<SelectSingle <SelectSingle
noBorder noBorder
placeholder='Источник'
className='w-[12rem]'
options={templateSelector}
value={
state.templateID
? { value: state.templateID, label: templates.find(item => item.id == state.templateID)!.title }
: null
}
onChange={data => partialUpdate({ templateID: data ? data.value : undefined })}
/>
<SelectSingle
noBorder
isSearchable={false}
placeholder='Выберите категорию' placeholder='Выберите категорию'
className='flex-grow border-none' className='flex-grow ml-1 border-none'
options={categorySelector} options={categorySelector}
value={ value={
state.filterCategory && templateSchema state.filterCategory && templateSchema
@ -105,18 +118,6 @@ function TemplateTab({ state, partialUpdate }: TemplateTabProps) {
} }
isClearable isClearable
/> />
<SelectSingle
noBorder
placeholder='Источник'
className='w-[12rem]'
options={templateSelector}
value={
state.templateID
? { value: state.templateID, label: templates.find(item => item.id == state.templateID)!.title }
: null
}
onChange={data => partialUpdate({ templateID: data ? data.value : undefined })}
/>
</div> </div>
<PickConstituenta <PickConstituenta
id='dlg_template_picker' id='dlg_template_picker'

View File

@ -165,14 +165,14 @@ function DlgEditWordForms({ hideWindow, target, onSave }: DlgEditWordFormsProps)
noHover noHover
title='Определить граммемы' title='Определить граммемы'
icon={<IconMoveRight size='1.25rem' className='icon-primary' />} icon={<IconMoveRight size='1.25rem' className='icon-primary' />}
disabled={textProcessor.loading || !inputText} disabled={textProcessor.processing || !inputText}
onClick={handleParse} onClick={handleParse}
/> />
<MiniButton <MiniButton
noHover noHover
title='Генерировать словоформу' title='Генерировать словоформу'
icon={<IconMoveLeft size='1.25rem' className='icon-primary' />} icon={<IconMoveLeft size='1.25rem' className='icon-primary' />}
disabled={textProcessor.loading || inputGrams.length == 0} disabled={textProcessor.processing || inputGrams.length == 0}
onClick={handleInflect} onClick={handleInflect}
/> />
</div> </div>
@ -190,14 +190,14 @@ function DlgEditWordForms({ hideWindow, target, onSave }: DlgEditWordFormsProps)
noHover noHover
title='Внести словоформу' title='Внести словоформу'
icon={<IconAccept size='1.5rem' className='icon-green' />} icon={<IconAccept size='1.5rem' className='icon-green' />}
disabled={textProcessor.loading || !inputText || inputGrams.length == 0} disabled={textProcessor.processing || !inputText || inputGrams.length == 0}
onClick={handleAddForm} onClick={handleAddForm}
/> />
<MiniButton <MiniButton
noHover noHover
title='Генерировать стандартные словоформы' title='Генерировать стандартные словоформы'
icon={<IconMoveDown size='1.5rem' className='icon-primary' />} icon={<IconMoveDown size='1.5rem' className='icon-primary' />}
disabled={textProcessor.loading || !inputText} disabled={textProcessor.processing || !inputText}
onClick={handleGenerateLexeme} onClick={handleGenerateLexeme}
/> />
</div> </div>
@ -210,7 +210,7 @@ function DlgEditWordForms({ hideWindow, target, onSave }: DlgEditWordFormsProps)
title='Сбросить все словоформы' title='Сбросить все словоформы'
className='py-0' className='py-0'
icon={<IconRemove size='1.5rem' className='icon-red' />} icon={<IconRemove size='1.5rem' className='icon-red' />}
disabled={textProcessor.loading || forms.length === 0} disabled={textProcessor.processing || forms.length === 0}
onClick={handleResetAll} onClick={handleResetAll}
/> />
</div> </div>

View File

@ -11,7 +11,7 @@ import { RSErrorType } from '@/models/rslang';
import { PARAMETER } from '@/utils/constants'; import { PARAMETER } from '@/utils/constants';
function useCheckExpression({ schema }: { schema?: IRSForm }) { function useCheckExpression({ schema }: { schema?: IRSForm }) {
const [loading, setLoading] = useState(false); const [processing, setProcessing] = useState(false);
const [error, setError] = useState<ErrorData>(undefined); const [error, setError] = useState<ErrorData>(undefined);
const [parseData, setParseData] = useState<IExpressionParse | undefined>(undefined); const [parseData, setParseData] = useState<IExpressionParse | undefined>(undefined);
@ -22,7 +22,7 @@ function useCheckExpression({ schema }: { schema?: IRSForm }) {
postCheckExpression(String(schema!.id), { postCheckExpression(String(schema!.id), {
data: { expression: expression }, data: { expression: expression },
showError: true, showError: true,
setLoading, setLoading: setProcessing,
onError: setError, onError: setError,
onSuccess: parse => { onSuccess: parse => {
if (activeCst) { if (activeCst) {
@ -34,7 +34,7 @@ function useCheckExpression({ schema }: { schema?: IRSForm }) {
}); });
} }
return { parseData, checkExpression, resetParse, error, setError, loading }; return { parseData, checkExpression, resetParse, error, setError, processing };
} }
export default useCheckExpression; export default useCheckExpression;

View File

@ -7,7 +7,7 @@ import { ErrorData } from '@/components/info/InfoError';
import { ILexemeData, ITextRequest, ITextResult, IWordFormPlain } from '@/models/language'; import { ILexemeData, ITextRequest, ITextResult, IWordFormPlain } from '@/models/language';
function useConceptText() { function useConceptText() {
const [loading, setLoading] = useState(false); const [processing, setProcessing] = useState(false);
const [error, setError] = useState<ErrorData>(undefined); const [error, setError] = useState<ErrorData>(undefined);
const inflect = useCallback((data: IWordFormPlain, onSuccess: DataCallback<ITextResult>) => { const inflect = useCallback((data: IWordFormPlain, onSuccess: DataCallback<ITextResult>) => {
@ -15,7 +15,7 @@ function useConceptText() {
postInflectText({ postInflectText({
data: data, data: data,
showError: true, showError: true,
setLoading, setLoading: setProcessing,
onError: setError, onError: setError,
onSuccess: data => { onSuccess: data => {
if (onSuccess) onSuccess(data); if (onSuccess) onSuccess(data);
@ -28,7 +28,7 @@ function useConceptText() {
postParseText({ postParseText({
data: data, data: data,
showError: true, showError: true,
setLoading, setLoading: setProcessing,
onError: setError, onError: setError,
onSuccess: data => { onSuccess: data => {
if (onSuccess) onSuccess(data); if (onSuccess) onSuccess(data);
@ -41,7 +41,7 @@ function useConceptText() {
postGenerateLexeme({ postGenerateLexeme({
data: data, data: data,
showError: true, showError: true,
setLoading, setLoading: setProcessing,
onError: setError, onError: setError,
onSuccess: data => { onSuccess: data => {
if (onSuccess) onSuccess(data); if (onSuccess) onSuccess(data);
@ -49,7 +49,7 @@ function useConceptText() {
}); });
}, []); }, []);
return { inflect, parse, generateLexeme, error, setError, loading }; return { inflect, parse, generateLexeme, error, setError, processing };
} }
export default useConceptText; export default useConceptText;

View File

@ -9,7 +9,7 @@ import { OssLoader } from '@/models/OssLoader';
function useOssDetails({ target }: { target?: string }) { function useOssDetails({ target }: { target?: string }) {
const [schema, setInner] = useState<IOperationSchema | undefined>(undefined); const [schema, setInner] = useState<IOperationSchema | undefined>(undefined);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(true);
const [error, setError] = useState<ErrorData>(undefined); const [error, setError] = useState<ErrorData>(undefined);
function setSchema(data?: IOperationSchemaData) { function setSchema(data?: IOperationSchemaData) {

View File

@ -9,7 +9,7 @@ import { RSFormLoader } from '@/models/RSFormLoader';
function useRSFormDetails({ target, version }: { target?: string; version?: string }) { function useRSFormDetails({ target, version }: { target?: string; version?: string }) {
const [schema, setInnerSchema] = useState<IRSForm | undefined>(undefined); const [schema, setInnerSchema] = useState<IRSForm | undefined>(undefined);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(true);
const [error, setError] = useState<ErrorData>(undefined); const [error, setError] = useState<ErrorData>(undefined);
function setSchema(data?: IRSFormData) { function setSchema(data?: IRSFormData) {

View File

@ -8,7 +8,7 @@ import { IResolutionData } from '@/models/language';
import { IRSForm } from '@/models/rsform'; import { IRSForm } from '@/models/rsform';
function useResolveText({ schema }: { schema?: IRSForm }) { function useResolveText({ schema }: { schema?: IRSForm }) {
const [loading, setLoading] = useState(false); const [processing, setProcessing] = useState(false);
const [error, setError] = useState<ErrorData>(undefined); const [error, setError] = useState<ErrorData>(undefined);
const [refsData, setRefsData] = useState<IResolutionData | undefined>(undefined); const [refsData, setRefsData] = useState<IResolutionData | undefined>(undefined);
@ -19,7 +19,7 @@ function useResolveText({ schema }: { schema?: IRSForm }) {
postResolveText(String(schema!.id), { postResolveText(String(schema!.id), {
data: { text: text }, data: { text: text },
showError: true, showError: true,
setLoading, setLoading: setProcessing,
onError: setError, onError: setError,
onSuccess: data => { onSuccess: data => {
setRefsData(data); setRefsData(data);
@ -28,7 +28,7 @@ function useResolveText({ schema }: { schema?: IRSForm }) {
}); });
} }
return { refsData, resolveText, resetData, error, setError, loading }; return { refsData, resolveText, resetData, error, setError, processing };
} }
export default useResolveText; export default useResolveText;

View File

@ -74,6 +74,10 @@ function HelpInfo() {
1994 Кучкаров З.А., Ким В.Л. Разработка родоструктурных конструктов для библиотеки моделей и исследование 1994 Кучкаров З.А., Ким В.Л. Разработка родоструктурных конструктов для библиотеки моделей и исследование
возможностей их развития. возможностей их развития.
</li> </li>
<li>
1994 Коваль А.Г., Воробей П.Н. Редактор Программного комплекса Экстеор 1.5,{' '}
<i>упростивший механизм печати экспликаций и улучшивший синтаксический анализ формального выражения.</i>
</li>
<li> <li>
1996 Коваль А.Г., Кучкаров З.А., Костюк А.В., Кононенко А.А., Син Ю.Е., Маклаков Ю.И. Программа 1996 Коваль А.Г., Кучкаров З.А., Костюк А.В., Кононенко А.А., Син Ю.Е., Маклаков Ю.И. Программа
родоструктурного синтеза операционализированных терминальных концептуальных моделей Экстеор 2,{' '} родоструктурного синтеза операционализированных терминальных концептуальных моделей Экстеор 2,{' '}
@ -157,6 +161,10 @@ function HelpInfo() {
2004 Кононенко А.А. Генерация кода на языке программирования C++ по тексту концептуальной схемы, 2004 Кононенко А.А. Генерация кода на языке программирования C++ по тексту концептуальной схемы,
эксплицированной в родах структур. эксплицированной в родах структур.
</li> </li>
<li>
2004 Кононенко А.А., Кучкаров З.А., Никаноров С.П., Никитина Н.К. Технология концептуального проектирования,
&mdash; <i>монография, собравшая исторический обзор и перспективы развития технологического направления.</i>
</li>
<li>2006 Кучкаров З.А., Никаноров С.П. Библиотека моделей.</li> <li>2006 Кучкаров З.А., Никаноров С.П. Библиотека моделей.</li>
<li>2006 Кучкаров З.А., Лавров В.А. Полные системы простых теоретико-множественных операций.</li> <li>2006 Кучкаров З.А., Лавров В.А. Полные системы простых теоретико-множественных операций.</li>
<li> <li>
@ -172,10 +180,6 @@ function HelpInfo() {
<li> <li>
2008 Пономарев И.Н. Об эквивалентной представимости рода структуры с помощью заданной типовой характеристики. 2008 Пономарев И.Н. Об эквивалентной представимости рода структуры с помощью заданной типовой характеристики.
</li> </li>
<li>
2008 Кононенко А.А., Кучкаров З.А., Никаноров С.П., Никитина Н.К. Технология концептуального проектирования,
&mdash; <i>монография, собравшая исторический обзор и перспективы развития технологического направления.</i>
</li>
<li> <li>
2010 Кононенко А.А., Грязнов А.Д. Исследование и построение транслятора концептуальной схемы в концептуальную 2010 Кононенко А.А., Грязнов А.Д. Исследование и построение транслятора концептуальной схемы в концептуальную
модель. модель.

View File

@ -20,7 +20,6 @@ function HelpPortal() {
<LinkTopic text='Конституент' topic={HelpTopic.CC_CONSTITUENTA} />, обладающих уникальными обозначениями и <LinkTopic text='Конституент' topic={HelpTopic.CC_CONSTITUENTA} />, обладающих уникальными обозначениями и
формальными определениями формальными определениями
</p> </p>
<br />
<h2>Разделы Портала</h2> <h2>Разделы Портала</h2>
<li> <li>
@ -35,7 +34,6 @@ function HelpPortal() {
<IconUser2 size='1.25rem' className='inline-icon' /> <TextURL text='Профиль' href={urls.profile} /> данные <IconUser2 size='1.25rem' className='inline-icon' /> <TextURL text='Профиль' href={urls.profile} /> данные
пользователя и смена пароля пользователя и смена пароля
</li> </li>
<br />
<h2>Разделы Справки</h2> <h2>Разделы Справки</h2>
{[ {[
@ -50,7 +48,6 @@ function HelpPortal() {
].map(topic => ( ].map(topic => (
<TopicItem key={`${prefixes.topic_item}${topic}`} topic={topic} /> <TopicItem key={`${prefixes.topic_item}${topic}`} topic={topic} />
))} ))}
<br />
<h2>Лицензирование и раскрытие информации</h2> <h2>Лицензирование и раскрытие информации</h2>
<li>Пользователи Портала сохраняют авторские права на создаваемый ими контент</li> <li>Пользователи Портала сохраняют авторские права на создаваемый ими контент</li>
@ -65,12 +62,15 @@ function HelpPortal() {
Данный сайт использует доменное имя и серверные мощности{' '} Данный сайт использует доменное имя и серверные мощности{' '}
<TextURL text='Центра Концепт' href={external_urls.concept} /> <TextURL text='Центра Концепт' href={external_urls.concept} />
</li> </li>
<br />
<h2>Поддержка</h2> <h2>Поддержка</h2>
<p> <p>
Портал разрабатывается <TextURL text='Центром Концепт' href={external_urls.concept} /> Портал разрабатывается <TextURL text='Центром Концепт' href={external_urls.concept} />
</p> </p>
<p>
Портал поддерживает актуальные версии браузеров Chrome, Firefox, Safari. Убедитесь, что используете последнюю
версию браузера в случае возникновения визуальных ошибок или проблем с производительностью.
</p>
<p> <p>
Ваши пожелания по доработке, найденные ошибки и иные предложения можно направлять по email:{' '} Ваши пожелания по доработке, найденные ошибки и иные предложения можно направлять по email:{' '}
<TextURL href={external_urls.mail_portal} text='portal@acconcept.ru' /> <TextURL href={external_urls.mail_portal} text='portal@acconcept.ru' />

View File

@ -170,7 +170,7 @@ function EditorRSExpression({
<Overlay position='top-[-0.5rem] pl-[8rem] sm:pl-[4rem] right-1/2 translate-x-1/2 flex'> <Overlay position='top-[-0.5rem] pl-[8rem] sm:pl-[4rem] right-1/2 translate-x-1/2 flex'>
<StatusBar <StatusBar
processing={parser.loading} processing={parser.processing}
isModified={isModified} isModified={isModified}
constituenta={activeCst} constituenta={activeCst}
parseData={parser.parseData} parseData={parser.parseData}