Compare commits

...

3 Commits

18 changed files with 376 additions and 231 deletions

View File

@ -2,6 +2,9 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 64 64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"> <svg width="100%" height="100%" viewBox="0 0 64 64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(0.069972,0,0,0.069972,-2.986098,-11.802594)"> <g transform="matrix(0.069972,0,0,0.069972,-2.986098,-11.802594)">
<path d="M242,226C206,232 174.833,248.333 148.5,275C122.167,301.667 106,333 100,369L100,884C106,919.333 122,950 148,976C174,1002 204.333,1018.333 239,1025L243,1026L758,1026L761,1025C796.333,1018.333 826.833,1001.833 852.5,975.5C878.167,949.167 894,918.333 900,883L900,368C894,332.667 877.667,301.667 851,275C824.333,248.333 793,232 757,226L242,226ZM802,325L802,401C731.333,401.667 636.667,401.667 518,401L519,326L802,325ZM481,326C481.667,342.667 482,367.667 482,401L200,401L200,326L481,326ZM518,438L802,438L802,514L518,514L518,438ZM482,438L482,514L200,513L200,439L482,438ZM554,550C590.667,550 645.667,550.333 719,551L801,551L801,627L518,628L518,550L554,550ZM482,550L482,628L200,628L200,551L482,551L482,550ZM518,665L801,665C801.667,677 801.667,695.333 801,720L801,740L519,740L518,665ZM311,700C327.667,700 343.833,703.5 359.5,710.5C375.167,717.5 388.333,727.333 399,740C413.667,756.667 422,776.5 424,799.5C426,822.5 422,844.5 412,865.5C402,886.5 387,902 367,912C348.333,922.667 327.5,927.167 304.5,925.5C281.5,923.833 260.833,916.333 242.5,903C224.167,889.667 212,872.333 206,851C198,831.667 196.333,811.333 201,790C205.667,768.667 215.333,750.167 230,734.5C244.667,718.833 262.333,708.667 283,704C292.333,701.333 301.667,700 311,700Z" style="fill:rgb(255,152,0);fill-rule:nonzero;"/> <path d="M242,226C206,232 174.833,248.333 148.5,275C122.167,301.667 106,333 100,369L100,884C106,919.333 122,950 148,976C174,1002 204.333,1018.333 239,1025L243,1026L758,1026L761,1025C796.333,1018.333 826.833,1001.833 852.5,975.5C878.167,949.167 894,918.333 900,883L900,368C894,332.667 877.667,301.667 851,275C824.333,248.333 793,232 757,226L242,226Z" style="fill:rgb(255,152,0);fill-rule:nonzero;"/>
<g transform="matrix(14.291431,0,0,14.291431,42.675613,168.675956)">
<path d="M35.778,26.682C38.344,26.682 42.193,26.705 47.324,26.752L53.061,26.752L53.061,32.07L33.259,32.14L33.259,26.682L35.778,26.682ZM53.131,10.938L53.131,16.256C48.187,16.303 41.563,16.303 33.259,16.256L33.329,11.008L53.131,10.938ZM30.74,18.845L30.74,24.163L11.008,24.093L11.008,18.915L30.74,18.845ZM30.67,11.008C30.717,12.175 30.74,13.924 30.74,16.256L11.008,16.256L11.008,11.008L30.67,11.008ZM18.775,37.178C19.941,37.178 21.073,37.423 22.169,37.913C23.265,38.402 24.186,39.09 24.933,39.977C25.959,41.143 26.542,42.531 26.682,44.14C26.822,45.749 26.542,47.289 25.842,48.758C25.143,50.228 24.093,51.312 22.694,52.012C21.387,52.758 19.93,53.073 18.32,52.956C16.711,52.84 15.265,52.315 13.982,51.382C12.699,50.449 11.848,49.236 11.428,47.744C10.868,46.391 10.752,44.968 11.078,43.475C11.405,41.983 12.081,40.688 13.107,39.592C14.134,38.496 15.37,37.784 16.816,37.458C17.469,37.271 18.122,37.178 18.775,37.178ZM33.259,18.845L53.131,18.845L53.131,24.163L33.259,24.163L33.259,18.845ZM30.74,26.752L30.74,32.14L11.008,32.14L11.008,26.752L30.74,26.752ZM33.259,34.729L53.061,34.729C53.108,35.568 53.108,36.851 53.061,38.577L53.061,39.977L33.329,39.977L33.259,34.729Z" style="fill:white;"/>
</g>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

18
assets/icons/rssicon.svg Normal file
View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 64 64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(0.069972,0,0,0.069972,-2.986098,-11.802594)">
<path d="M242,226C206,232 174.833,248.333 148.5,275C122.167,301.667 106,333 100,369L100,884C106,919.333 122,950 148,976C174,1002 204.333,1018.333 239,1025L243,1026L758,1026L761,1025C796.333,1018.333 826.833,1001.833 852.5,975.5C878.167,949.167 894,918.333 900,883L900,368C894,332.667 877.667,301.667 851,275C824.333,248.333 793,232 757,226L242,226Z" style="fill:rgb(204,93,21);fill-rule:nonzero;"/>
<g transform="matrix(1,0,0,1,0.001401,0)">
<g transform="matrix(3.343963,0,0,3.343963,60.268889,206.334409)">
<circle cx="68" cy="189" r="24" style="fill:white;"/>
</g>
<g transform="matrix(3.343963,0,0,3.343963,60.268889,206.334409)">
<path d="M160,213L126,213C126,168.016 88.984,131 44,131L44,97C107.636,97 160,149.364 160,213Z" style="fill:white;fill-rule:nonzero;"/>
</g>
<g transform="matrix(3.343963,0,0,3.343963,60.268889,206.334409)">
<path d="M184,213C184,136.198 120.802,73 44,73L44,38C140.002,38 219,116.998 219,213L184,213Z" style="fill:white;fill-rule:nonzero;"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -46,9 +46,9 @@
"cross-env": "^10.0.0", "cross-env": "^10.0.0",
"dayjs": "^1.11.18", "dayjs": "^1.11.18",
"dotenv": "^17.2.1", "dotenv": "^17.2.1",
"electron-store": "^11.0.2",
"gcode-preview": "^2.18.0", "gcode-preview": "^2.18.0",
"keycloak-js": "^26.2.0", "keycloak-js": "^26.2.0",
"keytar": "^7.9.0",
"lodash": "^4.17.23", "lodash": "^4.17.23",
"loglevel": "^1.9.2", "loglevel": "^1.9.2",
"nanoid": "^5.1.14", "nanoid": "^5.1.14",

236
pnpm-lock.yaml generated
View File

@ -119,15 +119,15 @@ importers:
dotenv: dotenv:
specifier: ^17.2.1 specifier: ^17.2.1
version: 17.2.3 version: 17.2.3
electron-store:
specifier: ^11.0.2
version: 11.0.2
gcode-preview: gcode-preview:
specifier: ^2.18.0 specifier: ^2.18.0
version: 2.18.0 version: 2.18.0
keycloak-js: keycloak-js:
specifier: ^26.2.0 specifier: ^26.2.0
version: 26.2.2 version: 26.2.2
keytar:
specifier: ^7.9.0
version: 7.9.0
lodash: lodash:
specifier: ^4.17.23 specifier: ^4.17.23
version: 4.17.23 version: 4.17.23
@ -2358,6 +2358,14 @@ packages:
ajv: ajv:
optional: true optional: true
ajv-formats@3.0.1:
resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==}
peerDependencies:
ajv: ^8.0.0
peerDependenciesMeta:
ajv:
optional: true
ajv-keywords@3.5.2: ajv-keywords@3.5.2:
resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==}
peerDependencies: peerDependencies:
@ -2504,6 +2512,9 @@ packages:
resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==}
engines: {node: '>= 4.0.0'} engines: {node: '>= 4.0.0'}
atomically@2.1.1:
resolution: {integrity: sha512-P4w9o2dqARji6P7MHprklbfiArZAWvo07yW7qs3pdljb3BWr12FIB7W+p0zJiuiVsUpRO0iZn1kFFcpPegg0tQ==}
author-regex@1.0.0: author-regex@1.0.0:
resolution: {integrity: sha512-KbWgR8wOYRAPekEmMXrYYdc7BRyhn2Ftk7KWfMUnQ43hFdojWEFRxhhRUm3/OFEdPa1r0KAvTTg9YQK57xTe0g==} resolution: {integrity: sha512-KbWgR8wOYRAPekEmMXrYYdc7BRyhn2Ftk7KWfMUnQ43hFdojWEFRxhhRUm3/OFEdPa1r0KAvTTg9YQK57xTe0g==}
engines: {node: '>=0.8'} engines: {node: '>=0.8'}
@ -2685,9 +2696,6 @@ packages:
character-reference-invalid@2.0.1: character-reference-invalid@2.0.1:
resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==}
chownr@1.1.4:
resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==}
chownr@3.0.0: chownr@3.0.0:
resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==}
engines: {node: '>=18'} engines: {node: '>=18'}
@ -2818,6 +2826,10 @@ packages:
engines: {node: '>=18'} engines: {node: '>=18'}
hasBin: true hasBin: true
conf@15.1.0:
resolution: {integrity: sha512-Uy5YN9KEu0WWDaZAVJ5FAmZoaJt9rdK6kH+utItPyGsCqCgaTKkrmZx3zoE0/3q6S3bcp3Ihkk+ZqPxWxFK5og==}
engines: {node: '>=20'}
content-disposition@0.5.2: content-disposition@0.5.2:
resolution: {integrity: sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==} resolution: {integrity: sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==}
engines: {node: '>= 0.6'} engines: {node: '>= 0.6'}
@ -3054,6 +3066,10 @@ packages:
dayjs@1.11.19: dayjs@1.11.19:
resolution: {integrity: sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==} resolution: {integrity: sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==}
debounce-fn@6.0.0:
resolution: {integrity: sha512-rBMW+F2TXryBwB54Q0d8drNEI+TfoS9JpNTAoVpukbWEhjXQq4rySFYLaqXMFXwdv61Zb2OHtj5bviSoimqxRQ==}
engines: {node: '>=18'}
debug@2.6.9: debug@2.6.9:
resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
peerDependencies: peerDependencies:
@ -3183,6 +3199,10 @@ packages:
dot-case@3.0.4: dot-case@3.0.4:
resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==}
dot-prop@10.1.0:
resolution: {integrity: sha512-MVUtAugQMOff5RnBy2d9N31iG0lNwg1qAoAOn7pOK5wf94WIaE3My2p3uwTQuvS2AcqchkcR3bHByjaM0mmi7Q==}
engines: {node: '>=20'}
dotenv-expand@11.0.7: dotenv-expand@11.0.7:
resolution: {integrity: sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==} resolution: {integrity: sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==}
engines: {node: '>=12'} engines: {node: '>=12'}
@ -3227,6 +3247,10 @@ packages:
electron-publish@26.6.0: electron-publish@26.6.0:
resolution: {integrity: sha512-LsyHMMqbvJ2vsOvuWJ19OezgF2ANdCiHpIucDHNiLhuI+/F3eW98ouzWSRmXXi82ZOPZXC07jnIravY4YYwCLQ==} resolution: {integrity: sha512-LsyHMMqbvJ2vsOvuWJ19OezgF2ANdCiHpIucDHNiLhuI+/F3eW98ouzWSRmXXi82ZOPZXC07jnIravY4YYwCLQ==}
electron-store@11.0.2:
resolution: {integrity: sha512-4VkNRdN+BImL2KcCi41WvAYbh6zLX5AUTi4so68yPqiItjbgTjqpEnGAqasgnG+lB6GuAyUltKwVopp6Uv+gwQ==}
engines: {node: '>=20'}
electron-to-chromium@1.5.283: electron-to-chromium@1.5.283:
resolution: {integrity: sha512-3vifjt1HgrGW/h76UEeny+adYApveS9dH2h3p57JYzBSXJIKUJAvtmIytDKjcSCt9xHfrNCFJ7gts6vkhuq++w==} resolution: {integrity: sha512-3vifjt1HgrGW/h76UEeny+adYApveS9dH2h3p57JYzBSXJIKUJAvtmIytDKjcSCt9xHfrNCFJ7gts6vkhuq++w==}
@ -3278,6 +3302,10 @@ packages:
resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==}
engines: {node: '>=6'} engines: {node: '>=6'}
env-paths@3.0.0:
resolution: {integrity: sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
err-code@2.0.3: err-code@2.0.3:
resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==}
@ -3565,10 +3593,6 @@ packages:
resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==}
engines: {node: '>=6'} engines: {node: '>=6'}
expand-template@2.0.3:
resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==}
engines: {node: '>=6'}
exponential-backoff@3.1.3: exponential-backoff@3.1.3:
resolution: {integrity: sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==} resolution: {integrity: sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==}
@ -3725,9 +3749,6 @@ packages:
resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==}
engines: {node: '>= 0.8'} engines: {node: '>= 0.8'}
fs-constants@1.0.0:
resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==}
fs-extra@10.1.0: fs-extra@10.1.0:
resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==}
engines: {node: '>=12'} engines: {node: '>=12'}
@ -3820,9 +3841,6 @@ packages:
resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
github-from-package@0.0.0:
resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==}
gl-matrix@3.4.4: gl-matrix@3.4.4:
resolution: {integrity: sha512-latSnyDNt/8zYUB6VIJ6PCh2jBjJX6gnDsoCZ7LyW7GkqrD51EWwa9qCoGixj8YqBtETQK/xY7OmpTF8xz1DdQ==} resolution: {integrity: sha512-latSnyDNt/8zYUB6VIJ6PCh2jBjJX6gnDsoCZ7LyW7GkqrD51EWwa9qCoGixj8YqBtETQK/xY7OmpTF8xz1DdQ==}
@ -4256,6 +4274,9 @@ packages:
json-schema-traverse@1.0.0: json-schema-traverse@1.0.0:
resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
json-schema-typed@8.0.2:
resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==}
json-stable-stringify-without-jsonify@1.0.1: json-stable-stringify-without-jsonify@1.0.1:
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
@ -4291,9 +4312,6 @@ packages:
keycloak-js@26.2.2: keycloak-js@26.2.2:
resolution: {integrity: sha512-ug7pNZ1xNkd7PPkerOJCEU2VnUhS7CYStDOCFJgqCNQ64h53ppxaKrh4iXH0xM8hFu5b1W6e6lsyYWqBMvaQFg==} resolution: {integrity: sha512-ug7pNZ1xNkd7PPkerOJCEU2VnUhS7CYStDOCFJgqCNQ64h53ppxaKrh4iXH0xM8hFu5b1W6e6lsyYWqBMvaQFg==}
keytar@7.9.0:
resolution: {integrity: sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==}
keyv@4.5.4: keyv@4.5.4:
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
@ -4620,6 +4638,10 @@ packages:
resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
engines: {node: '>=6'} engines: {node: '>=6'}
mimic-function@5.0.1:
resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==}
engines: {node: '>=18'}
mimic-response@1.0.1: mimic-response@1.0.1:
resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==}
engines: {node: '>=4'} engines: {node: '>=4'}
@ -4687,9 +4709,6 @@ packages:
resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==}
engines: {node: '>= 18'} engines: {node: '>= 18'}
mkdirp-classic@0.5.3:
resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==}
mkdirp@0.5.6: mkdirp@0.5.6:
resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==}
hasBin: true hasBin: true
@ -4729,9 +4748,6 @@ packages:
nanopop@2.3.0: nanopop@2.3.0:
resolution: {integrity: sha512-fzN+T2K7/Ah25XU02MJkPZ5q4Tj5FpjmIYq4rvoHX4yb16HzFdCO6JxFFn5Y/oBhQ8no8fUZavnyIv9/+xkBBw==} resolution: {integrity: sha512-fzN+T2K7/Ah25XU02MJkPZ5q4Tj5FpjmIYq4rvoHX4yb16HzFdCO6JxFFn5Y/oBhQ8no8fUZavnyIv9/+xkBBw==}
napi-build-utils@2.0.0:
resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==}
natural-compare@1.4.0: natural-compare@1.4.0:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
@ -4749,10 +4765,6 @@ packages:
no-case@3.0.4: no-case@3.0.4:
resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==}
node-abi@3.87.0:
resolution: {integrity: sha512-+CGM1L1CgmtheLcBuleyYOn7NWPVu0s0EJH2C4puxgEZb9h8QpR9G2dBfZJOAUhi7VQxuBPMd0hiISWcTyiYyQ==}
engines: {node: '>=10'}
node-abi@4.26.0: node-abi@4.26.0:
resolution: {integrity: sha512-8QwIZqikRvDIkXS2S93LjzhsSPJuIbfaMETWH+Bx8oOT9Sa9UsUtBFQlc3gBNd1+QINjaTloitXr1W3dQLi9Iw==} resolution: {integrity: sha512-8QwIZqikRvDIkXS2S93LjzhsSPJuIbfaMETWH+Bx8oOT9Sa9UsUtBFQlc3gBNd1+QINjaTloitXr1W3dQLi9Iw==}
engines: {node: '>=22.12.0'} engines: {node: '>=22.12.0'}
@ -4760,9 +4772,6 @@ packages:
node-addon-api@1.7.2: node-addon-api@1.7.2:
resolution: {integrity: sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==} resolution: {integrity: sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==}
node-addon-api@4.3.0:
resolution: {integrity: sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==}
node-api-version@0.2.1: node-api-version@0.2.1:
resolution: {integrity: sha512-2xP/IGGMmmSQpI1+O/k72jF/ykvZ89JeuKX3TLJAYPDVLUalrshrLHkeVcCCZqG/eEa635cr8IBYzgnDvM2O8Q==} resolution: {integrity: sha512-2xP/IGGMmmSQpI1+O/k72jF/ykvZ89JeuKX3TLJAYPDVLUalrshrLHkeVcCCZqG/eEa635cr8IBYzgnDvM2O8Q==}
@ -5038,11 +5047,6 @@ packages:
engines: {node: '>=14.0.0'} engines: {node: '>=14.0.0'}
hasBin: true hasBin: true
prebuild-install@7.1.3:
resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==}
engines: {node: '>=10'}
hasBin: true
prelude-ls@1.2.1: prelude-ls@1.2.1:
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
engines: {node: '>= 0.8.0'} engines: {node: '>= 0.8.0'}
@ -5784,12 +5788,6 @@ packages:
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
engines: {node: '>=14'} engines: {node: '>=14'}
simple-concat@1.0.1:
resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==}
simple-get@4.0.1:
resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==}
simple-swizzle@0.2.4: simple-swizzle@0.2.4:
resolution: {integrity: sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==} resolution: {integrity: sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==}
@ -5977,6 +5975,12 @@ packages:
resolution: {integrity: sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==} resolution: {integrity: sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
stubborn-fs@2.0.0:
resolution: {integrity: sha512-Y0AvSwDw8y+nlSNFXMm2g6L51rBGdAQT20J3YSOqxC53Lo3bjWRtr2BKcfYoAf352WYpsZSTURrA0tqhfgudPA==}
stubborn-utils@1.0.2:
resolution: {integrity: sha512-zOh9jPYI+xrNOyisSelgym4tolKTJCQd5GBhK0+0xJvcYDcwlOoxF/rnFKQ2KRZknXSG9jWAp66fwP6AxN9STg==}
style-mod@4.1.3: style-mod@4.1.3:
resolution: {integrity: sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ==} resolution: {integrity: sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ==}
@ -6045,17 +6049,14 @@ packages:
resolution: {integrity: sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==} resolution: {integrity: sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==}
engines: {node: ^14.18.0 || >=16.0.0} engines: {node: ^14.18.0 || >=16.0.0}
tagged-tag@1.0.0:
resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==}
engines: {node: '>=20'}
tapable@2.3.0: tapable@2.3.0:
resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==}
engines: {node: '>=6'} engines: {node: '>=6'}
tar-fs@2.1.4:
resolution: {integrity: sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==}
tar-stream@2.2.0:
resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==}
engines: {node: '>=6'}
tar@7.5.7: tar@7.5.7:
resolution: {integrity: sha512-fov56fJiRuThVFXD6o6/Q354S7pnWMJIVlDBYijsTNx6jKSE4pvrDTs6lUnmGvNyfJwFQQwWy3owKz1ucIhveQ==} resolution: {integrity: sha512-fov56fJiRuThVFXD6o6/Q354S7pnWMJIVlDBYijsTNx6jKSE4pvrDTs6lUnmGvNyfJwFQQwWy3owKz1ucIhveQ==}
engines: {node: '>=18'} engines: {node: '>=18'}
@ -6164,9 +6165,6 @@ packages:
tsparticles@3.9.1: tsparticles@3.9.1:
resolution: {integrity: sha512-Y780IGSL4qjkZj7+fI92PV/cziHqLR/s6nnYri4K6vH3NQRmDK5D6pfskDO8T4Y96ChCWHY3uxPtOb/hKQ83Qg==} resolution: {integrity: sha512-Y780IGSL4qjkZj7+fI92PV/cziHqLR/s6nnYri4K6vH3NQRmDK5D6pfskDO8T4Y96ChCWHY3uxPtOb/hKQ83Qg==}
tunnel-agent@0.6.0:
resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==}
type-check@0.4.0: type-check@0.4.0:
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
engines: {node: '>= 0.8.0'} engines: {node: '>= 0.8.0'}
@ -6187,6 +6185,10 @@ packages:
resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==}
engines: {node: '>=12.20'} engines: {node: '>=12.20'}
type-fest@5.7.0:
resolution: {integrity: sha512-1URUxUqfHFM1c+zfSPsa3gnkO7Aq21qyH75SIduNYz4SzY964rn1X2vCMQaHSHhktiw+0kPa2iyb6PUpXqB6Vg==}
engines: {node: '>=20'}
type-is@2.0.1: type-is@2.0.1:
resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==}
engines: {node: '>= 0.6'} engines: {node: '>= 0.6'}
@ -6218,6 +6220,10 @@ packages:
ufo@1.6.3: ufo@1.6.3:
resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==}
uint8array-extras@1.5.0:
resolution: {integrity: sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==}
engines: {node: '>=18'}
unbox-primitive@1.1.0: unbox-primitive@1.1.0:
resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@ -6415,6 +6421,9 @@ packages:
webpack-cli: webpack-cli:
optional: true optional: true
when-exit@2.1.5:
resolution: {integrity: sha512-VGkKJ564kzt6Ms1dbgPP/yuIoQCrsFAnRbptpC5wOEsDaNsbCB2bnfnaA8i/vRs5tjUSEOtIuvl9/MyVsvQZCg==}
which-boxed-primitive@1.1.1: which-boxed-primitive@1.1.1:
resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@ -9052,6 +9061,10 @@ snapshots:
optionalDependencies: optionalDependencies:
ajv: 8.17.1 ajv: 8.17.1
ajv-formats@3.0.1(ajv@8.17.1):
optionalDependencies:
ajv: 8.17.1
ajv-keywords@3.5.2(ajv@6.12.6): ajv-keywords@3.5.2(ajv@6.12.6):
dependencies: dependencies:
ajv: 6.12.6 ajv: 6.12.6
@ -9317,6 +9330,11 @@ snapshots:
at-least-node@1.0.0: {} at-least-node@1.0.0: {}
atomically@2.1.1:
dependencies:
stubborn-fs: 2.0.0
when-exit: 2.1.5
author-regex@1.0.0: {} author-regex@1.0.0: {}
available-typed-arrays@1.0.7: available-typed-arrays@1.0.7:
@ -9542,8 +9560,6 @@ snapshots:
character-reference-invalid@2.0.1: {} character-reference-invalid@2.0.1: {}
chownr@1.1.4: {}
chownr@3.0.0: {} chownr@3.0.0: {}
chrome-trace-event@1.0.4: {} chrome-trace-event@1.0.4: {}
@ -9669,6 +9685,18 @@ snapshots:
tree-kill: 1.2.2 tree-kill: 1.2.2
yargs: 17.7.2 yargs: 17.7.2
conf@15.1.0:
dependencies:
ajv: 8.17.1
ajv-formats: 3.0.1(ajv@8.17.1)
atomically: 2.1.1
debounce-fn: 6.0.0
dot-prop: 10.1.0
env-paths: 3.0.0
json-schema-typed: 8.0.2
semver: 7.7.3
uint8array-extras: 1.5.0
content-disposition@0.5.2: {} content-disposition@0.5.2: {}
content-disposition@1.0.1: {} content-disposition@1.0.1: {}
@ -9903,6 +9931,10 @@ snapshots:
dayjs@1.11.19: {} dayjs@1.11.19: {}
debounce-fn@6.0.0:
dependencies:
mimic-function: 5.0.1
debug@2.6.9: debug@2.6.9:
dependencies: dependencies:
ms: 2.0.0 ms: 2.0.0
@ -10036,6 +10068,10 @@ snapshots:
no-case: 3.0.4 no-case: 3.0.4
tslib: 2.8.1 tslib: 2.8.1
dot-prop@10.1.0:
dependencies:
type-fest: 5.7.0
dotenv-expand@11.0.7: dotenv-expand@11.0.7:
dependencies: dependencies:
dotenv: 16.6.1 dotenv: 16.6.1
@ -10120,6 +10156,11 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
electron-store@11.0.2:
dependencies:
conf: 15.1.0
type-fest: 5.7.0
electron-to-chromium@1.5.283: {} electron-to-chromium@1.5.283: {}
electron-winstaller@5.4.0: electron-winstaller@5.4.0:
@ -10182,6 +10223,8 @@ snapshots:
env-paths@2.2.1: {} env-paths@2.2.1: {}
env-paths@3.0.0: {}
err-code@2.0.3: {} err-code@2.0.3: {}
error-ex@1.3.4: error-ex@1.3.4:
@ -10670,8 +10713,6 @@ snapshots:
exit-hook@2.2.1: {} exit-hook@2.2.1: {}
expand-template@2.0.3: {}
exponential-backoff@3.1.3: {} exponential-backoff@3.1.3: {}
express@5.2.1: express@5.2.1:
@ -10855,8 +10896,6 @@ snapshots:
fresh@2.0.0: {} fresh@2.0.0: {}
fs-constants@1.0.0: {}
fs-extra@10.1.0: fs-extra@10.1.0:
dependencies: dependencies:
graceful-fs: 4.2.11 graceful-fs: 4.2.11
@ -10975,8 +11014,6 @@ snapshots:
es-errors: 1.3.0 es-errors: 1.3.0
get-intrinsic: 1.3.0 get-intrinsic: 1.3.0
github-from-package@0.0.0: {}
gl-matrix@3.4.4: {} gl-matrix@3.4.4: {}
glob-parent@5.1.2: glob-parent@5.1.2:
@ -11419,6 +11456,8 @@ snapshots:
json-schema-traverse@1.0.0: {} json-schema-traverse@1.0.0: {}
json-schema-typed@8.0.2: {}
json-stable-stringify-without-jsonify@1.0.1: {} json-stable-stringify-without-jsonify@1.0.1: {}
json-stringify-safe@5.0.1: json-stringify-safe@5.0.1:
@ -11455,11 +11494,6 @@ snapshots:
keycloak-js@26.2.2: {} keycloak-js@26.2.2: {}
keytar@7.9.0:
dependencies:
node-addon-api: 4.3.0
prebuild-install: 7.1.3
keyv@4.5.4: keyv@4.5.4:
dependencies: dependencies:
json-buffer: 3.0.1 json-buffer: 3.0.1
@ -11993,6 +12027,8 @@ snapshots:
mimic-fn@2.1.0: {} mimic-fn@2.1.0: {}
mimic-function@5.0.1: {}
mimic-response@1.0.1: {} mimic-response@1.0.1: {}
mimic-response@3.1.0: {} mimic-response@3.1.0: {}
@ -12070,8 +12106,6 @@ snapshots:
dependencies: dependencies:
minipass: 7.1.2 minipass: 7.1.2
mkdirp-classic@0.5.3: {}
mkdirp@0.5.6: mkdirp@0.5.6:
dependencies: dependencies:
minimist: 1.2.8 minimist: 1.2.8
@ -12107,8 +12141,6 @@ snapshots:
nanopop@2.3.0: {} nanopop@2.3.0: {}
napi-build-utils@2.0.0: {}
natural-compare@1.4.0: {} natural-compare@1.4.0: {}
negotiator@0.6.4: {} negotiator@0.6.4: {}
@ -12122,10 +12154,6 @@ snapshots:
lower-case: 2.0.2 lower-case: 2.0.2
tslib: 2.8.1 tslib: 2.8.1
node-abi@3.87.0:
dependencies:
semver: 7.7.3
node-abi@4.26.0: node-abi@4.26.0:
dependencies: dependencies:
semver: 7.7.3 semver: 7.7.3
@ -12133,8 +12161,6 @@ snapshots:
node-addon-api@1.7.2: node-addon-api@1.7.2:
optional: true optional: true
node-addon-api@4.3.0: {}
node-api-version@0.2.1: node-api-version@0.2.1:
dependencies: dependencies:
semver: 7.7.3 semver: 7.7.3
@ -12425,21 +12451,6 @@ snapshots:
commander: 9.5.0 commander: 9.5.0
optional: true optional: true
prebuild-install@7.1.3:
dependencies:
detect-libc: 2.1.2
expand-template: 2.0.3
github-from-package: 0.0.0
minimist: 1.2.8
mkdirp-classic: 0.5.3
napi-build-utils: 2.0.0
node-abi: 3.87.0
pump: 3.0.3
rc: 1.2.8
simple-get: 4.0.1
tar-fs: 2.1.4
tunnel-agent: 0.6.0
prelude-ls@1.2.1: {} prelude-ls@1.2.1: {}
prettier-eslint@16.4.2(typescript@5.9.3): prettier-eslint@16.4.2(typescript@5.9.3):
@ -13461,14 +13472,6 @@ snapshots:
signal-exit@4.1.0: {} signal-exit@4.1.0: {}
simple-concat@1.0.1: {}
simple-get@4.0.1:
dependencies:
decompress-response: 6.0.0
once: 1.4.0
simple-concat: 1.0.1
simple-swizzle@0.2.4: simple-swizzle@0.2.4:
dependencies: dependencies:
is-arrayish: 0.3.4 is-arrayish: 0.3.4
@ -13703,6 +13706,12 @@ snapshots:
dependencies: dependencies:
escape-string-regexp: 1.0.5 escape-string-regexp: 1.0.5
stubborn-fs@2.0.0:
dependencies:
stubborn-utils: 1.0.2
stubborn-utils@1.0.2: {}
style-mod@4.1.3: {} style-mod@4.1.3: {}
style-to-js@1.1.21: style-to-js@1.1.21:
@ -13782,23 +13791,10 @@ snapshots:
dependencies: dependencies:
'@pkgr/core': 0.2.9 '@pkgr/core': 0.2.9
tagged-tag@1.0.0: {}
tapable@2.3.0: {} tapable@2.3.0: {}
tar-fs@2.1.4:
dependencies:
chownr: 1.1.4
mkdirp-classic: 0.5.3
pump: 3.0.3
tar-stream: 2.2.0
tar-stream@2.2.0:
dependencies:
bl: 4.1.0
end-of-stream: 1.4.5
fs-constants: 1.0.0
inherits: 2.0.4
readable-stream: 3.6.2
tar@7.5.7: tar@7.5.7:
dependencies: dependencies:
'@isaacs/fs-minipass': 4.0.1 '@isaacs/fs-minipass': 4.0.1
@ -13915,10 +13911,6 @@ snapshots:
'@tsparticles/updater-twinkle': 3.9.1 '@tsparticles/updater-twinkle': 3.9.1
'@tsparticles/updater-wobble': 3.9.1 '@tsparticles/updater-wobble': 3.9.1
tunnel-agent@0.6.0:
dependencies:
safe-buffer: 5.2.1
type-check@0.4.0: type-check@0.4.0:
dependencies: dependencies:
prelude-ls: 1.2.1 prelude-ls: 1.2.1
@ -13932,6 +13924,10 @@ snapshots:
type-fest@2.19.0: {} type-fest@2.19.0: {}
type-fest@5.7.0:
dependencies:
tagged-tag: 1.0.0
type-is@2.0.1: type-is@2.0.1:
dependencies: dependencies:
content-type: 1.0.5 content-type: 1.0.5
@ -13977,6 +13973,8 @@ snapshots:
ufo@1.6.3: {} ufo@1.6.3: {}
uint8array-extras@1.5.0: {}
unbox-primitive@1.1.0: unbox-primitive@1.1.0:
dependencies: dependencies:
call-bound: 1.0.4 call-bound: 1.0.4
@ -14203,6 +14201,8 @@ snapshots:
- esbuild - esbuild
- uglify-js - uglify-js
when-exit@2.1.5: {}
which-boxed-primitive@1.1.1: which-boxed-primitive@1.1.1:
dependencies: dependencies:
is-bigint: 1.1.0 is-bigint: 1.1.0

View File

@ -2,7 +2,6 @@ allowBuilds:
electron: true electron: true
esbuild: true esbuild: true
sharp: true sharp: true
keytar: true
workerd: true workerd: true
core-js: true core-js: true
electron-winstaller: true electron-winstaller: true

View File

@ -1,5 +1,5 @@
import { app, ipcMain, shell, globalShortcut } from 'electron' import { app, ipcMain, shell, globalShortcut, safeStorage } from 'electron'
import { createRequire } from 'module' import Store from 'electron-store'
import { import {
registerGlobalShortcuts, registerGlobalShortcuts,
setupSpotlightIPC setupSpotlightIPC
@ -13,21 +13,60 @@ import {
handleDeepLinkFromArgv handleDeepLinkFromArgv
} from './mainWindow.js' } from './mainWindow.js'
// --- Keytar-backed auth session storage (main process) --- // --- Auth session storage (main process) ---
const require = createRequire(import.meta.url) const authStore = new Store({
let keytar = null name: 'auth-session'
try { })
// keytar is a native module; in some dev environments it may not be built yet. const AUTH_SESSION_KEY = 'authSession'
keytar = require('keytar')
} catch (e) { const serializeAuthSession = (session) => {
console.warn( const sessionJson = JSON.stringify(session)
'[keytar] Not available; auth session persistence will be disabled.',
e?.message || e if (safeStorage.isEncryptionAvailable()) {
) const encrypted = safeStorage.encryptString(sessionJson).toString('base64')
return {
encrypted: true,
value: encrypted
}
}
return {
encrypted: false,
value: sessionJson
}
} }
const KEYTAR_SERVICE = app.name || 'Farm Control' const deserializeAuthSession = (storedValue) => {
const KEYTAR_ACCOUNT = 'authSession' if (!storedValue) return null
if (typeof storedValue === 'object' && storedValue.encrypted === true) {
if (!safeStorage.isEncryptionAvailable()) {
console.warn(
'[auth-session] Encrypted auth session exists but encryption is unavailable on this system.'
)
return null
}
const decrypted = safeStorage.decryptString(
Buffer.from(storedValue.value, 'base64')
)
return JSON.parse(decrypted)
}
if (typeof storedValue === 'object' && typeof storedValue.value === 'string') {
return JSON.parse(storedValue.value)
}
if (typeof storedValue === 'string') {
return JSON.parse(storedValue)
}
// Legacy safety net if the object shape already matches the session structure.
if (typeof storedValue === 'object' && storedValue.token) {
return storedValue
}
return null
}
const gotTheLock = setupSingleInstanceLock(app) const gotTheLock = setupSingleInstanceLock(app)
@ -56,38 +95,31 @@ ipcMain.handle('os-info', () => {
ipcMain.handle('auth-session-get', async () => { ipcMain.handle('auth-session-get', async () => {
try { try {
if (!keytar) return null const storedValue = authStore.get(AUTH_SESSION_KEY)
const raw = await keytar.getPassword(KEYTAR_SERVICE, KEYTAR_ACCOUNT) return deserializeAuthSession(storedValue)
if (!raw) return null
return JSON.parse(raw)
} catch (e) { } catch (e) {
console.warn('[keytar] Failed to read auth session.', e?.message || e) console.warn('[auth-session] Failed to read auth session.', e?.message || e)
return null return null
} }
}) })
ipcMain.handle('auth-session-set', async (event, session) => { ipcMain.handle('auth-session-set', async (event, session) => {
try { try {
if (!keytar) return false
if (!session || typeof session !== 'object') return false if (!session || typeof session !== 'object') return false
await keytar.setPassword( authStore.set(AUTH_SESSION_KEY, serializeAuthSession(session))
KEYTAR_SERVICE,
KEYTAR_ACCOUNT,
JSON.stringify(session)
)
return true return true
} catch (e) { } catch (e) {
console.warn('[keytar] Failed to write auth session.', e?.message || e) console.warn('[auth-session] Failed to write auth session.', e?.message || e)
return false return false
} }
}) })
ipcMain.handle('auth-session-clear', async () => { ipcMain.handle('auth-session-clear', async () => {
try { try {
if (!keytar) return false authStore.delete(AUTH_SESSION_KEY)
return await keytar.deletePassword(KEYTAR_SERVICE, KEYTAR_ACCOUNT) return true
} catch (e) { } catch (e) {
console.warn('[keytar] Failed to clear auth session.', e?.message || e) console.warn('[auth-session] Failed to clear auth session.', e?.message || e)
return false return false
} }
}) })

View File

@ -52,10 +52,10 @@ const RegenerateAppPasswordSecret = ({ id }) => {
<Flex justify='center' style={{ minWidth: '395px' }}> <Flex justify='center' style={{ minWidth: '395px' }}>
<Flex justify='center'> <Flex justify='center'>
<Flex gap='small' align='center' justify='center'> <Flex gap='small' align='center' justify='center'>
<CopyButton size='default' text={appPassword} />
<Text code style={{ fontSize: '18px' }}> <Text code style={{ fontSize: '18px' }}>
{appPassword || '••••••••••••••••••••••••••••••••'} {appPassword || '••••••••••••••••••••••••••••••••'}
</Text> </Text>
<CopyButton size='default' text={appPassword} />
<Button <Button
type='text' type='text'
loading={loading} loading={loading}

View File

@ -85,11 +85,6 @@ const HostOTP = ({ id }) => {
> >
<Flex justify='center'> <Flex justify='center'>
<Flex gap={'small'} align='center' justify='center'> <Flex gap={'small'} align='center' justify='center'>
<CopyButton
size='default'
text={hostObject?.otp}
disabled={loading}
/>
<div> <div>
<Input.OTP <Input.OTP
disabled={loading} disabled={loading}
@ -100,6 +95,11 @@ const HostOTP = ({ id }) => {
onPaste={(e) => e.preventDefault()} // prevent pasting onPaste={(e) => e.preventDefault()} // prevent pasting
/> />
</div> </div>
<CopyButton
size='default'
text={hostObject?.otp}
disabled={loading}
/>
<div style={{ margin: '0 6px 0 8px', paddingBottom: '5px' }}> <div style={{ margin: '0 6px 0 8px', paddingBottom: '5px' }}>
{loading ? ( {loading ? (
<Text> <Text>

View File

@ -131,24 +131,26 @@ const ProductSkuInfo = () => {
loading={objectFormState.loading} loading={objectFormState.loading}
ref={actionHandlerRef} ref={actionHandlerRef}
> >
<InfoCollapse <ObjectForm
title='Product SKU Information' id={productSkuId}
icon={<InfoCircleIcon />} type='productSku'
active={collapseState.info} style={{ height: '100%' }}
onToggle={(expanded) => updateCollapseState('info', expanded)} ref={objectFormRef}
collapseKey='info' onStateChange={(state) => {
setEditFormState((prev) => ({ ...prev, ...state }))
}}
> >
<ObjectForm {({ loading, isEditing, objectData }) => (
id={productSkuId} <Flex vertical gap={'large'}>
type='productSku' <InfoCollapse
style={{ height: '100%' }} title='Product SKU Information'
ref={objectFormRef} icon={<InfoCircleIcon />}
onStateChange={(state) => { active={collapseState.info}
setEditFormState((prev) => ({ ...prev, ...state })) onToggle={(expanded) =>
}} updateCollapseState('info', expanded)
> }
{({ loading, isEditing, objectData }) => ( collapseKey='info'
<> >
<ObjectInfo <ObjectInfo
loading={loading} loading={loading}
isEditing={isEditing} isEditing={isEditing}
@ -158,56 +160,60 @@ const ProductSkuInfo = () => {
parts: false parts: false
}} }}
/> />
</> </InfoCollapse>
)} <InfoCollapse
</ObjectForm> title='SKU Parts'
</InfoCollapse> icon={<PartIcon />}
active={collapseState.parts}
onToggle={(expanded) =>
updateCollapseState('parts', expanded)
}
collapseKey='parts'
>
<ObjectProperty
{...getModelProperty('productSku', 'parts')}
isEditing={isEditing}
objectData={objectData}
loading={loading}
size='medium'
/>
</InfoCollapse>
</Flex>
)}
</ObjectForm>
</ActionHandler> </ActionHandler>
<InfoCollapse <Flex vertical gap={'large'}>
title='SKU Parts' <InfoCollapse
icon={<PartIcon />} title='Notes'
active={collapseState.parts} icon={<NoteIcon />}
onToggle={(expanded) => updateCollapseState('parts', expanded)} active={collapseState.notes}
collapseKey='parts' onToggle={(expanded) => updateCollapseState('notes', expanded)}
> collapseKey='notes'
<ObjectProperty >
{...getModelProperty('productSku', 'parts')} <Card>
isEditing={objectFormState.isEditing} <NotesPanel _id={productSkuId} type='productSku' />
objectData={objectFormState.objectData} </Card>
loading={objectFormState.loading} </InfoCollapse>
size='medium' <InfoCollapse
/> title='Audit Logs'
</InfoCollapse> icon={<AuditLogIcon />}
<InfoCollapse active={collapseState.auditLogs}
title='Notes' onToggle={(expanded) =>
icon={<NoteIcon />} updateCollapseState('auditLogs', expanded)
active={collapseState.notes} }
onToggle={(expanded) => updateCollapseState('notes', expanded)} collapseKey='auditLogs'
collapseKey='notes' >
> {objectFormState.loading ? (
<Card> <InfoCollapsePlaceholder />
<NotesPanel _id={productSkuId} type='productSku' /> ) : (
</Card> <ObjectTable
</InfoCollapse> type='auditLog'
<InfoCollapse masterFilter={{ 'parent._id': productSkuId }}
title='Audit Logs' visibleColumns={{ _id: false, 'parent._id': false }}
icon={<AuditLogIcon />} />
active={collapseState.auditLogs} )}
onToggle={(expanded) => </InfoCollapse>
updateCollapseState('auditLogs', expanded) </Flex>
}
collapseKey='auditLogs'
>
{objectFormState.loading ? (
<InfoCollapsePlaceholder />
) : (
<ObjectTable
type='auditLog'
masterFilter={{ 'parent._id': productSkuId }}
visibleColumns={{ _id: false, 'parent._id': false }}
/>
)}
</InfoCollapse>
</Flex> </Flex>
</ScrollBox> </ScrollBox>
</Flex> </Flex>

View File

@ -47,11 +47,10 @@ const SetAppPassword = ({ id }) => {
<Flex justify='center' style={{ minWidth: '395px' }}> <Flex justify='center' style={{ minWidth: '395px' }}>
<Flex justify='center'> <Flex justify='center'>
<Flex gap='small' align='center' justify='center'> <Flex gap='small' align='center' justify='center'>
<CopyButton size='default' text={appPassword} />
<Text code style={{ fontSize: '18px' }}> <Text code style={{ fontSize: '18px' }}>
{appPassword || '••••••••••••••••••••••••••••••••'} {appPassword || '••••••••••••••••••••••••••••••••'}
</Text> </Text>
<CopyButton size='default' text={appPassword} />
<Button <Button
type='texts' type='texts'
loading={loading} loading={loading}

View File

@ -35,10 +35,10 @@ const ConfigureMarketplace = ({
> >
<Flex justify='center'> <Flex justify='center'>
<Flex gap='small' align='center' justify='center'> <Flex gap='small' align='center' justify='center'>
<CopyButton size='default' text={callbackUrl} />
<Text code style={{ fontSize: '14px', wordBreak: 'break-all' }}> <Text code style={{ fontSize: '14px', wordBreak: 'break-all' }}>
{callbackUrl} {callbackUrl}
</Text> </Text>
<CopyButton size='default' text={callbackUrl} />
</Flex> </Flex>
</Flex> </Flex>
<Flex justify='center'> <Flex justify='center'>

View File

@ -3,11 +3,13 @@ import { useState, useContext } from 'react'
import { Button, Dropdown, Modal } from 'antd' import { Button, Dropdown, Modal } from 'antd'
import ExcelIcon from '../../Icons/ExcelIcon' import ExcelIcon from '../../Icons/ExcelIcon'
import ODataIcon from '../../Icons/ODataIcon' import ODataIcon from '../../Icons/ODataIcon'
import RssIcon from '../../Icons/RssIcon'
import CsvIcon from '../../Icons/CsvIcon' import CsvIcon from '../../Icons/CsvIcon'
import DownloadIcon from '../../Icons/DownloadIcon' import DownloadIcon from '../../Icons/DownloadIcon'
import OpenAppIcon from '../../Icons/OpenAppIcon' import OpenAppIcon from '../../Icons/OpenAppIcon'
import ExportIcon from '../../Icons/ExportIcon' import ExportIcon from '../../Icons/ExportIcon'
import ODataURL from './ODataURL' import ODataURL from './ODataURL'
import RSSFeedURL from './RSSFeedURL'
import { ApiServerContext } from '../context/ApiServerContext' import { ApiServerContext } from '../context/ApiServerContext'
const ExportListButton = ({ const ExportListButton = ({
@ -17,6 +19,7 @@ const ExportListButton = ({
...buttonProps ...buttonProps
}) => { }) => {
const [odataModalOpen, setOdataModalOpen] = useState(false) const [odataModalOpen, setOdataModalOpen] = useState(false)
const [rssModalOpen, setRssModalOpen] = useState(false)
const [excelLoading, setExcelLoading] = useState(false) const [excelLoading, setExcelLoading] = useState(false)
const [csvLoading, setCsvLoading] = useState(false) const [csvLoading, setCsvLoading] = useState(false)
const { exportToExcel, exportToCsv } = useContext(ApiServerContext) const { exportToExcel, exportToCsv } = useContext(ApiServerContext)
@ -76,6 +79,12 @@ const ExportListButton = ({
label: 'OData Connection', label: 'OData Connection',
icon: <ODataIcon />, icon: <ODataIcon />,
onClick: () => setOdataModalOpen(true) onClick: () => setOdataModalOpen(true)
},
{
key: 'rss',
label: 'RSS Feed Connection',
icon: <RssIcon />,
onClick: () => setRssModalOpen(true)
} }
] ]
@ -103,6 +112,15 @@ const ExportListButton = ({
> >
<ODataURL objectType={objectType} /> <ODataURL objectType={objectType} />
</Modal> </Modal>
<Modal
open={rssModalOpen}
destroyOnClose
width={750}
onCancel={() => setRssModalOpen(false)}
footer={null}
>
<RSSFeedURL objectType={objectType} />
</Modal>
</> </>
) )
} }

View File

@ -26,10 +26,10 @@ const ODataURL = ({ objectType }) => {
<Flex justify='center' style={{ minWidth: '395px' }}> <Flex justify='center' style={{ minWidth: '395px' }}>
<Flex justify='center'> <Flex justify='center'>
<Flex gap='small' align='center' justify='center'> <Flex gap='small' align='center' justify='center'>
<CopyButton size='default' text={odataUrl} />
<Text code style={{ fontSize: '14px', wordBreak: 'break-all' }}> <Text code style={{ fontSize: '14px', wordBreak: 'break-all' }}>
{odataUrl} {odataUrl}
</Text> </Text>
<CopyButton size='default' text={odataUrl} />
</Flex> </Flex>
</Flex> </Flex>
</Flex> </Flex>

View File

@ -259,6 +259,7 @@ const ObjectChildTable = ({
const currentItems = Array.isArray(itemsSource) ? itemsSource : [] const currentItems = Array.isArray(itemsSource) ? itemsSource : []
const newItems = [...currentItems, newItem] const newItems = [...currentItems, newItem]
console.log('newItems', newItems)
if (typeof onChange === 'function') { if (typeof onChange === 'function') {
onChange(newItems) onChange(newItems)
} }

View File

@ -0,0 +1,50 @@
import PropTypes from 'prop-types'
import { useContext } from 'react'
import { Result, Typography, Flex } from 'antd'
import CopyButton from './CopyButton'
import RssIcon from '../../Icons/RssIcon'
import config from '../../../config'
import { AuthContext } from '../context/AuthContext'
const { Text } = Typography
const RSSFeedURL = ({ objectType }) => {
const { userProfile } = useContext(AuthContext)
const baseUrl = config.backendUrl?.replace(/\/$/, '') || ''
const feedUsername = encodeURIComponent(userProfile?.username || 'USERNAME')
const feedPassword = 'APP_PASSWORD'
const rssUrl = `${baseUrl}/rss/${objectType}?u=${feedUsername}&p=${feedPassword}`
return (
<Flex vertical align='center'>
<Result
title='RSS Feed Connection'
subTitle={
<Text>
Use this URL to subscribe from RSS readers or automation tools. An
app password is required and can be configured in your user
settings. Use your app password, not your account password.
</Text>
}
icon={<RssIcon />}
>
<Flex justify='center' style={{ minWidth: '395px' }}>
<Flex justify='center'>
<Flex gap='small' align='center' justify='center'>
<Text code style={{ fontSize: '14px', wordBreak: 'break-all' }}>
{rssUrl}
</Text>
<CopyButton size='default' text={rssUrl} />
</Flex>
</Flex>
</Flex>
</Result>
</Flex>
)
}
RSSFeedURL.propTypes = {
objectType: PropTypes.string.isRequired
}
export default RSSFeedURL

View File

@ -162,7 +162,7 @@ const AuthProvider = ({ children }) => {
} }
}, [messageApi, isElectron]) }, [messageApi, isElectron])
// Read token from cookies (web) or keytar (electron) if present // Read token from cookies (web) or electron session storage if present
useEffect(() => { useEffect(() => {
let cancelled = false let cancelled = false
@ -432,7 +432,7 @@ const AuthProvider = ({ children }) => {
setUserProfile(nextUser) setUserProfile(nextUser)
setAuthenticated(true) setAuthenticated(true)
// Persist session (cookies on web, keytar on electron) // Persist session (cookies on web, electron storage on desktop)
const persisted = await persistSession({ const persisted = await persistSession({
token: nextToken, token: nextToken,
expiresAt: nextExpiresAt, expiresAt: nextExpiresAt,

View File

@ -0,0 +1,6 @@
import Icon from '@ant-design/icons'
import CustomIconSvg from '../../../assets/icons/rssicon.svg?react'
const RssIcon = (props) => <Icon component={CustomIconSvg} {...props} />
export default RssIcon

View File

@ -332,15 +332,28 @@ export const ProductSku = {
name: 'parts', name: 'parts',
label: 'Parts', label: 'Parts',
type: 'objectChildren', type: 'objectChildren',
objectType: 'partSku', size: 'medium',
properties: [ properties: [
{
name: 'part',
label: 'Part',
type: 'object',
objectType: 'part',
required: true,
showHyperlink: true
},
{ {
name: 'partSku', name: 'partSku',
label: 'Part SKU', label: 'Part SKU',
type: 'object', type: 'object',
objectType: 'partSku', objectType: 'partSku',
required: true, required: true,
showHyperlink: true showHyperlink: true,
masterFilter: (objectData) => {
const partId = objectData?.part?._id
if (partId == null) return {}
return { part: partId }
}
}, },
{ {
name: 'quantity', name: 'quantity',