Compare commits
5 Commits
760c4cd659
...
4c20d151d7
Author | SHA1 | Date | |
---|---|---|---|
![]() |
4c20d151d7 | ||
![]() |
4383511a4a | ||
![]() |
f3c11747d8 | ||
![]() |
aeaa92df3f | ||
![]() |
e1604bb7f8 |
2
TODO.txt
2
TODO.txt
|
@ -63,12 +63,12 @@ https://yandex.cloud/ru/docs/smartcaptcha
|
||||||
[Research]
|
[Research]
|
||||||
Research and consider integration
|
Research and consider integration
|
||||||
- django-allauth - consider supporting popular auth providers
|
- django-allauth - consider supporting popular auth providers
|
||||||
- drf-messages
|
|
||||||
|
|
||||||
- skeleton loading
|
- skeleton loading
|
||||||
https://react.dev/reference/react/Suspense
|
https://react.dev/reference/react/Suspense
|
||||||
|
|
||||||
- backend error message unification
|
- backend error message unification
|
||||||
|
- drf-messages
|
||||||
https://drf-standardized-errors.readthedocs.io/en/latest/error_response.html
|
https://drf-standardized-errors.readthedocs.io/en/latest/error_response.html
|
||||||
|
|
||||||
- semantic json diff
|
- semantic json diff
|
||||||
|
|
|
@ -8,7 +8,7 @@ drf-spectacular-sidecar==2024.7.1
|
||||||
coreapi==2.3.3
|
coreapi==2.3.3
|
||||||
django-rest-passwordreset==1.4.1
|
django-rest-passwordreset==1.4.1
|
||||||
cctext==0.1.4
|
cctext==0.1.4
|
||||||
pyconcept==0.1.8
|
pyconcept==0.1.10
|
||||||
|
|
||||||
psycopg2-binary==2.9.9
|
psycopg2-binary==2.9.9
|
||||||
gunicorn==23.0.0
|
gunicorn==23.0.0
|
||||||
|
|
|
@ -8,7 +8,7 @@ drf-spectacular-sidecar==2024.7.1
|
||||||
coreapi==2.3.3
|
coreapi==2.3.3
|
||||||
django-rest-passwordreset==1.4.1
|
django-rest-passwordreset==1.4.1
|
||||||
cctext==0.1.4
|
cctext==0.1.4
|
||||||
pyconcept==0.1.8
|
pyconcept==0.1.10
|
||||||
|
|
||||||
psycopg2-binary==2.9.9
|
psycopg2-binary==2.9.9
|
||||||
gunicorn==23.0.0
|
gunicorn==23.0.0
|
|
@ -4,7 +4,7 @@
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"generate": "lezer-generator src/components/RSInput/rslang/rslangFull.grammar -o src/components/RSInput/rslang/parser.ts && lezer-generator src/components/RefsInput/parse/refsText.grammar -o src/components/RefsInput/parse/parser.ts",
|
"generate": "lezer-generator src/components/RSInput/rslang/rslangFast.grammar -o src/components/RSInput/rslang/parser.ts && lezer-generator src/components/RSInput/rslang/rslangAST.grammar -o src/components/RSInput/rslang/parserAST.ts && lezer-generator src/components/RefsInput/parse/refsText.grammar -o src/components/RefsInput/parse/parser.ts",
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"dev": "vite --host",
|
"dev": "vite --host",
|
||||||
"build": "tsc && vite build",
|
"build": "tsc && vite build",
|
||||||
|
|
|
@ -28,6 +28,10 @@ export const Router = createBrowserRouter([
|
||||||
path: '',
|
path: '',
|
||||||
element: <HomePage />
|
element: <HomePage />
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: `${routes.not_found}`,
|
||||||
|
element: <NotFoundPage />
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: routes.login,
|
path: routes.login,
|
||||||
element: <LoginPage />
|
element: <LoginPage />
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { buildConstants } from '@/utils/buildConstants';
|
||||||
* Routes.
|
* Routes.
|
||||||
*/
|
*/
|
||||||
export const routes = {
|
export const routes = {
|
||||||
|
not_found: 'not-found',
|
||||||
login: 'login',
|
login: 'login',
|
||||||
signup: 'signup',
|
signup: 'signup',
|
||||||
profile: 'profile',
|
profile: 'profile',
|
||||||
|
@ -39,6 +40,7 @@ interface OssProps {
|
||||||
* Internal navigation URLs.
|
* Internal navigation URLs.
|
||||||
*/
|
*/
|
||||||
export const urls = {
|
export const urls = {
|
||||||
|
page404: '/not-found',
|
||||||
admin: `${buildConstants.backend}/admin`,
|
admin: `${buildConstants.backend}/admin`,
|
||||||
rest_api: `${buildConstants.backend}/`,
|
rest_api: `${buildConstants.backend}/`,
|
||||||
home: '/',
|
home: '/',
|
||||||
|
|
|
@ -75,7 +75,7 @@ export function SubfoldersIcon({ value, size = '1.25rem', className }: DomIconPr
|
||||||
if (value) {
|
if (value) {
|
||||||
return <IconSubfolders size={size} className={className ?? 'clr-text-green'} />;
|
return <IconSubfolders size={size} className={className ?? 'clr-text-green'} />;
|
||||||
} else {
|
} else {
|
||||||
return <IconSubfolders size={size} className={className ?? 'clr-text-controls'} />;
|
return <IconSubfolders size={size} className={className ?? 'clr-text-primary'} />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ export { LuMoon as IconDarkTheme } from 'react-icons/lu';
|
||||||
export { LuSun as IconLightTheme } from 'react-icons/lu';
|
export { LuSun as IconLightTheme } from 'react-icons/lu';
|
||||||
export { LuFolderTree as IconFolderTree } from 'react-icons/lu';
|
export { LuFolderTree as IconFolderTree } from 'react-icons/lu';
|
||||||
export { LuFolder as IconFolder } from 'react-icons/lu';
|
export { LuFolder as IconFolder } from 'react-icons/lu';
|
||||||
|
export { LuFolderSearch as IconFolderSearch } from 'react-icons/lu';
|
||||||
export { LuFolders as IconSubfolders } from 'react-icons/lu';
|
export { LuFolders as IconSubfolders } from 'react-icons/lu';
|
||||||
export { LuFolderEdit as IconFolderEdit } from 'react-icons/lu';
|
export { LuFolderEdit as IconFolderEdit } from 'react-icons/lu';
|
||||||
export { LuFolderOpen as IconFolderOpened } from 'react-icons/lu';
|
export { LuFolderOpen as IconFolderOpened } from 'react-icons/lu';
|
||||||
|
@ -57,6 +58,7 @@ export { PiFileCsv as IconCSV } from 'react-icons/pi';
|
||||||
export { LuUserCircle2 as IconUser } from 'react-icons/lu';
|
export { LuUserCircle2 as IconUser } from 'react-icons/lu';
|
||||||
export { FaCircleUser as IconUser2 } from 'react-icons/fa6';
|
export { FaCircleUser as IconUser2 } from 'react-icons/fa6';
|
||||||
export { TbUserEdit as IconEditor } from 'react-icons/tb';
|
export { TbUserEdit as IconEditor } from 'react-icons/tb';
|
||||||
|
export { TbUserSearch as IconUserSearch } from 'react-icons/tb';
|
||||||
export { LuCrown as IconOwner } from 'react-icons/lu';
|
export { LuCrown as IconOwner } from 'react-icons/lu';
|
||||||
export { TbMeteor as IconAdmin } from 'react-icons/tb';
|
export { TbMeteor as IconAdmin } from 'react-icons/tb';
|
||||||
export { TbMeteorOff as IconAdminOff } from 'react-icons/tb';
|
export { TbMeteorOff as IconAdminOff } from 'react-icons/tb';
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
// This file was generated by lezer-generator. You probably shouldn't edit it.
|
||||||
|
export const
|
||||||
|
Expression = 1,
|
||||||
|
Logic = 2,
|
||||||
|
Logic_predicates = 3,
|
||||||
|
Variable = 4,
|
||||||
|
Local = 5,
|
||||||
|
Tuple = 8,
|
||||||
|
Setexpr_enum_min2 = 9,
|
||||||
|
Setexpr_enum = 10,
|
||||||
|
Setexpr = 11,
|
||||||
|
Literal = 12,
|
||||||
|
Integer = 13,
|
||||||
|
EmptySet = 14,
|
||||||
|
IntegerSet = 15,
|
||||||
|
Global = 16,
|
||||||
|
Radical = 17,
|
||||||
|
Setexpr_binary = 18,
|
||||||
|
Setexpr_generators = 27,
|
||||||
|
Enumeration = 30,
|
||||||
|
Boolean = 31,
|
||||||
|
Filter_expression = 33,
|
||||||
|
Filter = 34,
|
||||||
|
Declarative = 37,
|
||||||
|
PrefixD = 40,
|
||||||
|
PrefixI = 41,
|
||||||
|
Imperative = 42,
|
||||||
|
Imp_blocks = 43,
|
||||||
|
PrefixR = 45,
|
||||||
|
Recursion = 46,
|
||||||
|
Function = 48,
|
||||||
|
TextFunction = 49,
|
||||||
|
BigPr = 50,
|
||||||
|
SmallPr = 51,
|
||||||
|
Card = 52,
|
||||||
|
Bool = 53,
|
||||||
|
Debool = 54,
|
||||||
|
Red = 55,
|
||||||
|
Logic_unary = 68,
|
||||||
|
Predicate = 71,
|
||||||
|
Logic_quantor = 72,
|
||||||
|
Variable_pack = 74,
|
||||||
|
Logic_binary = 76,
|
||||||
|
Function_decl = 81,
|
||||||
|
Arguments = 82,
|
||||||
|
Declaration = 83
|
|
@ -0,0 +1,20 @@
|
||||||
|
// This file was generated by lezer-generator. You probably shouldn't edit it.
|
||||||
|
import {LRParser} from "@lezer/lr"
|
||||||
|
export const parser = LRParser.deserialize({
|
||||||
|
version: 14,
|
||||||
|
states: "2xO!sQPOOOOQO'#Ch'#ChO#lQPO'#EWOOQO'#EW'#EWO%yQPO'#EVOVQPO'#CnO'_QPO'#CzO'fQPO'#C{O'nQPO'#C}O'sQPO'#DRO'xQPO'#DWO'}QPO'#D[OOQO'#Cw'#CwO(SQPO'#CwOOQO'#D_'#D_OOQO'#Cg'#CgO)pQPO'#CgO)uQPO'#CgO)zQPO'#C_OVQPO'#DsO*SQPO'#DvOOQO'#Dr'#DrO*[QPO'#DrO*aQPO'#EVOOQO'#C^'#C^O*rQPO'#EPQOQPOOO*wQPO,59YO*wQPO,59YO*wQPO,59YO*wQPO,59YO*wQPO,59YO*wQPO,59YO*wQPO,59YO*wQPO,59YO*wQPO,58yO+OQPO'#CfO+VQPO,59YO,jQPO,59OO,rQPO'#CeO,wQPO,58xO-YQPO,59mO-{QPO'#CfO*wQPO'#CnO.YQPO,59fOOQO'#Cf'#CfO*wQPO,59gOOQO,59g,59gO*wQPO,59iO*SQPO,59mO*wQPO,59rO*SQPO,59vO*wQPO,59RO*wQPO,59RO$lQPO'#C_OOQO,5:_,5:_O*wQPO'#CdOOQO'#C`'#C`OOQO'#Dx'#DxO.bQPO,5:bO*wQPO,5:^OVQPO,5:fOVQPO,5:fOVQPO,5:fOVQPO,5:fO.jQPO'#EROOQO'#EQ'#EQO.oQPO,5:kOOQO1G.t1G.tO2`QPO1G.tO2gQPO1G.tO6VQPO1G.tO9uQPO1G.tO9|QPO1G.tO:TQPO1G.tO:[QPO1G.tO=vQPO1G.eOOQO1G.j1G.jO*wQPO,59POOQO1G.d1G.dO*wQPO1G/XOOQO1G/Q1G/QO>gQPO1G/RO>nQPO1G/TO>vQPO1G/XO>{QPO1G/^O?SQPO1G/bO?XQPO1G.mO?aQPO1G.mO*SQPO,5:dO*wQPO1G/|O?hQPO1G/xOOQO1G0Q1G0QO@[QPO1G0QO@cQPO1G0QO@jQPO1G0QO*wQPO,5:mO*rQPO,5:lOVQPO1G0VOAXQPO1G.kOAiQPO7+$sOOQO7+$m7+$mOApQPO7+$oO*wQPO7+$sOVQPO7+$xO*wQPO7+$|OOQO7+$X7+$XOOQO1G0O1G0OOAuQPO7+%hOOQO7+%d7+%dOBcQPO1G0XOOQO1G0W1G0WOOQO7+%q7+%qOVQPO<<H_O*wQPO<<HZOBmQPO<<H_OBtQPO'#DXOCYQPO<<HdOCbQPO<<HhOCiQPO<<ISODWQPOAN=yODiQPOAN=uOVQPOAN=yOVQPO,59sOOQOAN>OAN>OOVQPOAN>SOOQOG23eG23eOOQOG23aG23aODpQPOG23eOERQPO1G/_OEgQPOG23nOEnQPOG23nOOQOLD)PLD)POOQOLD)YLD)YO*wQPOLD)YOFPQPO!$'LtOOQO!)9B`!)9B`",
|
||||||
|
stateData: "Fi~O!xOS~OTQOVTO]PO^PO_PO`ROaROmUOpVOrWOxXOyYO}ZO!Q`O!S^O!T^O!U^O!V^O!W^O!X^O!hcO!ifO!kdO!mdO~OsiO~PVOc!zXd!zXe!zXf!zXg!zXh!zXi!zXj!zX!Y!zXl!zX~Ov!zX!PSX!ZSX![!zX!]!zX!^!zX!_!zX!`!zX!a!zX!b!zX!c!zX!d!zX!e!zX!v!zX~P!zOckOdlOemOfnOgoOhpOiqOjrOvsO![sO!]sO!^sO!_sO!`sO!asO!bsO!csO!dsO!esO~O!v!yX~P$lOV{O]PO^PO_PO`ROaROmUOpVOrWOxXOyYO}ZO!Q`O!S^O!T^O!U^O!V^O!W^O!X^O~OTyO~P&QOV!OOpVO~Os!QO~Om!RO~Om!SO~Om!TO~OckXdkXekXfkXgkXhkXikXjkXvkX!PSX!ZSX![kX!]kX!^kX!_kX!`kX!akX!bkX!ckX!dkX!ekX!vkX!YkXlkX~Os!UO~OV!VO~O!PsO!ZsO~OT!ZOV!YO~Os!^O~O!o!_O!p!`O!q!aO!r!bO!v!yX~OT!cO~OTRO~P&QO!YYX~P$lOU!fOcZXdZXeZXfZXgZXhZXiZXjZXvZX!YZX![ZX!]ZX!^ZX!_ZX!`ZX!aZX!bZX!cZX!dZX!eZX~OU!oO!YYX~O!Y!pO~OU!qO!o!_O!p!`O!q!aO!r!bO~Ov!rO~P!zOckOdlOemOfnOgoOhpOiqOjrO~OlYX!YYXtYX~P-aOl!sO!Y!pO~Ov!|O!Y!{O~Ov#SO~Ot#UO!Y#TO~OckOebifbigbihbiibijbivbi![bi!]bi!^bi!_bi!`bi!abi!bbi!cbi!dbi!ebi!vbiUbi!Ybilbi!obi!pbi!qbi!rbitbiwbiTbiVbi]bi^bi_bi`biabimbipbirbixbiybi}bi!Qbi!Sbi!Tbi!Ubi!Vbi!Wbi!Xbi!hbi!ibi!kbi!mbi|bi~Odbi~P.wOdlO~P.wOckOdlOemOjrOgbihbiibivbi![bi!]bi!^bi!_bi!`bi!abi!bbi!cbi!dbi!ebi!vbiUbi!Ybilbi!obi!pbi!qbi!rbitbiwbiTbiVbi]bi^bi_bi`biabimbipbirbixbiybi}bi!Qbi!Sbi!Tbi!Ubi!Vbi!Wbi!Xbi!hbi!ibi!kbi!mbi|bi~Ofbi~P2nOckOdlOemOfnOiqOjrOhbivbi![bi!]bi!^bi!_bi!`bi!abi!bbi!cbi!dbi!ebi!vbiUbi!Ybilbi!obi!pbi!qbi!rbitbiwbiTbiVbi]bi^bi_bi`biabimbipbirbixbiybi}bi!Qbi!Sbi!Tbi!Ubi!Vbi!Wbi!Xbi!hbi!ibi!kbi!mbi|bi~Ogbi~P6^OgoO~P6^OfnO~P2nOckOdlOemOfbigbihbiibijbivbi![bi!]bi!^bi!_bi!`bi!abi!bbi!cbi!dbi!ebi!vbiUbi!Ybilbi!obi!pbi!qbi!rbitbiwbiTbiVbi]bi^bi_bi`biabimbipbirbixbiybi}bi!Qbi!Sbi!Tbi!Ubi!Vbi!Wbi!Xbi!hbi!ibi!kbi!mbi|bi~O!oRi!pRi!qRi!rRi!vRiURilRi|RiwRi~P-aOU#XO~P-aOt#YO!Y!pO~Ov#ZO~Ow#[O~P-aO!P#]O~Ot#^O!Y!pO~OU#^O~P-aOt#aO!Y!pO~O!o!_O!q!ni!r!ni!v!niU!nil!ni|!niw!ni~O!p!ni~P?pO!p!`O~P?pO!o!_O!p!`O!q!aO!r!ni!v!niU!nil!ni|!niw!ni~OUXi!YXilXitXi~P-aOw#eO~P-aOV#fO~OckOdlOemOfnOgoOhpOiqOjrO~PVOt!ui!Y!ui~P-aOw#nO~P-aO!o!_O!p!`O!q!aO!r!bOl{X|{X~Ol#pO|#oO~Ow#qO~P-aO!o!_O!p!`O!q!aO!r!bO!v!jyU!jyl!jy|!jyw!jy~Ol#rO!o!_O!p!`O!q!aO!r!bO~OU#sO~P-aOl#xO!o!_O!p!`O!q!aO!r!bO~O!o!_O!p!`O!q!aO!r!bOl{i|{i~Ol#yO~P$lOw#zO!o!_O!p!`O!q!aO!r!bO~Ol#|O~P-aOr!S!i!Q`a!U!V!W!X!TT}yxy~",
|
||||||
|
goto: "-}!{PP!|#v$WPPP$t%x&T&f(dPPPPP)`PPPPPPPP(dPP*^+YP*^PPP*^PPPP*^,XPP*^PP,[PPPPPPPPPPPPPPPPPP#v-WPP-WP-hP#vPPPP-k-n-qPPP-w(dSgO#UQxTQ!XcQ#O!_Q#P!`Q#Q!aQ#R!bQ#h#[Q#k#`Q#l#eQ#t#nQ#u#oR#w#qmhOTc!_!`!a!b#U#[#`#e#n#o#qlbOTc!_!`!a!b#U#[#`#e#n#o#qQ![dQ!v!RQ!x!TR#_!{!U[Uklmnopqrs{!O!Q!S!U!V!Y!^!p!r!|#S#Z#]#f#zl]OTc!_!`!a!b#U#[#`#e#n#o#qX!Zd!R!T!{UvT{!YX}U!Q!U!^UwT{!YQ|UQ!u!QQ!y!UR!}!^SSO#UQtT[zU{!Q!U!Y!^d!Wc!_!`!a!b#[#`#e#n#oQ!fkQ!glQ!hmQ!inQ!joQ!kpQ!lqQ!mrQ!nsQ!t!OQ!w!SQ!z!VQ#V!pQ#W!rQ#`!|Q#b#SQ#g#ZQ#j#]Q#m#fQ#v#qR#{#z!s_OTUcklmnopqrs{!O!Q!S!U!V!Y!^!_!`!a!b!p!r!|#S#U#Z#[#]#`#e#f#n#o#q#z!n_OUcklmnopqrs!O!Q!S!U!V!Y!^!_!`!a!b!p!r!|#S#U#Z#[#]#`#e#f#n#o#q#zTuT{!s[OTUcklmnopqrs{!O!Q!S!U!V!Y!^!_!`!a!b!p!r!|#S#U#Z#[#]#`#e#f#n#o#q#z!r[OTUcklmnopqrs{!O!Q!S!U!V!Y!^!_!`!a!b!p!r!|#S#U#Z#[#]#`#e#f#n#o#q#zR!PVR#i#[!saOTUcklmnopqrs{!O!Q!S!U!V!Y!^!_!`!a!b!p!r!|#S#U#Z#[#]#`#e#f#n#o#q#zmeOTc!_!`!a!b#U#[#`#e#n#o#qR!]dRjOR!eiQ!diR#c#TQjOR#d#U",
|
||||||
|
nodeNames: "⚠ Expression Logic Logic_predicates Variable Local ) ( Tuple Setexpr_enum_min2 Setexpr_enum Setexpr Literal Integer EmptySet IntegerSet Global Radical Setexpr_binary + - * ∪ \\ ∆ ∩ × Setexpr_generators } { Enumeration Boolean ℬ Filter_expression Filter [ ] Declarative ∈ | PrefixD PrefixI Imperative Imp_blocks ; PrefixR Recursion := Function TextFunction BigPr SmallPr Card Bool Debool Red , :∈ ∉ ⊆ ⊄ ⊂ > ≥ < ≤ ≠ = Logic_unary Negation ¬ Predicate Logic_quantor ∀ Variable_pack ∃ Logic_binary ⇔ ⇒ ∨ & Function_decl Arguments Declaration",
|
||||||
|
maxTerm: 88,
|
||||||
|
nodeProps: [
|
||||||
|
["openedBy", 6,"(",28,"{"],
|
||||||
|
["closedBy", 7,")",29,"}"]
|
||||||
|
],
|
||||||
|
skippedNodes: [0],
|
||||||
|
repeatNodeCount: 0,
|
||||||
|
tokenData: "6g~R!iX^%ppq%pvw&exy&jyz&oz{&t{|&y|}'O}!O'T!Q!['Y![!]'b!]!^'u!^!_'z!_!`(P!`!a(U!c!d(Z!e!f(Z!f!g(i!h!i(q!k!l)e!r!s)j!t!u*^!u!v(Z!v!w(Z!z!{(Z!|!}*n!}#O*s#O#P*x#P#Q*}#R#S+S#T#U+S#U#V+j#V#W-Y#W#X.u#X#d+S#d#e1_#e#f+S#f#g2t#g#o+S#o#p4O#p#q4T#q#r4Y#y#z%p$f$g%p$r$s4_%o%p4d5i6S+S#BY#BZ%p$IS$I_%p$I|$JO%p$JT$JU%p$KV$KW%p% l% m4i%%Y%%Z4n%%[%%]4s%&Y%&Z4x%&]%&^4}%&_%&`5S%&`%&a5X%&b%&c5^%&c%&d5c%'S%'T5h%'T%'U5m%'U%'V5r%(^%(_5w%(b%(c5|%(c%(d6R%)Q%)R6W%)S%)T6]%)U%)V6b&FU&FV%p~%uY!x~X^%ppq%p#y#z%p$f$g%p#BY#BZ%p$IS$I_%p$I|$JO%p$JT$JU%p$KV$KW%p&FU&FV%p~&jO!r~~&oOV~~&tOU~~&yOe~~'OOc~~'TO!Y~~'YOd~~'_P]~!Q!['Y~'eQ!_!`'k%&b%&c'p~'pO!P~~'uO!Z~~'zO|~~(PO!b~~(UO!e~~(ZO!`~~(^P!Q![(a~(fP`~!Q![(a~(nPx~!Q![(a~(tQ!Q![(z#]#^)S~)PP!Q~!Q![(z~)VP!R![)Y~)_Qr~|})S!Q![)Y~)jOy~~)mQ!Q![)s#f#g){~)xP!i~!Q![)s~*OP!R![*R~*WQ!S~|}){!Q![*R~*cP}~!Q![*f~*kPa~!Q![*f~*sO_~~*xOs~~*}Og~~+SOt~~+XRT~!Q![+b#T#o+S5i6S+S~+gPT~!Q![+b~+oTT~!Q![+b#T#c+S#c#d,O#d#o+S5i6S+S~,TTT~!Q![+b#T#c+S#c#d,d#d#o+S5i6S+S~,iTT~!Q![+b#T#`+S#`#a,x#a#o+S5i6S+S~-PR!V~T~!Q![+b#T#o+S5i6S+S~-_ST~!Q![+b#T#U-k#U#o+S5i6S+S~-pTT~!Q![+b#T#f+S#f#g.P#g#o+S5i6S+S~.UTT~!Q![+b#T#W+S#W#X.e#X#o+S5i6S+S~.lR!U~T~!Q![+b#T#o+S5i6S+S~.zTT~!Q![+b#T#X+S#X#Y/Z#Y#o+S5i6S+S~/`TT~!Q![+b#T#U+S#U#V/o#V#o+S5i6S+S~/tTT~!Q![+b#T#c+S#c#d0T#d#o+S5i6S+S~0YTT~!Q![+b#T#c+S#c#d0i#d#o+S5i6S+S~0nTT~!Q![+b#T#`+S#`#a0}#a#o+S5i6S+S~1UR!W~T~!Q![+b#T#o+S5i6S+S~1dTT~!Q![+b#T#f+S#f#g1s#g#o+S5i6S+S~1xST~!Q!R+b!R![2U#T#o+S5i6S+S~2]Q!T~T~|}2c!Q![2U~2fP!R![2i~2nQ!T~|}2c!Q![2i~2yTT~!Q![+b#T#X+S#X#Y3Y#Y#o+S5i6S+S~3_TT~!Q![+b#T#W+S#W#X3n#X#o+S5i6S+S~3uR!X~T~!Q![+b#T#o+S5i6S+S~4TOm~~4YOw~~4_Ol~~4dO!h~~4iOj~~4nOp~~4sO!p~~4xO!o~~4}O!k~~5SO!m~~5XO^~~5^Oh~~5cOv~~5hO![~~5mO!q~~5rOi~~5wOf~~5|O!d~~6RO!c~~6WO!a~~6]O!_~~6bO!^~~6gO!]~",
|
||||||
|
tokenizers: [0],
|
||||||
|
topRules: {"Expression":[0,1]},
|
||||||
|
tokenPrec: 1710
|
||||||
|
})
|
|
@ -0,0 +1,247 @@
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
// ------------- Generator Definitions --------------------
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
@detectDelim
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
// ------------- Precedence Definitions --------------------
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
@precedence {
|
||||||
|
plus @left minus @left,
|
||||||
|
times @left,
|
||||||
|
not @right,
|
||||||
|
log_equiv @left,
|
||||||
|
log_impl @left,
|
||||||
|
log_or @left,
|
||||||
|
log_and @left,
|
||||||
|
set_decart @left set_union @left set_intersect @left set_minus @left set_symminus @left,
|
||||||
|
set_bool @right,
|
||||||
|
quant @right
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
// ------------- Terminal Tokens --------------------------
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
@tokens {
|
||||||
|
space { @whitespace+ }
|
||||||
|
Integer { $[0-9]+ }
|
||||||
|
EmptySet { "∅" }
|
||||||
|
IntegerSet { "Z" }
|
||||||
|
|
||||||
|
BigPr { "Pr"$[1-9]$[0-9]*(","$[1-9]$[0-9]*)* }
|
||||||
|
SmallPr { "pr"$[1-9]$[0-9]*(","$[1-9]$[0-9]*)* }
|
||||||
|
Filter { "Fi"$[1-9]$[0-9]*(","$[1-9]$[0-9]*)* }
|
||||||
|
Card { "card" }
|
||||||
|
Bool { "bool" }
|
||||||
|
Debool { "debool" }
|
||||||
|
Red { "red" }
|
||||||
|
|
||||||
|
Global { $[XCSDAT]$[0-9]+ }
|
||||||
|
Function { "F"$[0-9]+ }
|
||||||
|
Predicate { "P"$[0-9]+ }
|
||||||
|
Radical { "R"$[0-9]+ }
|
||||||
|
Local { $[_a-zα-ω]($[a-zα-ω])*$[0-9]* }
|
||||||
|
PrefixR { "R" }
|
||||||
|
PrefixI { "I" }
|
||||||
|
PrefixD { "D" }
|
||||||
|
|
||||||
|
"¬"
|
||||||
|
"∀" "∃" "⇔" "⇒" "∨" "&"
|
||||||
|
"ℬ"
|
||||||
|
"+" "-" "*" "∪" "\\" "∆" "∩" "×"
|
||||||
|
"∈" "∉" "⊆" "⊄" "⊂" ">" "≥" "≤" "<" "≠" "="
|
||||||
|
":∈" ":="
|
||||||
|
|
||||||
|
"," ";" "|"
|
||||||
|
"[" "]"
|
||||||
|
"{" "}"
|
||||||
|
"(" ")"
|
||||||
|
|
||||||
|
@precedence {
|
||||||
|
Filter
|
||||||
|
BigPr
|
||||||
|
Predicate
|
||||||
|
Function
|
||||||
|
Global
|
||||||
|
Radical
|
||||||
|
PrefixR
|
||||||
|
PrefixI
|
||||||
|
PrefixD
|
||||||
|
}
|
||||||
|
@precedence {
|
||||||
|
Card
|
||||||
|
Bool
|
||||||
|
Debool
|
||||||
|
Red
|
||||||
|
SmallPr
|
||||||
|
Local
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@skip { space }
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// ------------------------- Grammar Rules ------------------------------------
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// ------------------------- Language Expression ------------------------------
|
||||||
|
@top Expression {
|
||||||
|
logic_or_setexpr |
|
||||||
|
Function_decl
|
||||||
|
}
|
||||||
|
logic_or_setexpr {
|
||||||
|
Logic |
|
||||||
|
Setexpr
|
||||||
|
}
|
||||||
|
Function_decl {
|
||||||
|
"[" Arguments "]" logic_or_setexpr
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------- Variables and arguments -------------------------
|
||||||
|
Arguments {
|
||||||
|
Declaration |
|
||||||
|
Arguments "," Declaration
|
||||||
|
}
|
||||||
|
Declaration {
|
||||||
|
Local "∈" Setexpr
|
||||||
|
}
|
||||||
|
Variable {
|
||||||
|
Local |
|
||||||
|
Tuple
|
||||||
|
}
|
||||||
|
Variable_pack {
|
||||||
|
Variable |
|
||||||
|
Variable_pack "," Variable
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------- Logic Expressions --------------------------------
|
||||||
|
Logic {
|
||||||
|
Logic_predicates |
|
||||||
|
Logic_unary |
|
||||||
|
Logic_binary |
|
||||||
|
"(" Logic ")"
|
||||||
|
}
|
||||||
|
|
||||||
|
Logic_predicates {
|
||||||
|
Variable ":∈" Setexpr |
|
||||||
|
Variable ":=" Setexpr |
|
||||||
|
Setexpr "∈" Setexpr |
|
||||||
|
Setexpr "∉" Setexpr |
|
||||||
|
Setexpr "⊆" Setexpr |
|
||||||
|
Setexpr "⊄" Setexpr |
|
||||||
|
Setexpr "⊂" Setexpr |
|
||||||
|
Setexpr ">" Setexpr |
|
||||||
|
Setexpr "≥" Setexpr |
|
||||||
|
Setexpr "<" Setexpr |
|
||||||
|
Setexpr "≤" Setexpr |
|
||||||
|
Setexpr "≠" Setexpr |
|
||||||
|
Setexpr "=" Setexpr
|
||||||
|
}
|
||||||
|
|
||||||
|
Logic_unary {
|
||||||
|
Negation { !not "¬" Logic } |
|
||||||
|
Predicate "[" Setexpr_enum "]" |
|
||||||
|
Logic_quantor
|
||||||
|
}
|
||||||
|
|
||||||
|
Logic_quantor {
|
||||||
|
"∀" Variable_pack "∈" Setexpr !quant Logic |
|
||||||
|
"∃" Variable_pack "∈" Setexpr !quant Logic
|
||||||
|
}
|
||||||
|
|
||||||
|
Logic_binary {
|
||||||
|
Logic !log_equiv "⇔" Logic |
|
||||||
|
Logic !log_impl "⇒" Logic |
|
||||||
|
Logic !log_or "∨" Logic |
|
||||||
|
Logic !log_and "&" Logic
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------- Set Expressions ----------------------------------
|
||||||
|
Setexpr {
|
||||||
|
Literal |
|
||||||
|
identifier |
|
||||||
|
Setexpr_binary |
|
||||||
|
Setexpr_generators |
|
||||||
|
Function "[" Setexpr_enum "]" |
|
||||||
|
TextFunction "(" Setexpr ")"
|
||||||
|
}
|
||||||
|
TextFunction {
|
||||||
|
BigPr |
|
||||||
|
SmallPr |
|
||||||
|
Card |
|
||||||
|
Bool |
|
||||||
|
Debool |
|
||||||
|
Red
|
||||||
|
}
|
||||||
|
Setexpr_enum {
|
||||||
|
Setexpr |
|
||||||
|
Setexpr_enum_min2
|
||||||
|
}
|
||||||
|
Setexpr_enum_min2 {
|
||||||
|
Setexpr_enum "," Setexpr
|
||||||
|
}
|
||||||
|
|
||||||
|
Literal {
|
||||||
|
Integer |
|
||||||
|
EmptySet |
|
||||||
|
IntegerSet
|
||||||
|
}
|
||||||
|
identifier {
|
||||||
|
Local |
|
||||||
|
Global |
|
||||||
|
Radical
|
||||||
|
}
|
||||||
|
|
||||||
|
Setexpr_binary {
|
||||||
|
Setexpr !plus "+" Setexpr |
|
||||||
|
Setexpr !minus "-" Setexpr |
|
||||||
|
Setexpr !times "*" Setexpr |
|
||||||
|
Setexpr !set_union "∪" Setexpr |
|
||||||
|
Setexpr !set_minus "\\" Setexpr |
|
||||||
|
Setexpr !set_symminus "∆" Setexpr |
|
||||||
|
Setexpr !set_intersect "∩" Setexpr |
|
||||||
|
Setexpr !set_decart "×" Setexpr |
|
||||||
|
"(" Setexpr_binary ")"
|
||||||
|
}
|
||||||
|
|
||||||
|
Setexpr_generators {
|
||||||
|
Enumeration |
|
||||||
|
Tuple |
|
||||||
|
Boolean |
|
||||||
|
Filter_expression |
|
||||||
|
Declarative |
|
||||||
|
Imperative |
|
||||||
|
Recursion
|
||||||
|
}
|
||||||
|
Enumeration {
|
||||||
|
"{" Setexpr_enum "}"
|
||||||
|
}
|
||||||
|
Tuple {
|
||||||
|
"(" Setexpr_enum_min2 ")"
|
||||||
|
}
|
||||||
|
Boolean {
|
||||||
|
!set_bool "ℬ" "(" Setexpr ")" |
|
||||||
|
!set_bool "ℬ" Boolean
|
||||||
|
}
|
||||||
|
Filter_expression {
|
||||||
|
Filter "[" Setexpr_enum "]" "(" Setexpr ")"
|
||||||
|
}
|
||||||
|
|
||||||
|
Declarative {
|
||||||
|
"{" Local "∈" Setexpr "|" Logic "}" |
|
||||||
|
PrefixD "{" Variable "∈" Setexpr "|" Logic "}"
|
||||||
|
}
|
||||||
|
Recursion {
|
||||||
|
PrefixR "{" Variable ":=" Setexpr ("|" Logic)? "|" Setexpr "}"
|
||||||
|
}
|
||||||
|
Imperative {
|
||||||
|
PrefixI "{" Setexpr "|" Imp_blocks "}"
|
||||||
|
}
|
||||||
|
Imp_blocks {
|
||||||
|
Logic |
|
||||||
|
Imp_blocks ";" Logic
|
||||||
|
}
|
|
@ -27,7 +27,7 @@ function DlgShowAST({ hideWindow, syntaxTree, expression }: DlgShowASTProps) {
|
||||||
const nodes: GraphNode[] = useMemo(
|
const nodes: GraphNode[] = useMemo(
|
||||||
() =>
|
() =>
|
||||||
syntaxTree.map(node => ({
|
syntaxTree.map(node => ({
|
||||||
id: String(node.uid),
|
id: String(syntaxTree.length - node.uid), // invert order of IDs to force correct ordering in graph layout
|
||||||
label: labelSyntaxTree(node),
|
label: labelSyntaxTree(node),
|
||||||
fill: colorBgSyntaxTree(node, colors)
|
fill: colorBgSyntaxTree(node, colors)
|
||||||
})),
|
})),
|
||||||
|
@ -40,15 +40,15 @@ function DlgShowAST({ hideWindow, syntaxTree, expression }: DlgShowASTProps) {
|
||||||
if (node.parent !== node.uid) {
|
if (node.parent !== node.uid) {
|
||||||
result.push({
|
result.push({
|
||||||
id: String(node.uid),
|
id: String(node.uid),
|
||||||
source: String(node.parent),
|
source: String(syntaxTree.length - node.parent),
|
||||||
target: String(node.uid)
|
target: String(syntaxTree.length - node.uid)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
}, [syntaxTree]);
|
}, [syntaxTree]);
|
||||||
|
|
||||||
const handleHoverIn = useCallback((node: GraphNode) => setHoverID(Number(node.id)), []);
|
const handleHoverIn = useCallback((node: GraphNode) => setHoverID(syntaxTree.length - Number(node.id)), [syntaxTree]);
|
||||||
|
|
||||||
const handleHoverOut = useCallback(() => setHoverID(undefined), []);
|
const handleHoverOut = useCallback(() => setHoverID(undefined), []);
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { Node } from 'reactflow';
|
||||||
|
|
||||||
import { LibraryItemType, LocationHead } from './library';
|
import { LibraryItemType, LocationHead } from './library';
|
||||||
import { IOperation } from './oss';
|
import { IOperation } from './oss';
|
||||||
|
import { UserID } from './user';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents graph dependency mode.
|
* Represents graph dependency mode.
|
||||||
|
@ -182,6 +183,7 @@ export interface ILibraryFilter {
|
||||||
isVisible?: boolean;
|
isVisible?: boolean;
|
||||||
isOwned?: boolean;
|
isOwned?: boolean;
|
||||||
isEditor?: boolean;
|
isEditor?: boolean;
|
||||||
|
filterUser?: UserID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -232,6 +232,7 @@ export enum RSErrorType {
|
||||||
invalidBinding = 34836,
|
invalidBinding = 34836,
|
||||||
localOutOfScope = 34837,
|
localOutOfScope = 34837,
|
||||||
invalidElementPredicate = 34838,
|
invalidElementPredicate = 34838,
|
||||||
|
invalidEmptySetUsage = 34839,
|
||||||
invalidArgsArity = 34840,
|
invalidArgsArity = 34840,
|
||||||
invalidArgumentType = 34841,
|
invalidArgumentType = 34841,
|
||||||
globalStructure = 34844,
|
globalStructure = 34844,
|
||||||
|
|
|
@ -16,6 +16,7 @@ import DlgChangeLocation from '@/dialogs/DlgChangeLocation';
|
||||||
import useLocalStorage from '@/hooks/useLocalStorage';
|
import useLocalStorage from '@/hooks/useLocalStorage';
|
||||||
import { ILibraryItem, IRenameLocationData, LocationHead } from '@/models/library';
|
import { ILibraryItem, IRenameLocationData, LocationHead } from '@/models/library';
|
||||||
import { ILibraryFilter } from '@/models/miscellaneous';
|
import { ILibraryFilter } from '@/models/miscellaneous';
|
||||||
|
import { UserID } from '@/models/user';
|
||||||
import { storage } from '@/utils/constants';
|
import { storage } from '@/utils/constants';
|
||||||
import { information } from '@/utils/labels';
|
import { information } from '@/utils/labels';
|
||||||
import { convertToCSV, toggleTristateFlag } from '@/utils/utils';
|
import { convertToCSV, toggleTristateFlag } from '@/utils/utils';
|
||||||
|
@ -36,8 +37,9 @@ function LibraryPage() {
|
||||||
const [head, setHead] = useLocalStorage<LocationHead | undefined>(storage.librarySearchHead, undefined);
|
const [head, setHead] = useLocalStorage<LocationHead | undefined>(storage.librarySearchHead, undefined);
|
||||||
const [subfolders, setSubfolders] = useLocalStorage<boolean>(storage.librarySearchSubfolders, false);
|
const [subfolders, setSubfolders] = useLocalStorage<boolean>(storage.librarySearchSubfolders, false);
|
||||||
const [isVisible, setIsVisible] = useLocalStorage<boolean | undefined>(storage.librarySearchVisible, true);
|
const [isVisible, setIsVisible] = useLocalStorage<boolean | undefined>(storage.librarySearchVisible, true);
|
||||||
const [isOwned, setIsOwned] = useLocalStorage<boolean | undefined>(storage.librarySearchEditor, undefined);
|
const [isOwned, setIsOwned] = useLocalStorage<boolean | undefined>(storage.librarySearchOwned, undefined);
|
||||||
const [isEditor, setIsEditor] = useLocalStorage<boolean | undefined>(storage.librarySearchEditor, undefined);
|
const [isEditor, setIsEditor] = useLocalStorage<boolean | undefined>(storage.librarySearchEditor, undefined);
|
||||||
|
const [filterUser, setFilterUser] = useLocalStorage<UserID | undefined>(storage.librarySearchUser, undefined);
|
||||||
const [showRenameLocation, setShowRenameLocation] = useState(false);
|
const [showRenameLocation, setShowRenameLocation] = useState(false);
|
||||||
|
|
||||||
const filter: ILibraryFilter = useMemo(
|
const filter: ILibraryFilter = useMemo(
|
||||||
|
@ -50,9 +52,22 @@ function LibraryPage() {
|
||||||
isVisible: user ? isVisible : true,
|
isVisible: user ? isVisible : true,
|
||||||
folderMode: options.folderMode,
|
folderMode: options.folderMode,
|
||||||
subfolders: subfolders,
|
subfolders: subfolders,
|
||||||
location: options.location
|
location: options.location,
|
||||||
|
filterUser: filterUser
|
||||||
}),
|
}),
|
||||||
[head, path, query, isEditor, isOwned, isVisible, user, options.folderMode, options.location, subfolders]
|
[
|
||||||
|
head,
|
||||||
|
path,
|
||||||
|
query,
|
||||||
|
isEditor,
|
||||||
|
isOwned,
|
||||||
|
isVisible,
|
||||||
|
user,
|
||||||
|
options.folderMode,
|
||||||
|
options.location,
|
||||||
|
subfolders,
|
||||||
|
filterUser
|
||||||
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
const hasCustomFilter = useMemo(
|
const hasCustomFilter = useMemo(
|
||||||
|
@ -63,6 +78,7 @@ function LibraryPage() {
|
||||||
filter.isEditor !== undefined ||
|
filter.isEditor !== undefined ||
|
||||||
filter.isOwned !== undefined ||
|
filter.isOwned !== undefined ||
|
||||||
filter.isVisible !== true ||
|
filter.isVisible !== true ||
|
||||||
|
filter.filterUser !== undefined ||
|
||||||
!!filter.location,
|
!!filter.location,
|
||||||
[filter]
|
[filter]
|
||||||
);
|
);
|
||||||
|
@ -84,8 +100,9 @@ function LibraryPage() {
|
||||||
setIsVisible(true);
|
setIsVisible(true);
|
||||||
setIsOwned(undefined);
|
setIsOwned(undefined);
|
||||||
setIsEditor(undefined);
|
setIsEditor(undefined);
|
||||||
|
setFilterUser(undefined);
|
||||||
options.setLocation('');
|
options.setLocation('');
|
||||||
}, [setHead, setIsVisible, setIsOwned, setIsEditor, options.setLocation]);
|
}, [setHead, setIsVisible, setIsOwned, setIsEditor, setFilterUser, options.setLocation]);
|
||||||
|
|
||||||
const promptRenameLocation = useCallback(() => {
|
const promptRenameLocation = useCallback(() => {
|
||||||
setShowRenameLocation(true);
|
setShowRenameLocation(true);
|
||||||
|
@ -186,6 +203,8 @@ function LibraryPage() {
|
||||||
toggleVisible={toggleVisible}
|
toggleVisible={toggleVisible}
|
||||||
isEditor={isEditor}
|
isEditor={isEditor}
|
||||||
toggleEditor={toggleEditor}
|
toggleEditor={toggleEditor}
|
||||||
|
filterUser={filterUser}
|
||||||
|
setFilterUser={setFilterUser}
|
||||||
resetFilter={resetFilter}
|
resetFilter={resetFilter}
|
||||||
folderMode={options.folderMode}
|
folderMode={options.folderMode}
|
||||||
toggleFolderMode={toggleFolderMode}
|
toggleFolderMode={toggleFolderMode}
|
||||||
|
|
|
@ -1,19 +1,31 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { useCallback } from 'react';
|
import { motion } from 'framer-motion';
|
||||||
|
import { useCallback, useMemo } from 'react';
|
||||||
|
|
||||||
import { LocationIcon, VisibilityIcon } from '@/components/DomainIcons';
|
import { LocationIcon, VisibilityIcon } from '@/components/DomainIcons';
|
||||||
import { IconEditor, IconFilterReset, IconFolder, IconFolderTree, IconOwner } from '@/components/Icons';
|
import {
|
||||||
|
IconEditor,
|
||||||
|
IconFilterReset,
|
||||||
|
IconFolder,
|
||||||
|
IconFolderSearch,
|
||||||
|
IconFolderTree,
|
||||||
|
IconOwner,
|
||||||
|
IconUserSearch
|
||||||
|
} from '@/components/Icons';
|
||||||
import { CProps } from '@/components/props';
|
import { CProps } from '@/components/props';
|
||||||
|
import SelectUser from '@/components/select/SelectUser';
|
||||||
import Dropdown from '@/components/ui/Dropdown';
|
import Dropdown from '@/components/ui/Dropdown';
|
||||||
import DropdownButton from '@/components/ui/DropdownButton';
|
import DropdownButton from '@/components/ui/DropdownButton';
|
||||||
import MiniButton from '@/components/ui/MiniButton';
|
import MiniButton from '@/components/ui/MiniButton';
|
||||||
import SearchBar from '@/components/ui/SearchBar';
|
import SearchBar from '@/components/ui/SearchBar';
|
||||||
import SelectorButton from '@/components/ui/SelectorButton';
|
import SelectorButton from '@/components/ui/SelectorButton';
|
||||||
import { useAuth } from '@/context/AuthContext';
|
import { useUsers } from '@/context/UsersContext';
|
||||||
import useDropdown from '@/hooks/useDropdown';
|
import useDropdown from '@/hooks/useDropdown';
|
||||||
import { LocationHead } from '@/models/library';
|
import { LocationHead } from '@/models/library';
|
||||||
|
import { UserID } from '@/models/user';
|
||||||
|
import { animateDropdownItem } from '@/styling/animations';
|
||||||
import { prefixes } from '@/utils/constants';
|
import { prefixes } from '@/utils/constants';
|
||||||
import { describeLocationHead, labelLocationHead } from '@/utils/labels';
|
import { describeLocationHead, labelLocationHead } from '@/utils/labels';
|
||||||
import { tripleToggleColor } from '@/utils/utils';
|
import { tripleToggleColor } from '@/utils/utils';
|
||||||
|
@ -39,6 +51,9 @@ interface ToolbarSearchProps {
|
||||||
toggleOwned: () => void;
|
toggleOwned: () => void;
|
||||||
isEditor: boolean | undefined;
|
isEditor: boolean | undefined;
|
||||||
toggleEditor: () => void;
|
toggleEditor: () => void;
|
||||||
|
filterUser: UserID | undefined;
|
||||||
|
setFilterUser: React.Dispatch<React.SetStateAction<UserID | undefined>>;
|
||||||
|
|
||||||
resetFilter: () => void;
|
resetFilter: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,10 +78,19 @@ function ToolbarSearch({
|
||||||
toggleOwned,
|
toggleOwned,
|
||||||
isEditor,
|
isEditor,
|
||||||
toggleEditor,
|
toggleEditor,
|
||||||
|
filterUser,
|
||||||
|
setFilterUser,
|
||||||
|
|
||||||
resetFilter
|
resetFilter
|
||||||
}: ToolbarSearchProps) {
|
}: ToolbarSearchProps) {
|
||||||
const { user } = useAuth();
|
|
||||||
const headMenu = useDropdown();
|
const headMenu = useDropdown();
|
||||||
|
const userMenu = useDropdown();
|
||||||
|
const { users } = useUsers();
|
||||||
|
|
||||||
|
const userActive = useMemo(
|
||||||
|
() => isOwned !== undefined || isEditor !== undefined || filterUser !== undefined,
|
||||||
|
[isOwned, isEditor, filterUser]
|
||||||
|
);
|
||||||
|
|
||||||
const handleChange = useCallback(
|
const handleChange = useCallback(
|
||||||
(newValue: LocationHead | undefined) => {
|
(newValue: LocationHead | undefined) => {
|
||||||
|
@ -106,7 +130,7 @@ function ToolbarSearch({
|
||||||
<div
|
<div
|
||||||
className={clsx(
|
className={clsx(
|
||||||
'ml-3 pt-1 self-center',
|
'ml-3 pt-1 self-center',
|
||||||
'min-w-[4.5rem] sm:min-w-[5.5rem]',
|
'min-w-[4.5rem] sm:min-w-[7.4rem]',
|
||||||
'select-none',
|
'select-none',
|
||||||
'whitespace-nowrap'
|
'whitespace-nowrap'
|
||||||
)}
|
)}
|
||||||
|
@ -114,41 +138,58 @@ function ToolbarSearch({
|
||||||
{filtered} из {total}
|
{filtered} из {total}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{user ? (
|
<div className='cc-icons'>
|
||||||
<div className='cc-icons'>
|
<MiniButton
|
||||||
<MiniButton
|
title='Видимость'
|
||||||
title='Видимость'
|
icon={<VisibilityIcon value={true} className={tripleToggleColor(isVisible)} />}
|
||||||
icon={<VisibilityIcon value={true} className={tripleToggleColor(isVisible)} />}
|
onClick={toggleVisible}
|
||||||
onClick={toggleVisible}
|
/>
|
||||||
/>
|
|
||||||
|
|
||||||
|
<div ref={userMenu.ref} className='flex'>
|
||||||
<MiniButton
|
<MiniButton
|
||||||
title='Я - Владелец'
|
title='Поиск пользователя'
|
||||||
icon={<IconOwner size='1.25rem' className={tripleToggleColor(isOwned)} />}
|
hideTitle={userMenu.isOpen}
|
||||||
onClick={toggleOwned}
|
icon={<IconUserSearch size='1.25rem' className={userActive ? 'icon-green' : 'icon-primary'} />}
|
||||||
/>
|
onClick={userMenu.toggle}
|
||||||
|
|
||||||
<MiniButton
|
|
||||||
title='Я - Редактор'
|
|
||||||
icon={<IconEditor size='1.25rem' className={tripleToggleColor(isEditor)} />}
|
|
||||||
onClick={toggleEditor}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<MiniButton
|
|
||||||
title='Сбросить фильтры'
|
|
||||||
icon={<IconFilterReset size='1.25rem' className='icon-primary' />}
|
|
||||||
onClick={resetFilter}
|
|
||||||
disabled={!hasCustomFilter}
|
|
||||||
/>
|
/>
|
||||||
|
<Dropdown isOpen={userMenu.isOpen}>
|
||||||
|
<DropdownButton
|
||||||
|
text='Я - Владелец'
|
||||||
|
icon={<IconOwner size='1.25rem' className={tripleToggleColor(isOwned)} />}
|
||||||
|
onClick={toggleOwned}
|
||||||
|
/>
|
||||||
|
<DropdownButton
|
||||||
|
text='Я - Редактор'
|
||||||
|
icon={<IconEditor size='1.25rem' className={tripleToggleColor(isEditor)} />}
|
||||||
|
onClick={toggleEditor}
|
||||||
|
/>
|
||||||
|
<motion.div className='px-1 pb-1' variants={animateDropdownItem}>
|
||||||
|
<SelectUser
|
||||||
|
noBorder
|
||||||
|
placeholder='Выберите автора'
|
||||||
|
className='min-w-[15rem] text-sm'
|
||||||
|
items={users}
|
||||||
|
value={filterUser}
|
||||||
|
onSelectValue={setFilterUser}
|
||||||
|
/>
|
||||||
|
</motion.div>
|
||||||
|
</Dropdown>
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
|
||||||
|
|
||||||
<div className='flex h-full'>
|
<MiniButton
|
||||||
|
title='Сбросить фильтры'
|
||||||
|
icon={<IconFilterReset size='1.25rem' className='icon-primary' />}
|
||||||
|
onClick={resetFilter}
|
||||||
|
disabled={!hasCustomFilter}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='flex h-full flex-grow pr-4'>
|
||||||
<SearchBar
|
<SearchBar
|
||||||
id='library_search'
|
id='library_search'
|
||||||
placeholder='Поиск'
|
placeholder='Поиск'
|
||||||
noBorder
|
noBorder
|
||||||
className='min-w-[7rem] sm:min-w-[10rem]'
|
className={clsx('min-w-[7rem] sm:min-w-[10rem] max-w-[20rem]', folderMode && 'flex-grow')}
|
||||||
value={query}
|
value={query}
|
||||||
onChange={setQuery}
|
onChange={setQuery}
|
||||||
/>
|
/>
|
||||||
|
@ -163,7 +204,7 @@ function ToolbarSearch({
|
||||||
head ? (
|
head ? (
|
||||||
<LocationIcon value={head} size='1.25rem' />
|
<LocationIcon value={head} size='1.25rem' />
|
||||||
) : (
|
) : (
|
||||||
<IconFolder size='1.25rem' className='clr-text-controls' />
|
<IconFolderSearch size='1.25rem' className='clr-text-controls' />
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
onClick={handleFolderClick}
|
onClick={handleFolderClick}
|
||||||
|
@ -171,7 +212,7 @@ function ToolbarSearch({
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Dropdown isOpen={headMenu.isOpen} stretchLeft className='z-modalTooltip'>
|
<Dropdown isOpen={headMenu.isOpen} stretchLeft className='z-modalTooltip'>
|
||||||
<DropdownButton className='w-[10rem]' title='Переключение в режим Проводник' onClick={handleToggleFolder}>
|
<DropdownButton title='Переключение в режим Проводник' onClick={handleToggleFolder}>
|
||||||
<div className='inline-flex items-center gap-3'>
|
<div className='inline-flex items-center gap-3'>
|
||||||
<IconFolderTree size='1rem' className='clr-text-controls' />
|
<IconFolderTree size='1rem' className='clr-text-controls' />
|
||||||
<span>проводник...</span>
|
<span>проводник...</span>
|
||||||
|
@ -207,7 +248,7 @@ function ToolbarSearch({
|
||||||
placeholder='Путь'
|
placeholder='Путь'
|
||||||
noIcon
|
noIcon
|
||||||
noBorder
|
noBorder
|
||||||
className='min-w-[4.5rem] sm:min-w-[5rem]'
|
className='w-[4.5rem] sm:w-[5rem] flex-grow'
|
||||||
value={path}
|
value={path}
|
||||||
onChange={setPath}
|
onChange={setPath}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -89,13 +89,18 @@ function ViewSideLocation({
|
||||||
place='right-start'
|
place='right-start'
|
||||||
/>
|
/>
|
||||||
<div className='cc-icons'>
|
<div className='cc-icons'>
|
||||||
|
{canRename ? (
|
||||||
|
<MiniButton
|
||||||
|
icon={<IconFolderEdit size='1.25rem' className='icon-primary' />}
|
||||||
|
titleHtml='<b>Редактирование пути</b><br/>Перемещаются только Ваши схемы<br/>в указанной папке (и подпапках)'
|
||||||
|
onClick={onRenameLocation}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
<MiniButton
|
<MiniButton
|
||||||
icon={<IconFolderEdit size='1.25rem' className='icon-primary' />}
|
title='Вложенные папки' // prettier: split-lines
|
||||||
titleHtml='<b>Редактирование пути</b><br/>Перемещаются только Ваши схемы<br/>в указанной папке (и подпапках)'
|
icon={<SubfoldersIcon value={subfolders} />}
|
||||||
onClick={onRenameLocation}
|
onClick={toggleSubfolders}
|
||||||
disabled={!canRename}
|
|
||||||
/>
|
/>
|
||||||
<MiniButton title='Вложенные папки' icon={<SubfoldersIcon value={subfolders} />} onClick={toggleSubfolders} />
|
|
||||||
<MiniButton
|
<MiniButton
|
||||||
icon={<IconFolderTree size='1.25rem' className='icon-green' />}
|
icon={<IconFolderTree size='1.25rem' className='icon-green' />}
|
||||||
title='Переключение в режим Поиск'
|
title='Переключение в режим Поиск'
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { useConceptOptions } from '@/context/ConceptOptionsContext';
|
||||||
import { useConceptNavigation } from '@/context/NavigationContext';
|
import { useConceptNavigation } from '@/context/NavigationContext';
|
||||||
import useQueryStrings from '@/hooks/useQueryStrings';
|
import useQueryStrings from '@/hooks/useQueryStrings';
|
||||||
import { HelpTopic } from '@/models/miscellaneous';
|
import { HelpTopic } from '@/models/miscellaneous';
|
||||||
|
import { PARAMETER } from '@/utils/constants';
|
||||||
|
|
||||||
import TopicsList from './TopicsList';
|
import TopicsList from './TopicsList';
|
||||||
import ViewTopic from './ViewTopic';
|
import ViewTopic from './ViewTopic';
|
||||||
|
@ -18,6 +19,14 @@ function ManualsPage() {
|
||||||
|
|
||||||
const { mainHeight } = useConceptOptions();
|
const { mainHeight } = useConceptOptions();
|
||||||
|
|
||||||
|
if (!Object.values(HelpTopic).includes(activeTopic)) {
|
||||||
|
setTimeout(() => {
|
||||||
|
router.push(urls.page404);
|
||||||
|
}, PARAMETER.refreshTimeout);
|
||||||
|
console.log(1);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const onSelectTopic = useCallback(
|
const onSelectTopic = useCallback(
|
||||||
(newTopic: HelpTopic) => {
|
(newTopic: HelpTopic) => {
|
||||||
router.push(urls.help_topic(newTopic));
|
router.push(urls.help_topic(newTopic));
|
||||||
|
|
|
@ -5,6 +5,7 @@ import {
|
||||||
IconFolderEdit,
|
IconFolderEdit,
|
||||||
IconFolderEmpty,
|
IconFolderEmpty,
|
||||||
IconFolderOpened,
|
IconFolderOpened,
|
||||||
|
IconFolderSearch,
|
||||||
IconFolderTree,
|
IconFolderTree,
|
||||||
IconOSS,
|
IconOSS,
|
||||||
IconRSForm,
|
IconRSForm,
|
||||||
|
@ -12,7 +13,8 @@ import {
|
||||||
IconShow,
|
IconShow,
|
||||||
IconSortAsc,
|
IconSortAsc,
|
||||||
IconSortDesc,
|
IconSortDesc,
|
||||||
IconSubfolders
|
IconSubfolders,
|
||||||
|
IconUserSearch
|
||||||
} from '@/components/Icons';
|
} from '@/components/Icons';
|
||||||
import LinkTopic from '@/components/ui/LinkTopic';
|
import LinkTopic from '@/components/ui/LinkTopic';
|
||||||
import { useConceptOptions } from '@/context/ConceptOptionsContext';
|
import { useConceptOptions } from '@/context/ConceptOptionsContext';
|
||||||
|
@ -43,11 +45,14 @@ function HelpLibrary() {
|
||||||
<IconSortAsc size='1rem' className='inline-icon' />
|
<IconSortAsc size='1rem' className='inline-icon' />
|
||||||
<IconSortDesc size='1rem' className='inline-icon' /> сортировка по клику на заголовок таблицы
|
<IconSortDesc size='1rem' className='inline-icon' /> сортировка по клику на заголовок таблицы
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<IconUserSearch size='1rem' className='inline-icon' /> фильтр по пользователю
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<IconSearch size='1rem' className='inline-icon' /> фильтр по названию и шифру
|
<IconSearch size='1rem' className='inline-icon' /> фильтр по названию и шифру
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<IconFolder size='1rem' className='inline-icon' /> фильтр по расположению
|
<IconFolderSearch size='1rem' className='inline-icon' /> фильтр по расположению
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<IconFilterReset size='1rem' className='inline-icon' /> сбросить фильтры
|
<IconFilterReset size='1rem' className='inline-icon' /> сбросить фильтры
|
||||||
|
|
|
@ -6,7 +6,9 @@ import { useCallback, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
import BadgeHelp from '@/components/info/BadgeHelp';
|
import BadgeHelp from '@/components/info/BadgeHelp';
|
||||||
|
import { CProps } from '@/components/props';
|
||||||
import RSInput from '@/components/RSInput';
|
import RSInput from '@/components/RSInput';
|
||||||
|
import { parser as rslangParser } from '@/components/RSInput/rslang/parserAST';
|
||||||
import { RSTextWrapper } from '@/components/RSInput/textEditing';
|
import { RSTextWrapper } from '@/components/RSInput/textEditing';
|
||||||
import Overlay from '@/components/ui/Overlay';
|
import Overlay from '@/components/ui/Overlay';
|
||||||
import { useRSForm } from '@/context/RSFormContext';
|
import { useRSForm } from '@/context/RSFormContext';
|
||||||
|
@ -18,6 +20,7 @@ import { ConstituentaID, IConstituenta } from '@/models/rsform';
|
||||||
import { getDefinitionPrefix } from '@/models/rsformAPI';
|
import { getDefinitionPrefix } from '@/models/rsformAPI';
|
||||||
import { IExpressionParse, IRSErrorDescription, SyntaxTree } from '@/models/rslang';
|
import { IExpressionParse, IRSErrorDescription, SyntaxTree } from '@/models/rslang';
|
||||||
import { TokenID } from '@/models/rslang';
|
import { TokenID } from '@/models/rslang';
|
||||||
|
import { transformAST } from '@/utils/codemirror';
|
||||||
import { storage } from '@/utils/constants';
|
import { storage } from '@/utils/constants';
|
||||||
import { errors, labelTypification } from '@/utils/labels';
|
import { errors, labelTypification } from '@/utils/labels';
|
||||||
|
|
||||||
|
@ -124,17 +127,25 @@ function EditorRSExpression({
|
||||||
setIsModified(true);
|
setIsModified(true);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
function handleShowAST() {
|
function handleShowAST(event: CProps.EventMouse) {
|
||||||
handleCheckExpression(parse => {
|
if (event.ctrlKey) {
|
||||||
if (!parse.astText) {
|
const tree = rslangParser.parse(value);
|
||||||
toast.error(errors.astFailed);
|
const ast = transformAST(tree);
|
||||||
} else {
|
setSyntaxTree(ast);
|
||||||
setSyntaxTree(parse.ast);
|
setExpression(value);
|
||||||
// TODO: return prefix from parser API instead of prefixLength
|
setShowAST(true);
|
||||||
setExpression(getDefinitionPrefix(activeCst) + value);
|
} else {
|
||||||
setShowAST(true);
|
handleCheckExpression(parse => {
|
||||||
}
|
if (!parse.astText) {
|
||||||
});
|
toast.error(errors.astFailed);
|
||||||
|
} else {
|
||||||
|
setSyntaxTree(parse.ast);
|
||||||
|
// TODO: return prefix from parser API instead of prefixLength
|
||||||
|
setExpression(getDefinitionPrefix(activeCst) + value);
|
||||||
|
setShowAST(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const controls = useMemo(
|
const controls = useMemo(
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { IconControls, IconTree } from '@/components/Icons';
|
import { IconControls, IconTree } from '@/components/Icons';
|
||||||
|
import { CProps } from '@/components/props';
|
||||||
import MiniButton from '@/components/ui/MiniButton';
|
import MiniButton from '@/components/ui/MiniButton';
|
||||||
import Overlay from '@/components/ui/Overlay';
|
import Overlay from '@/components/ui/Overlay';
|
||||||
import { useRSForm } from '@/context/RSFormContext';
|
import { useRSForm } from '@/context/RSFormContext';
|
||||||
|
@ -8,7 +9,7 @@ interface ToolbarRSExpressionProps {
|
||||||
showControls: boolean;
|
showControls: boolean;
|
||||||
|
|
||||||
toggleControls: () => void;
|
toggleControls: () => void;
|
||||||
showAST: () => void;
|
showAST: (event: CProps.EventMouse) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ToolbarRSExpression({ disabled, showControls, toggleControls, showAST }: ToolbarRSExpressionProps) {
|
function ToolbarRSExpression({ disabled, showControls, toggleControls, showAST }: ToolbarRSExpressionProps) {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { GramData, Grammeme, NounGrams, PartOfSpeech, VerbGrams } from '@/models
|
||||||
import { GraphColoring } from '@/models/miscellaneous';
|
import { GraphColoring } from '@/models/miscellaneous';
|
||||||
import { CstClass, ExpressionStatus, IConstituenta } from '@/models/rsform';
|
import { CstClass, ExpressionStatus, IConstituenta } from '@/models/rsform';
|
||||||
import { ISyntaxTreeNode, TokenID } from '@/models/rslang';
|
import { ISyntaxTreeNode, TokenID } from '@/models/rslang';
|
||||||
|
import { PARAMETER } from '@/utils/constants';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents application color theme configuration.
|
* Represents application color theme configuration.
|
||||||
|
@ -375,8 +376,65 @@ export function colorBgSyntaxTree(node: ISyntaxTreeNode, colors: IColorTheme): s
|
||||||
case TokenID.ITERATE:
|
case TokenID.ITERATE:
|
||||||
return colors.bgRed;
|
return colors.bgRed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (node.data.value) {
|
||||||
|
case 'Expression':
|
||||||
|
case 'Local':
|
||||||
|
return colors.bgGreen;
|
||||||
|
|
||||||
|
case 'Global':
|
||||||
|
case 'Radical':
|
||||||
|
case 'Function':
|
||||||
|
case 'Predicate':
|
||||||
|
case 'Literal':
|
||||||
|
case 'Integer':
|
||||||
|
case 'EmptySet':
|
||||||
|
case 'IntegerSet':
|
||||||
|
return colors.bgTeal;
|
||||||
|
|
||||||
|
case 'Logic':
|
||||||
|
case 'Logic_predicates':
|
||||||
|
case 'Variable':
|
||||||
|
case 'Tuple':
|
||||||
|
case 'Setexpr_enum_min2':
|
||||||
|
case 'Setexpr_enum':
|
||||||
|
case 'Setexpr':
|
||||||
|
case 'Setexpr_binary':
|
||||||
|
case 'Setexpr_generators':
|
||||||
|
case 'Enumeration':
|
||||||
|
case 'Boolean':
|
||||||
|
case 'Filter_expression':
|
||||||
|
case 'Filter':
|
||||||
|
case 'Declarative':
|
||||||
|
case 'Imperative':
|
||||||
|
case 'Imp_blocks':
|
||||||
|
case 'Recursion':
|
||||||
|
case 'TextFunction':
|
||||||
|
case 'Logic_unary':
|
||||||
|
case 'Logic_quantor':
|
||||||
|
case 'Variable_pack':
|
||||||
|
case 'Logic_binary':
|
||||||
|
case 'Function_decl':
|
||||||
|
case 'Arguments':
|
||||||
|
case 'Declaration':
|
||||||
|
return colors.bgBlue;
|
||||||
|
|
||||||
|
case 'BigPr':
|
||||||
|
case 'SmallPr':
|
||||||
|
case 'Card':
|
||||||
|
case 'Bool':
|
||||||
|
case 'Debool':
|
||||||
|
case 'Red':
|
||||||
|
case 'PrefixD':
|
||||||
|
case 'PrefixI':
|
||||||
|
case 'PrefixR':
|
||||||
|
return colors.bgPurple;
|
||||||
|
|
||||||
|
case PARAMETER.errorNodeLabel:
|
||||||
|
return colors.bgRed;
|
||||||
|
}
|
||||||
// node
|
// node
|
||||||
return colors.bgRed;
|
return colors.bgPurple;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -13,8 +13,10 @@ import { IEntityReference, ISyntacticReference } from '@/models/language';
|
||||||
import { parseEntityReference, parseGrammemes, parseSyntacticReference } from '@/models/languageAPI';
|
import { parseEntityReference, parseGrammemes, parseSyntacticReference } from '@/models/languageAPI';
|
||||||
import { IConstituenta } from '@/models/rsform';
|
import { IConstituenta } from '@/models/rsform';
|
||||||
import { isBasicConcept } from '@/models/rsformAPI';
|
import { isBasicConcept } from '@/models/rsformAPI';
|
||||||
|
import { SyntaxTree } from '@/models/rslang';
|
||||||
|
|
||||||
import { colorFgGrammeme, IColorTheme } from '../styling/color';
|
import { colorFgGrammeme, IColorTheme } from '../styling/color';
|
||||||
|
import { PARAMETER } from './constants';
|
||||||
import { describeConstituentaTerm, labelCstTypification, labelGrammeme } from './labels';
|
import { describeConstituentaTerm, labelCstTypification, labelGrammeme } from './labels';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -91,6 +93,56 @@ export function printTree(tree: Tree): string {
|
||||||
return state.output;
|
return state.output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform Tree to {@link SyntaxTree}.
|
||||||
|
*/
|
||||||
|
export function transformAST(tree: Tree): SyntaxTree {
|
||||||
|
const result: SyntaxTree = [];
|
||||||
|
const parents: number[] = [];
|
||||||
|
const cursor = tree.cursor();
|
||||||
|
let finished = false;
|
||||||
|
let leave = true;
|
||||||
|
while (!finished) {
|
||||||
|
let node = cursorNode(cursor);
|
||||||
|
node.isLeaf = !cursor.firstChild();
|
||||||
|
|
||||||
|
leave = true;
|
||||||
|
result.push({
|
||||||
|
uid: result.length,
|
||||||
|
parent: parents.length > 0 ? parents[parents.length - 1] : result.length,
|
||||||
|
typeID: node.type.id,
|
||||||
|
start: node.from,
|
||||||
|
finish: node.to,
|
||||||
|
data: {
|
||||||
|
dataType: 'string',
|
||||||
|
value: node.type.name == '⚠' ? PARAMETER.errorNodeLabel : node.type.name
|
||||||
|
}
|
||||||
|
});
|
||||||
|
parents.push(result.length - 1);
|
||||||
|
|
||||||
|
if (!node.isLeaf) continue;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
node = cursorNode(cursor, node.isLeaf);
|
||||||
|
if (leave) {
|
||||||
|
parents.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
leave = cursor.type.isAnonymous;
|
||||||
|
node.isLeaf = false;
|
||||||
|
if (cursor.nextSibling()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!cursor.parent()) {
|
||||||
|
finished = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
leave = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves a list of all nodes, containing given range and corresponding to a filter.
|
* Retrieves a list of all nodes, containing given range and corresponding to a filter.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -34,6 +34,7 @@ export const PARAMETER = {
|
||||||
statSmallThreshold: 3, // characters - threshold for small labels - small font
|
statSmallThreshold: 3, // characters - threshold for small labels - small font
|
||||||
|
|
||||||
logicLabel: 'LOGIC',
|
logicLabel: 'LOGIC',
|
||||||
|
errorNodeLabel: '[ERROR]',
|
||||||
exteorVersion: '4.9.5',
|
exteorVersion: '4.9.5',
|
||||||
|
|
||||||
TOOLTIP_WIDTH: 'max-w-[29rem]'
|
TOOLTIP_WIDTH: 'max-w-[29rem]'
|
||||||
|
@ -116,6 +117,7 @@ export const storage = {
|
||||||
librarySearchVisible: 'library.search.visible',
|
librarySearchVisible: 'library.search.visible',
|
||||||
librarySearchOwned: 'library.search.owned',
|
librarySearchOwned: 'library.search.owned',
|
||||||
librarySearchEditor: 'library.search.editor',
|
librarySearchEditor: 'library.search.editor',
|
||||||
|
librarySearchUser: 'library.search.user',
|
||||||
libraryPagination: 'library.pagination',
|
libraryPagination: 'library.pagination',
|
||||||
|
|
||||||
rsgraphFilter: 'rsgraph.filter2',
|
rsgraphFilter: 'rsgraph.filter2',
|
||||||
|
|
|
@ -362,11 +362,11 @@ export function describeExpressionStatus(status: ExpressionStatus): string {
|
||||||
export function labelHelpTopic(topic: HelpTopic): string {
|
export function labelHelpTopic(topic: HelpTopic): string {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
switch (topic) {
|
switch (topic) {
|
||||||
case HelpTopic.MAIN: return 'Портал';
|
case HelpTopic.MAIN: return '🏠 Портал';
|
||||||
|
|
||||||
case HelpTopic.THESAURUS: return 'Тезаурус';
|
case HelpTopic.THESAURUS: return '📖 Тезаурус';
|
||||||
|
|
||||||
case HelpTopic.INTERFACE: return 'Интерфейс';
|
case HelpTopic.INTERFACE: return '🦄 Интерфейс';
|
||||||
case HelpTopic.UI_LIBRARY: return 'Библиотека';
|
case HelpTopic.UI_LIBRARY: return 'Библиотека';
|
||||||
case HelpTopic.UI_RS_MENU: return 'Меню схемы';
|
case HelpTopic.UI_RS_MENU: return 'Меню схемы';
|
||||||
case HelpTopic.UI_RS_CARD: return 'Карточка схемы';
|
case HelpTopic.UI_RS_CARD: return 'Карточка схемы';
|
||||||
|
@ -378,7 +378,7 @@ export function labelHelpTopic(topic: HelpTopic): string {
|
||||||
case HelpTopic.UI_CST_CLASS: return 'Класс конституенты';
|
case HelpTopic.UI_CST_CLASS: return 'Класс конституенты';
|
||||||
case HelpTopic.UI_OSS_GRAPH: return 'Граф синтеза';
|
case HelpTopic.UI_OSS_GRAPH: return 'Граф синтеза';
|
||||||
|
|
||||||
case HelpTopic.CONCEPTUAL: return 'Концептуализация';
|
case HelpTopic.CONCEPTUAL: return '♨️ Концептуализация';
|
||||||
case HelpTopic.CC_SYSTEM: return 'Система определений';
|
case HelpTopic.CC_SYSTEM: return 'Система определений';
|
||||||
case HelpTopic.CC_CONSTITUENTA: return 'Конституента';
|
case HelpTopic.CC_CONSTITUENTA: return 'Конституента';
|
||||||
case HelpTopic.CC_RELATIONS: return 'Связи понятий';
|
case HelpTopic.CC_RELATIONS: return 'Связи понятий';
|
||||||
|
@ -386,24 +386,24 @@ export function labelHelpTopic(topic: HelpTopic): string {
|
||||||
case HelpTopic.CC_OSS: return 'Операционная схема';
|
case HelpTopic.CC_OSS: return 'Операционная схема';
|
||||||
case HelpTopic.CC_PROPAGATION: return 'Сквозные изменения';
|
case HelpTopic.CC_PROPAGATION: return 'Сквозные изменения';
|
||||||
|
|
||||||
case HelpTopic.RSLANG: return 'Экспликация';
|
case HelpTopic.RSLANG: return '🚀 Экспликация';
|
||||||
case HelpTopic.RSL_TYPES: return 'Типизация';
|
case HelpTopic.RSL_TYPES: return 'Типизация';
|
||||||
case HelpTopic.RSL_CORRECT: return 'Переносимость';
|
case HelpTopic.RSL_CORRECT: return 'Переносимость';
|
||||||
case HelpTopic.RSL_INTERPRET: return 'Интерпретируемость';
|
case HelpTopic.RSL_INTERPRET: return 'Интерпретируемость';
|
||||||
case HelpTopic.RSL_OPERATIONS: return 'Операции';
|
case HelpTopic.RSL_OPERATIONS: return 'Операции';
|
||||||
case HelpTopic.RSL_TEMPLATES: return 'Банк выражений';
|
case HelpTopic.RSL_TEMPLATES: return 'Банк выражений';
|
||||||
|
|
||||||
case HelpTopic.TERM_CONTROL: return 'Терминологизация';
|
case HelpTopic.TERM_CONTROL: return '🪸 Терминологизация';
|
||||||
case HelpTopic.ACCESS: return 'Доступы';
|
case HelpTopic.ACCESS: return '👀 Доступы';
|
||||||
case HelpTopic.VERSIONS: return 'Версионирование';
|
case HelpTopic.VERSIONS: return '🏺 Версионирование';
|
||||||
|
|
||||||
case HelpTopic.INFO: return 'Информация';
|
case HelpTopic.INFO: return '📰 Информация';
|
||||||
case HelpTopic.INFO_RULES: return 'Правила';
|
case HelpTopic.INFO_RULES: return 'Правила';
|
||||||
case HelpTopic.INFO_CONTRIB: return 'Разработчики';
|
case HelpTopic.INFO_CONTRIB: return 'Разработчики';
|
||||||
case HelpTopic.INFO_PRIVACY: return 'Обработка данных';
|
case HelpTopic.INFO_PRIVACY: return 'Обработка данных';
|
||||||
case HelpTopic.INFO_API: return 'REST API';
|
case HelpTopic.INFO_API: return 'REST API';
|
||||||
|
|
||||||
case HelpTopic.EXTEOR: return 'Экстеор';
|
case HelpTopic.EXTEOR: return '🖥️ Экстеор';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -622,6 +622,9 @@ export function labelSyntaxTree(node: ISyntaxTreeNode): string {
|
||||||
return labelToken(node.typeID);
|
return labelToken(node.typeID);
|
||||||
}
|
}
|
||||||
// node
|
// node
|
||||||
|
if (node.data.value) {
|
||||||
|
return node.data.value as string;
|
||||||
|
}
|
||||||
return 'UNKNOWN ' + String(node.typeID);
|
return 'UNKNOWN ' + String(node.typeID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -760,6 +763,8 @@ export function describeRSError(error: IRSErrorDescription): string {
|
||||||
return `Использование имени переменной вне области действия: ${error.params[0]}`;
|
return `Использование имени переменной вне области действия: ${error.params[0]}`;
|
||||||
case RSErrorType.invalidElementPredicate:
|
case RSErrorType.invalidElementPredicate:
|
||||||
return `Несоответствие типизаций операндов для оператора: ${error.params[0]}${error.params[1]}${error.params[2]}`;
|
return `Несоответствие типизаций операндов для оператора: ${error.params[0]}${error.params[1]}${error.params[2]}`;
|
||||||
|
case RSErrorType.invalidEmptySetUsage:
|
||||||
|
return 'Бессмысленное использование пустого множества';
|
||||||
case RSErrorType.invalidArgsArity:
|
case RSErrorType.invalidArgsArity:
|
||||||
return `Неверное число аргументов терм-функции: ${error.params[0]} != ${error.params[1]}`;
|
return `Неверное число аргументов терм-функции: ${error.params[0]} != ${error.params[1]}`;
|
||||||
case RSErrorType.invalidArgumentType:
|
case RSErrorType.invalidArgumentType:
|
||||||
|
|
|
@ -3,10 +3,6 @@
|
||||||
$container= Read-Host -Prompt "Enter backend container name: "
|
$container= Read-Host -Prompt "Enter backend container name: "
|
||||||
|
|
||||||
function PopulateDevData() {
|
function PopulateDevData() {
|
||||||
ImportInitialData
|
|
||||||
}
|
|
||||||
|
|
||||||
function ImportInitialData() {
|
|
||||||
docker exec `
|
docker exec `
|
||||||
-it $container `
|
-it $container `
|
||||||
python3.12 manage.py loaddata ./fixtures/InitialData.json
|
python3.12 manage.py loaddata ./fixtures/InitialData.json
|
||||||
|
|
Loading…
Reference in New Issue
Block a user