Compare commits
1 Commits
main
...
electrobun
| Author | SHA1 | Date | |
|---|---|---|---|
| 550f0eca06 |
2
.gitignore
vendored
@ -28,5 +28,3 @@ yarn-error.log*
|
|||||||
/design_files/*.af~lock~
|
/design_files/*.af~lock~
|
||||||
|
|
||||||
stats.html
|
stats.html
|
||||||
|
|
||||||
test-results.xml
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
<?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.913777,0,0,0.913777,-11.957695,-8.458487)">
|
|
||||||
<path d="M56.866,48.187C56.775,48.817 56.734,49.463 56.734,50.118C56.734,52.243 57.143,54.279 57.906,56.141C54.515,53.972 49.815,52.352 44,52.352C31.125,52.352 23.734,60.274 23.734,64.477C23.734,64.93 23.953,65.165 24.547,65.165L63.031,65.165L63.031,71.774L24.766,71.774C19.047,71.774 16.219,69.852 16.219,65.774C16.219,56.587 27.547,45.727 44,45.727C48.778,45.727 53.123,46.643 56.866,48.187ZM57.984,27.368C57.984,35.743 51.766,42.477 44,42.477C36.25,42.477 30.031,35.758 30.031,27.399C30.031,19.227 36.328,12.54 44,12.54C51.719,12.54 57.984,19.165 57.984,27.368ZM36.812,27.384C36.812,32.352 40.109,35.868 44,35.868C47.938,35.868 51.203,32.321 51.203,27.368C51.203,22.587 47.922,19.149 44,19.149C40.125,19.149 36.812,22.634 36.812,27.384Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M72.469,39.508C66.531,39.508 61.812,44.29 61.812,50.118C61.812,54.462 64.266,58.212 68.109,59.899L68.109,74.743C68.109,75.29 68.359,75.821 68.766,76.243L71.609,78.915C72.141,79.399 72.969,79.462 73.562,78.868L78.5,73.946C79.125,73.305 79.062,72.383 78.484,71.774L76.031,69.258L79.641,65.649C80.234,65.055 80.25,64.118 79.609,63.43L76.234,60.087C80.641,57.962 83.125,54.399 83.125,50.118C83.125,44.29 78.375,39.508 72.469,39.508ZM72.453,43.696C74.094,43.696 75.422,45.055 75.422,46.696C75.422,48.321 74.094,49.696 72.453,49.696C70.844,49.696 69.469,48.321 69.469,46.696C69.469,45.055 70.797,43.696 72.453,43.696Z" style="fill-rule:nonzero;"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.9 KiB |
@ -1,11 +0,0 @@
|
|||||||
<?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.865066,0,0,0.865066,3,7.501025)">
|
|
||||||
<path d="M3.656,56.641L63.359,56.641C65.406,56.641 67.047,54.906 67.047,52.891C67.047,50.813 65.422,49.125 63.359,49.125L3.656,49.125C1.609,49.125 0,50.859 0,52.891C0,54.875 1.625,56.641 3.656,56.641Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M3.656,40.297L63.359,40.297C65.406,40.297 67.047,38.563 67.047,36.547C67.047,34.453 65.422,32.781 63.359,32.781L3.656,32.781C1.609,32.781 0,34.484 0,36.547C0,38.516 1.625,40.297 3.656,40.297Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M46.469,23.891L63.359,23.938C65.406,23.953 67.047,22.188 67.047,20.172C67.047,18.11 65.422,16.438 63.359,16.422L46.469,16.375C44.422,16.36 42.812,18.094 42.812,20.125C42.812,22.094 44.438,23.891 46.469,23.891Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M46.469,7.516L63.359,7.578C65.406,7.594 67.047,5.844 67.047,3.828C67.047,1.75 65.422,0.078 63.359,0.063L46.469,0C44.422,-0.016 42.812,1.734 42.812,3.766C42.812,5.75 44.438,7.516 46.469,7.516Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M9.047,24.594C13.453,24.594 16.984,21.5 16.984,17.063C16.984,12.828 14.078,9.906 10.219,9.906C7.75,9.906 5.719,11 4.703,13.61L5.406,14.063C5.594,9.063 9.016,5.547 14.219,5.203C15.516,5.109 16.5,4.063 16.5,2.781C16.5,1.25 15.172,0.266 13.453,0.266C6.359,0.266 0.047,6.188 0.047,14.406C0.047,20.594 3.797,24.594 9.047,24.594ZM29.297,24.594C33.672,24.594 37.219,21.5 37.219,17.063C37.219,12.828 34.312,9.906 30.453,9.906C27.984,9.906 25.953,11 24.922,13.61L25.641,14.063C25.812,9.063 29.234,5.531 34.422,5.203C35.734,5.109 36.75,4.063 36.75,2.781C36.75,1.25 35.453,0.266 33.688,0.266C26.609,0.266 20.266,6.188 20.266,14.406C20.266,20.594 24.047,24.594 29.297,24.594Z" style="fill-rule:nonzero;"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 2.2 KiB |
@ -1,7 +0,0 @@
|
|||||||
<?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(1,0,0,1,12.2656,8.9375)">
|
|
||||||
<path d="M6.125,46.125L23.078,46.125C33.078,46.125 39.469,40.859 39.469,32.844C39.469,26.656 34.562,22.031 28.062,21.766L28.062,21.516C33.484,20.797 37.344,16.781 37.344,11.578C37.344,4.391 31.75,0.016 22.484,0.016L6.125,0.016C2.344,0.016 0,2.234 0,6.109L0,40.047C0,43.922 2.344,46.125 6.125,46.125ZM12.953,37.828L12.953,26.062L18.5,26.062C23.469,26.062 26.312,28.125 26.312,31.844C26.312,35.734 23.922,37.828 18.938,37.828L12.953,37.828ZM12.953,18.844L12.953,8.391L18.219,8.391C22.25,8.391 24.672,10.297 24.672,13.531C24.672,16.828 22.047,18.844 17.672,18.844L12.953,18.844Z" style="fill-rule:nonzero;"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.1 KiB |
@ -1,12 +0,0 @@
|
|||||||
<?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.865066,0,0,0.865066,3,10.731571)">
|
|
||||||
<path d="M21.156,48.391L63.359,48.391C65.406,48.391 67.047,46.656 67.047,44.625C67.047,42.547 65.422,40.875 63.359,40.875L21.156,40.875C19.078,40.875 17.484,42.594 17.484,44.625C17.484,46.609 19.109,48.391 21.156,48.391Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M5.203,49.828C8.078,49.828 10.422,47.484 10.422,44.625C10.422,41.766 8.078,39.422 5.203,39.422C2.344,39.422 0,41.766 0,44.625C0,47.484 2.344,49.828 5.203,49.828Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M21.156,28.672L63.359,28.672C65.406,28.672 67.047,26.938 67.047,24.922C67.047,22.844 65.422,21.156 63.359,21.156L21.156,21.156C19.078,21.156 17.484,22.891 17.484,24.922C17.484,26.906 19.109,28.672 21.156,28.672Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M5.203,30.125C8.078,30.125 10.422,27.797 10.422,24.922C10.422,22.047 8.078,19.719 5.203,19.719C2.344,19.719 0,22.047 0,24.922C0,27.797 2.344,30.125 5.203,30.125Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M21.156,8.969L63.359,8.969C65.406,8.969 67.047,7.234 67.047,5.203C67.047,3.141 65.422,1.453 63.359,1.453L21.156,1.453C19.078,1.453 17.484,3.172 17.484,5.203C17.484,7.203 19.109,8.969 21.156,8.969Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M5.203,10.422C8.078,10.422 10.422,8.078 10.422,5.203C10.422,2.344 8.078,0 5.203,0C2.344,0 0,2.344 0,5.203C0,8.078 2.344,10.422 5.203,10.422Z" style="fill-rule:nonzero;"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.8 KiB |
@ -1,12 +0,0 @@
|
|||||||
<?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 12 12" 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.156042,0,0,0.156042,1.80453,0.721021)">
|
|
||||||
<rect x="0" y="0" width="53.774" height="67.661" style="fill-opacity:0;"/>
|
|
||||||
<path d="M10.149,67.641L43.438,67.641C50.137,67.641 53.586,64.135 53.586,57.41L53.586,29.058C53.586,24.717 53.028,22.725 50.308,19.954L33.894,3.284C31.282,0.616 29.111,0 25.212,0L10.149,0C3.481,0 0,3.532 0,10.257L0,57.41C0,64.161 3.455,67.641 10.149,67.641ZM10.637,61.519C7.621,61.519 6.122,59.941 6.122,57.029L6.122,10.637C6.122,7.752 7.621,6.122 10.663,6.122L23.984,6.122L23.984,23.261C23.984,27.733 26.167,29.895 30.619,29.895L47.464,29.895L47.464,57.029C47.464,59.941 45.965,61.519 42.929,61.519L10.637,61.519ZM31.198,24.496C29.903,24.496 29.384,23.945 29.384,22.656L29.384,6.973L46.613,24.496L31.198,24.496Z" style="fill-rule:nonzero;"/>
|
|
||||||
<g transform="matrix(12.808657,0,0,12.808657,-40.118025,-49.663642)">
|
|
||||||
<path d="M4.662,8.034C4.545,8.034 4.448,8.015 4.37,7.978C4.293,7.94 4.236,7.89 4.2,7.825C4.163,7.761 4.145,7.69 4.145,7.612C4.145,7.528 4.166,7.454 4.208,7.389C4.25,7.325 4.316,7.274 4.405,7.236C4.495,7.198 4.607,7.178 4.743,7.178L5.084,7.178C5.084,7.115 5.076,7.063 5.06,7.022C5.045,6.981 5.019,6.95 4.984,6.93C4.948,6.909 4.9,6.899 4.838,6.899C4.773,6.899 4.718,6.912 4.673,6.938C4.629,6.964 4.601,7.005 4.59,7.061L4.187,7.061C4.197,6.961 4.23,6.873 4.286,6.798C4.343,6.724 4.419,6.665 4.514,6.622C4.609,6.58 4.718,6.558 4.841,6.558C4.975,6.558 5.092,6.58 5.19,6.624C5.289,6.668 5.366,6.731 5.421,6.815C5.476,6.899 5.503,7.003 5.503,7.128L5.503,8L5.154,8L5.104,7.796C5.083,7.831 5.059,7.864 5.031,7.892C5.003,7.921 4.971,7.946 4.933,7.968C4.896,7.989 4.855,8.006 4.81,8.017C4.766,8.028 4.716,8.034 4.662,8.034ZM4.766,7.715C4.81,7.715 4.849,7.708 4.883,7.693C4.917,7.678 4.945,7.657 4.97,7.631C4.994,7.605 5.014,7.575 5.03,7.54C5.046,7.506 5.057,7.468 5.065,7.427L5.065,7.424L4.794,7.424C4.747,7.424 4.708,7.43 4.678,7.443C4.647,7.455 4.624,7.472 4.609,7.494C4.594,7.517 4.587,7.543 4.587,7.572C4.587,7.604 4.595,7.631 4.611,7.652C4.626,7.674 4.648,7.689 4.675,7.7C4.702,7.71 4.732,7.715 4.766,7.715Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M5.835,7.521L6.43,7.521L6.077,8.432L5.637,8.432L5.835,7.521Z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 2.6 KiB |
@ -1,17 +0,0 @@
|
|||||||
<?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.124,0,0,0.124,1.867256,1)">
|
|
||||||
<path d="M69.43,159.719C69.43,125.199 97.41,97.219 131.922,97.219L486.012,97.219L486.012,458.328C486.012,481.34 467.359,500 444.352,500L152.738,500C106.73,500 69.43,462.691 69.43,416.672L69.43,159.719Z" style="fill:rgb(38,120,43);fill-rule:nonzero;"/>
|
|
||||||
<path d="M69.43,83.328C69.43,37.309 106.73,0 152.738,0L319.371,0L319.371,166.672L152.738,166.672C106.73,166.672 69.43,203.98 69.43,250L69.43,83.328Z" style="fill:rgb(115,218,95);fill-rule:nonzero;"/>
|
|
||||||
<g transform="matrix(1.243478,0,0,1.243478,-118.330239,0)">
|
|
||||||
<path d="M332.245,0L444.34,0C467.348,0 486,18.652 486,41.66L486,125.012C486,148.02 467.348,166.672 444.34,166.672L332.245,166.672C309.237,166.672 290.585,148.02 290.585,125.012L290.585,41.66C290.585,18.652 309.237,0 332.245,0Z" style="fill:rgb(143,233,111);fill-rule:nonzero;"/>
|
|
||||||
</g>
|
|
||||||
<g transform="matrix(1.31598,0,0,1.31598,0,-144.822643)">
|
|
||||||
<path d="M45.129,236.109L177.039,236.109C201.965,236.109 222.172,256.316 222.172,281.238L222.172,413.199C222.172,438.125 201.965,458.328 177.039,458.328L45.129,458.328C20.207,458.328 0,438.125 0,413.199L0,281.238C0,256.316 20.207,236.109 45.129,236.109Z" style="fill:rgb(11,78,46);fill-rule:nonzero;"/>
|
|
||||||
<g transform="matrix(1.2548,0,0,1.2548,-33.009557,-88.471875)">
|
|
||||||
<path d="M169.48,410.711L135.23,410.711L113.73,370.238C112.961,368.82 112.371,367.699 111.961,366.871C111.609,365.988 111.219,364.98 110.809,363.859L110.461,363.859C109.93,365.281 109.43,366.43 108.961,367.309C108.488,368.199 107.93,369.289 107.281,370.59L84.98,410.699L52.68,410.699L91.441,347.121L55.34,283.719L89.141,283.719L108.25,319.852C109.02,321.328 109.672,322.629 110.199,323.75C110.789,324.809 111.379,326.078 111.969,327.559L112.32,327.559C113.141,325.852 113.789,324.488 114.27,323.488C114.801,322.488 115.512,321.16 116.391,319.512L136.211,283.738L168.422,283.738L131.789,346.172L169.488,410.719L169.48,410.711Z" style="fill:rgb(254,254,254);fill-rule:nonzero;"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 2.5 KiB |
@ -1,9 +0,0 @@
|
|||||||
<?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.760492,0,0,0.760492,9.844746,-1.023725)">
|
|
||||||
<path d="M19.578,35.125L14.438,35.125C10.359,35.125 8.062,37.422 8.062,41.5L8.062,64.734C8.062,68.828 10.359,71.125 14.438,71.125L43.828,71.125C47.906,71.125 50.203,68.828 50.203,64.734L50.203,41.5C50.203,37.422 47.906,35.125 43.828,35.125L38.672,35.125L38.672,27.062L44.266,27.062C53.234,27.062 58.266,32.062 58.266,41.047L58.266,65.188C58.266,74.156 53.234,79.188 44.266,79.188L14,79.188C5.016,79.188 0,74.156 0,65.188L0,41.047C0,32.062 5.016,27.062 14,27.062L19.578,27.062L19.578,35.125Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M32.423,14.141L32.75,18.578L32.75,49.219C32.75,51.125 31.141,52.766 29.125,52.766C27.109,52.766 25.516,51.125 25.516,49.219L25.516,18.578L25.851,14.122L29.125,9.438L32.423,14.141Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M18.172,21.328C19.078,21.328 19.938,20.953 20.547,20.297L24.375,16.234L29.125,9.438L33.891,16.234L37.703,20.297C38.312,20.953 39.156,21.328 40.062,21.328C41.703,21.328 43.188,20.094 43.188,18.328C43.188,17.406 42.859,16.734 42.234,16.109L31.984,6.281C31.047,5.359 30.109,5.031 29.125,5.031C28.156,5.031 27.234,5.359 26.266,6.281L16.031,16.109C15.422,16.734 15.062,17.406 15.062,18.328C15.062,20.094 16.531,21.328 18.172,21.328Z" style="fill-rule:nonzero;"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.7 KiB |
@ -1,13 +0,0 @@
|
|||||||
<?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.011907,-0,-0,-0.011907,-0.017623,64)">
|
|
||||||
<path d="M2168,4709C1894,4666 1703,4555 1616,4389C1580,4321 1580,4184 1616,4116C1686,3983 1795,3902 1990,3838C2374,3713 2898,3806 3075,4030C3139,4112 3155,4156 3155,4253C3155,4349 3139,4393 3075,4475C2930,4659 2521,4765 2168,4709ZM2531,4395C2672,4372 2780,4328 2829,4275C2848,4253 2848,4252 2829,4230C2762,4157 2554,4095 2373,4095C2192,4095 1984,4157 1917,4230C1898,4252 1898,4253 1917,4275C2010,4378 2296,4434 2531,4395Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M4413.328,0.003L3970,0C2805,0 2804,0 2641,56C2546.293,88.172 2456.943,133.018 2375.17,188.649L752.515,188.649C440.617,188.649 187.395,441.871 187.395,753.769L187.395,2042.949C187.395,2333.828 407.638,2573.672 690.318,2604.678C623.112,2767.055 626.105,2931.521 701,3087L731,3149L707,3196C648,3311 626,3466 653,3579L665,3631L598,3692C381,3894 287,4149 343,4391C403,4658 606,4880 958,5066C1270,5230 1637,5326 2121,5369C2228,5379 2689,5366 2814,5350C3439,5270 3943,5054 4214,4748C4509,4415 4483,4003 4148,3692L4081,3631L4093,3579C4120,3465 4098,3312 4038,3194C4014,3145 4014,3144 4033,3113C4078,3041 4100,2950 4100,2835C4100,2738.782 4090.9,2682.466 4058.642,2608.068L4625.617,2608.068C4937.515,2608.068 5190.736,2354.846 5190.736,2042.949L5190.736,753.769C5190.736,611.423 5137.993,481.298 5051,381.889L5051.021,155.223C5051.021,69.541 4981.4,0.003 4895.817,0.003L4413.328,0.003ZM1063.992,2608.068L1634.782,2608.068C1394.851,2668.367 1190.699,2752.015 1034,2856C966,2901 967,2901 960,2872C944,2809 979,2712 1045,2630C1050.866,2622.695 1057.204,2615.38 1063.992,2608.068ZM1078,3393C1025,3416 976,3438 970,3440C961,3444 960,3436 965,3411C1016,3186 1382,2969 1856,2883C2036,2850 2146,2841 2373,2841C2600,2841 2710,2850 2890,2883C3364,2969 3730,3186 3781,3411C3786,3436 3785,3444 3776,3440C3770,3438 3721,3416 3668,3393C3424,3286 3132,3213 2772,3169C2627,3151 2119,3151 1974,3169C1614,3213 1322,3286 1078,3393ZM4854.788,2042.949C4854.788,2169.432 4752.1,2272.12 4625.617,2272.12L752.515,2272.12C626.032,2272.12 523.344,2169.432 523.344,2042.949L523.344,753.769C523.344,627.286 626.032,524.597 752.515,524.597L4625.617,524.597C4752.1,524.597 4854.788,627.286 4854.788,753.769L4854.788,2042.949ZM2621,5050C1966,5103 1283,4947 897,4656C795,4579 733,4507 685,4411C650,4342 646,4324 646,4253C646,4146 685,4063 783,3960C1103,3621 1884,3416 2631,3476C3229,3524 3721,3702 3963,3960C4061,4063 4100,4146 4100,4253C4100,4324 4096,4342 4061,4411C4013,4507 3951,4579 3849,4656C3560,4873 3138,5009 2621,5050ZM3111.507,2608.068L3680.692,2608.068C3712.673,2642.169 3737.999,2677.689 3757,2715C3782,2766 3797,2857 3783,2881C3775,2896 3769,2895 3733,2870C3569.742,2759.218 3359.738,2670.745 3111.507,2608.068Z"/>
|
|
||||||
<g transform="matrix(143.743961,-0,-0,-143.743961,-3687.186324,8190.967756)">
|
|
||||||
<path d="M34.865,52.259C37.413,52.259 38.935,51.026 38.935,49.082C38.935,47.56 37.996,46.722 35.931,46.326L34.939,46.139C33.887,45.938 33.451,45.656 33.451,45.147C33.451,44.577 33.974,44.174 34.865,44.174C35.576,44.174 36.112,44.409 36.428,45.012C36.716,45.482 37.051,45.676 37.587,45.676C38.204,45.669 38.62,45.287 38.62,44.717C38.62,44.516 38.586,44.355 38.519,44.188C38.05,42.961 36.696,42.25 34.845,42.25C32.62,42.25 31.004,43.45 31.004,45.314C31.004,46.789 32.01,47.734 33.934,48.096L34.933,48.284C36.079,48.505 36.488,48.78 36.488,49.316C36.488,49.906 35.864,50.335 34.906,50.335C34.128,50.335 33.478,50.081 33.149,49.477C32.834,48.995 32.512,48.827 32.036,48.827C31.413,48.827 30.97,49.243 30.97,49.859C30.97,50.061 31.011,50.268 31.098,50.469C31.5,51.468 32.767,52.259 34.865,52.259Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M41.308,52.239C42.086,52.239 42.535,51.777 42.535,50.959L42.535,49.357L43.433,48.418L45.941,51.549C46.336,52.052 46.691,52.246 47.208,52.246C47.878,52.246 48.388,51.73 48.388,51.059C48.388,50.718 48.22,50.349 47.818,49.853L45.344,46.823L47.657,44.382C47.985,44.027 48.113,43.759 48.113,43.397C48.113,42.767 47.596,42.264 46.953,42.264C46.537,42.264 46.229,42.425 45.88,42.814L42.589,46.46L42.535,46.46L42.535,43.551C42.535,42.733 42.086,42.27 41.308,42.27C40.53,42.27 40.075,42.733 40.075,43.551L40.075,50.959C40.075,51.777 40.53,52.239 41.308,52.239Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M53.583,52.259C56.097,52.259 57.746,50.832 57.746,48.659L57.746,43.551C57.746,42.733 57.297,42.27 56.513,42.27C55.735,42.27 55.286,42.733 55.286,43.551L55.286,48.398C55.286,49.524 54.676,50.195 53.583,50.195C52.484,50.195 51.874,49.524 51.874,48.398L51.874,43.551C51.874,42.733 51.424,42.27 50.647,42.27C49.869,42.27 49.413,42.733 49.413,43.551L49.413,48.659C49.413,50.832 51.062,52.259 53.583,52.259Z" style="fill-rule:nonzero;"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 5.1 KiB |
@ -1,7 +0,0 @@
|
|||||||
<?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.889695,0,0,0.889695,3,3.004404)">
|
|
||||||
<path d="M65.191,32.59C65.191,50.56 50.592,65.181 32.59,65.181C14.621,65.181 0,50.56 0,32.59C0,14.599 14.621,0 32.59,0C50.592,0 65.191,14.599 65.191,32.59ZM24.761,42.45C22.996,42.45 21.767,43.565 21.767,45.227C21.767,46.89 22.996,48.026 24.761,48.026L40.494,48.026C42.259,48.026 43.509,46.89 43.509,45.227C43.509,43.565 42.259,42.45 40.494,42.45L24.761,42.45ZM20.339,31.642C18.552,31.642 17.323,32.777 17.323,34.44C17.323,36.144 18.552,37.249 20.339,37.249L44.937,37.249C46.703,37.249 47.931,36.144 47.931,34.44C47.931,32.777 46.703,31.642 44.937,31.642L20.339,31.642ZM16.054,20.886C14.279,20.886 13.039,22.001 13.039,23.684C13.039,25.358 14.279,26.472 16.054,26.472L49.222,26.472C50.976,26.472 52.237,25.358 52.237,23.684C52.237,22.001 50.976,20.886 49.222,20.886L16.054,20.886Z" style="fill-rule:nonzero;"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.3 KiB |
@ -1,8 +0,0 @@
|
|||||||
<?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.889695,0,0,0.889695,3,3.004404)">
|
|
||||||
<path d="M32.59,65.181C50.592,65.181 65.191,50.582 65.191,32.59C65.191,14.599 50.592,0 32.59,0C14.599,0 0,14.599 0,32.59C0,50.582 14.599,65.181 32.59,65.181ZM32.59,58.02C18.529,58.02 7.161,46.652 7.161,32.59C7.161,18.529 18.529,7.161 32.59,7.161C46.652,7.161 58.03,18.529 58.03,32.59C58.03,46.652 46.652,58.02 32.59,58.02Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M16.733,26.802L48.5,26.802C50.183,26.802 51.362,25.748 51.362,24.146C51.362,22.565 50.183,21.511 48.5,21.511L16.733,21.511C15.029,21.511 13.871,22.565 13.871,24.146C13.871,25.748 15.029,26.802 16.733,26.802ZM20.832,37.096L44.402,37.096C46.065,37.096 47.233,36.042 47.233,34.44C47.233,32.869 46.065,31.805 44.402,31.805L20.832,31.805C19.147,31.805 17.98,32.869 17.98,34.44C17.98,36.042 19.147,37.096 20.832,37.096ZM25.068,47.411L40.145,47.411C41.808,47.411 42.996,46.336 42.996,44.755C42.996,43.184 41.808,42.121 40.145,42.121L25.068,42.121C23.405,42.121 22.237,43.184 22.237,44.755C22.237,46.336 23.405,47.411 25.068,47.411Z" style="fill-rule:nonzero;"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.5 KiB |
@ -1,9 +0,0 @@
|
|||||||
<?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.929807,0,0,0.929807,1,12.754528)">
|
|
||||||
<path d="M16.503,41.397L50.239,41.397C52.648,41.397 54.536,39.324 54.536,36.987C54.536,34.578 52.671,32.569 50.239,32.569L16.503,32.569C14.094,32.569 12.212,34.626 12.212,36.987C12.212,39.276 14.118,41.397 16.503,41.397Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M10.407,25.112L56.342,25.112C58.727,25.112 60.608,23.039 60.608,20.702C60.608,18.269 58.751,16.285 56.342,16.285L10.407,16.285C8.022,16.285 6.133,18.341 6.133,20.702C6.133,22.992 8.046,25.112 10.407,25.112Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M4.267,8.827L62.414,8.827C64.823,8.827 66.68,6.755 66.68,4.417C66.68,1.984 64.847,0 62.414,0L4.267,0C1.882,0 0,2.032 0,4.417C0,6.683 1.905,8.827 4.267,8.827Z" style="fill-rule:nonzero;"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.2 KiB |
@ -1,8 +0,0 @@
|
|||||||
<?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.624686,0,0,0.624686,3,17.237995)">
|
|
||||||
<path d="M45.17,47.212C46.58,47.212 47.578,46.42 47.578,45.039C47.578,44.432 47.455,44.033 47.022,43.038C43.627,36.904 41.807,30.56 41.807,23.653C41.807,16.937 43.541,10.39 47.022,4.224C47.455,3.24 47.578,2.84 47.578,2.233C47.578,0.895 46.58,0.05 45.17,0.05C43.622,0.05 42.412,0.807 41.094,2.698C36.763,8.399 34.637,15.598 34.637,23.632C34.637,31.696 36.75,38.726 41.094,44.574C42.402,46.475 43.622,47.212 45.17,47.212ZM53.441,39.915C54.789,39.915 55.627,39.472 56.736,37.85L63.381,28.189L63.526,28.189L70.367,38.036C71.337,39.448 72.177,39.915 73.434,39.915C75.47,39.915 76.876,38.574 76.876,36.677C76.876,35.855 76.63,35.133 76.075,34.383L68.175,23.647L76.006,13.227C76.629,12.367 76.927,11.646 76.927,10.722C76.927,8.851 75.474,7.596 73.587,7.596C72.104,7.596 71.3,8.297 70.379,9.72L64.033,19.158L63.877,19.158L57.501,9.689C56.548,8.256 55.66,7.596 54.075,7.596C52.07,7.596 50.568,9.08 50.568,10.866C50.568,11.932 50.899,12.683 51.435,13.403L59.08,23.63L51.105,34.459C50.429,35.36 50.226,36.071 50.226,36.964C50.226,38.669 51.625,39.915 53.441,39.915ZM82.304,47.212C83.862,47.212 85.062,46.465 86.38,44.574C90.754,38.736 92.847,31.696 92.847,23.632C92.847,15.598 90.682,8.419 86.38,2.698C85.072,0.797 83.862,0.05 82.304,0.05C80.894,0.05 79.896,0.895 79.896,2.233C79.896,2.84 80.029,3.24 80.452,4.224C83.933,10.39 85.667,16.937 85.667,23.653C85.667,30.56 83.848,36.904 80.452,43.038C80.029,44.033 79.896,44.432 79.896,45.039C79.896,46.377 80.894,47.212 82.304,47.212Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M5.252,47.17C12.053,47.17 15.203,44.455 16.783,37.027L20.127,21.046L25.664,21.046C27.685,21.046 29.099,19.888 29.099,17.909C29.099,16.108 27.887,15.025 26.141,15.025L21.395,15.025L22.161,11.302C22.935,7.691 24.066,6.295 27.165,6.295C27.697,6.295 28.187,6.263 28.56,6.222C30.37,5.986 31.317,5.049 31.317,3.437C31.317,1.14 29.52,0.071 25.884,0.071C19.19,0.071 15.859,3.04 14.354,10.214L13.352,15.025L9.606,15.025C7.544,15.025 6.149,16.193 6.149,18.163C6.149,19.974 7.342,21.046 9.139,21.046L12.084,21.046L8.945,35.949C8.159,39.645 7.007,40.946 3.961,40.946C3.534,40.946 3.096,40.987 2.775,41.019C0.93,41.266 0,42.325 0,43.856C0,46.1 1.765,47.17 5.252,47.17Z" style="fill-rule:nonzero;"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 2.7 KiB |
@ -1,7 +0,0 @@
|
|||||||
<?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(1,0,0,1,14.41405,8.929688)">
|
|
||||||
<path d="M4.047,46.125L24.406,46.125C26.797,46.125 28.438,44.75 28.438,42.391C28.438,40.094 26.859,38.719 24.422,38.719L19.062,38.719L25.797,7.438L31.156,7.438C33.547,7.438 35.172,6.062 35.172,3.719C35.172,1.406 33.594,0.016 31.172,0.016L10.75,0.016C8.328,0.016 6.734,1.406 6.734,3.719C6.734,6.062 8.375,7.438 10.766,7.438L16.125,7.438L9.391,38.719L4.031,38.719C1.594,38.719 0,40.094 0,42.391C0,44.75 1.641,46.125 4.047,46.125Z" style="fill-rule:nonzero;"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 979 B |
@ -1,8 +0,0 @@
|
|||||||
<?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.905936,0,0,0.905936,8.091803,1)">
|
|
||||||
<path d="M0,64.406C0,66.625 1.812,68.438 4.031,68.438C6.25,68.438 8.062,66.625 8.062,64.406L8.062,9.844C8.062,8.75 8.75,8.062 9.797,8.062L42.984,8.062C44.031,8.062 44.719,8.75 44.719,9.844L44.719,64.406C44.719,66.625 46.531,68.438 48.766,68.438C50.984,68.438 52.781,66.625 52.781,64.406L52.781,8.828C52.781,3.391 49.391,0 43.875,0L8.922,0C3.406,0 0,3.391 0,8.828L0,64.406Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M11.891,65.75C11.891,66.547 12.5,66.938 13.359,66.578L22.859,62.547C23.672,62.203 24.031,61.828 24.031,61.062L24.031,17.438C24.031,16.672 23.672,16.281 22.875,15.969L13.359,11.906C12.5,11.562 11.891,11.953 11.891,12.766L11.891,65.75Z" style="fill-rule:nonzero;"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.2 KiB |
@ -1,12 +0,0 @@
|
|||||||
<?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(1,0,0,1,0,-0.113382)">
|
|
||||||
<g transform="matrix(0.725404,0,0,0.725404,3.539221,11.473342)">
|
|
||||||
<path d="M43.789,56.563L11.031,56.562C3.922,56.562 0,52.672 0,45.594L0,11C0,3.922 3.906,0.031 10.516,0.031L67.422,0.031C74.547,0.031 78.469,3.922 78.469,11L78.469,39.642C76.475,37.218 73.921,35.265 71.016,33.991L71.016,11.879L54.327,26.905L60.012,32.59C57.573,32.984 55.276,33.831 53.211,35.039L49.46,31.288L45.719,34.656C43.594,36.578 41.609,37.391 39.219,37.391C36.844,37.391 34.844,36.578 32.734,34.656L28.993,31.29L11.188,49.108L11.328,49.109L43.533,49.109C43.374,50.11 43.292,51.133 43.292,52.174C43.292,53.679 43.464,55.148 43.789,56.563ZM7.453,43.594L24.132,26.915L7.453,11.906L7.453,43.594ZM12.279,7.484L36.734,29.547C37.547,30.266 38.359,30.641 39.219,30.641C40.094,30.641 40.906,30.266 41.719,29.547L66.174,7.484L12.279,7.484Z"/>
|
|
||||||
</g>
|
|
||||||
<g transform="matrix(0.692828,0,0,0.692828,-0,0.822733)">
|
|
||||||
<path d="M87.672,70C87.672,78.984 80.188,86.469 71.219,86.469C62.203,86.469 54.766,79.016 54.766,70C54.766,61 62.203,53.562 71.219,53.562C80.234,53.562 87.672,61 87.672,70ZM75.922,62.812L68.984,72.391L65.766,68.766C65.281,68.219 64.609,67.938 63.797,67.938C62.391,67.938 61.062,68.906 61.062,70.641C61.062,71.328 61.391,72.031 61.891,72.578L67.047,78.156C67.594,78.766 68.453,79 69.188,79C70.078,79 70.938,78.625 71.391,78.016L80.375,65.828C80.719,65.344 80.875,64.781 80.875,64.297C80.875,62.812 79.672,61.625 78.172,61.625C77.266,61.625 76.453,62.078 75.922,62.812Z" style="fill-rule:nonzero;"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 2.0 KiB |
@ -1,7 +0,0 @@
|
|||||||
<?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.725404,0,0,0.725404,3.539221,11.473342)">
|
|
||||||
<path d="M11.031,56.562C3.922,56.562 0,52.672 0,45.594L0,11C0,3.922 3.906,0.031 10.516,0.031L67.422,0.031C74.547,0.031 78.469,3.922 78.469,11L78.469,45.594C78.469,52.672 74.562,56.562 67.953,56.562L11.031,56.562ZM7.453,43.594L24.132,26.915L7.453,11.906L7.453,43.594ZM67.279,49.107L49.46,31.288L45.719,34.656C43.594,36.578 41.609,37.391 39.219,37.391C36.844,37.391 34.844,36.578 32.734,34.656L28.993,31.29L11.188,49.108C11.234,49.109 11.281,49.109 11.328,49.109L67.109,49.109C67.167,49.109 67.223,49.109 67.279,49.107ZM71.016,11.879L54.327,26.905L71.016,43.594L71.016,11.879ZM12.279,7.484L36.734,29.547C37.547,30.266 38.359,30.641 39.219,30.641C40.094,30.641 40.906,30.266 41.719,29.547L66.174,7.484L12.279,7.484Z"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.2 KiB |
@ -1,5 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
|
|
||||||
<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" version="1.1" viewBox="0 0 72 69" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="m20.601 66.402v-19.472h8.932v19.472h28.517c4.163 0 6.597-2.375 6.597-6.48v-23.76c3.033-1.711 5.043-4.945 5.043-8.699v-0.498c0-1.144-0.293-2.17-0.88-3.167l-7.77-13.283v-2.433c0-3.724-2.287-5.952-6.069-5.952h-37.912c-3.783 0-6.099 2.228-6.099 5.952v2.433l-7.77 13.283c-0.587 0.997-0.88 2.023-0.88 3.167v0.498c0 3.754 2.01 6.988 5.043 8.699v23.76c0 4.105 2.434 6.48 6.597 6.48h6.651zm39.325-28.945c-0.098 3e-3 -0.195 5e-3 -0.293 5e-3 -3.255 0-6.099-1.496-7.858-3.871-1.789 2.375-4.604 3.871-7.888 3.871s-6.128-1.496-7.887-3.871c-1.759 2.375-4.603 3.871-7.887 3.871-3.255 0-6.099-1.496-7.858-3.871-1.789 2.375-4.633 3.871-7.888 3.871-0.098 0-0.195-2e-3 -0.293-5e-3v21.262c0 1.906 1.026 2.962 2.903 2.962h1.759v-16.449c0-1.349 0.909-2.229 2.258-2.229h12.432c1.349 0 2.228 0.88 2.228 2.229v16.449h23.399c1.876 0 2.873-1.056 2.873-2.962v-21.262zm-37.443-8.088h11.289c-0.645 2.375-2.639 3.958-5.659 3.958-2.991 0-5.014-1.583-5.63-3.958zm31.52 0h11.289c-0.645 2.375-2.639 3.958-5.659 3.958-2.991 0-5.014-1.583-5.63-3.958zm-47.295 0h11.318c-0.645 2.375-2.639 3.958-5.659 3.958s-5.014-1.583-5.659-3.958zm31.52 0h11.318c-0.645 2.375-2.639 3.958-5.659 3.958s-5.013-1.583-5.659-3.958zm-30.846-4.134 6.363-11.201h44.275l6.539 11.201h-57.177zm8.005-15.629v-0.703c0-1.466 0.851-2.346 2.287-2.346h36.652c1.437 0 2.287 0.88 2.287 2.346v0.703h-41.226z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.6 KiB |
@ -1,12 +0,0 @@
|
|||||||
<?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.865066,0,0,0.865066,3,8.230968)">
|
|
||||||
<path d="M23.234,51.266L63.359,51.266C65.406,51.266 67.047,49.531 67.047,47.516C67.047,45.422 65.422,43.75 63.359,43.75L23.234,43.75C21.172,43.75 19.562,45.469 19.562,47.516C19.562,49.484 21.188,51.266 23.234,51.266Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M5.922,54.953C10.047,54.953 12.406,53.203 12.406,50.391C12.406,48.562 11.125,47.344 8.859,47.141L8.859,47.031C10.422,46.734 11.797,45.594 11.797,43.688C11.797,41.078 9.203,39.734 5.906,39.734C3.328,39.734 0.391,40.859 0.391,43.172C0.391,44.156 1.094,44.859 2.25,44.859C2.984,44.859 3.344,44.578 3.828,44.125C4.625,43.375 5.203,43.156 5.906,43.156C6.781,43.156 7.484,43.547 7.484,44.422C7.484,45.219 6.812,45.656 5.641,45.656L5.219,45.656C4.297,45.656 3.688,46.172 3.688,47.203C3.688,48.188 4.266,48.734 5.219,48.734L5.672,48.734C6.922,48.734 7.609,49.172 7.625,50.047C7.641,50.812 6.891,51.359 5.922,51.359C4.812,51.359 4,50.672 3.406,50.188C3.016,49.891 2.656,49.609 2,49.609C0.828,49.609 0,50.297 0,51.438C0,53.688 3.094,54.953 5.922,54.953Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M23.234,31.562L63.359,31.562C65.406,31.562 67.047,29.812 67.047,27.797C67.047,25.719 65.422,24.047 63.359,24.047L23.234,24.047C21.172,24.047 19.562,25.766 19.562,27.797C19.562,29.781 21.188,31.562 23.234,31.562Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M2.031,34.797L10.5,34.797C11.531,34.797 12.312,34.141 12.312,33.062C12.312,32 11.547,31.312 10.5,31.312L6.219,31.312L6.219,31.203L8.719,29.234C10.859,27.531 11.875,26.531 11.875,24.5C11.875,21.797 9.562,20.031 5.859,20.031C2.641,20.031 0.344,21.609 0.344,23.703C0.344,24.828 1.078,25.453 2.297,25.453C3.062,25.453 3.594,25.203 4.172,24.484C4.688,23.828 5.172,23.5 5.938,23.5C6.75,23.5 7.359,24.016 7.359,24.844C7.359,25.547 6.953,26.125 5.312,27.438L1.109,30.859C0.406,31.422 0.109,32.062 0.109,32.891C0.109,34 0.859,34.797 2.031,34.797Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M23.234,11.844L63.359,11.844C65.406,11.844 67.047,10.109 67.047,8.094C67.047,6.016 65.422,4.328 63.359,4.328L23.234,4.328C21.172,4.328 19.562,6.047 19.562,8.094C19.562,10.078 21.188,11.844 23.234,11.844Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M7.312,15.234C8.688,15.234 9.656,14.469 9.656,12.766L9.656,2.469C9.656,0.953 8.562,0 6.984,0C5.766,0 4.969,0.406 4.031,1.016L1.812,2.516C1.094,2.984 0.766,3.438 0.766,4.203C0.766,5.172 1.453,5.828 2.281,5.797C2.703,5.781 2.922,5.734 3.516,5.359L4.828,4.469L4.922,4.469L4.922,12.766C4.922,14.469 5.875,15.234 7.312,15.234Z" style="fill-rule:nonzero;"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 3.0 KiB |
@ -1,7 +0,0 @@
|
|||||||
<?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,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;"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.8 KiB |
@ -1,11 +0,0 @@
|
|||||||
<?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(1,0,0,1,1.056758,1.088008)">
|
|
||||||
<rect x="0" y="0" width="59.625" height="59.562" style="fill-opacity:0;"/>
|
|
||||||
</g>
|
|
||||||
<g transform="matrix(0.918716,0,0,0.918716,5,4.991502)">
|
|
||||||
<path d="M17.169,58.796L41.597,58.796C47.087,58.796 51.398,57.182 54.261,54.3C57.207,51.396 58.778,47.075 58.778,41.616L58.778,17.19C58.778,11.722 57.207,7.41 54.261,4.496C51.377,1.602 47.087,0 41.597,0L17.169,0C11.7,0 7.358,1.624 4.496,4.496C1.571,7.41 0,11.722 0,17.19L0,41.616C0,47.075 1.55,51.396 4.496,54.3C7.379,57.204 11.7,58.796 17.169,58.796ZM17.487,51.837C13.94,51.837 11.276,50.962 9.566,49.252C7.813,47.53 6.959,44.898 6.959,41.288L6.959,17.508C6.959,13.909 7.813,11.276 9.566,9.545C11.245,7.865 13.94,6.959 17.487,6.959L41.27,6.959C44.848,6.959 47.49,7.844 49.212,9.545C50.965,11.276 51.819,13.909 51.819,17.508L51.819,41.288C51.819,44.898 50.965,47.53 49.212,49.252C47.511,50.941 44.848,51.837 41.27,51.837L17.487,51.837Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M34.245,20.733L28.455,25.929L17.907,36.476C17.311,37.063 16.929,37.896 16.929,38.71C16.929,40.544 18.242,41.748 19.997,41.748C20.916,41.748 21.667,41.417 22.323,40.771L32.821,30.304L37.996,24.505C40.497,21.719 37.205,18.138 34.245,20.733ZM36.354,30.119L36.354,34.789C36.354,36.636 37.45,37.853 39.143,37.853C40.836,37.853 41.911,36.582 41.911,34.767L41.911,20.374C41.911,18.014 40.563,16.868 38.364,16.868L23.898,16.868C22.062,16.868 20.845,17.943 20.845,19.636C20.845,21.329 22.064,22.404 23.91,22.404L28.872,22.404L37.417,21.188L36.354,30.119Z" style="fill-rule:nonzero;"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 2.0 KiB |
@ -1,12 +0,0 @@
|
|||||||
<?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(1,0,0,1,-0.5,-4)">
|
|
||||||
<path d="M59.063,37.932C60.996,39.115 62.286,41.246 62.286,43.675L62.286,59.025C62.286,62.739 59.271,65.754 55.558,65.754L9.442,65.754C5.729,65.754 2.714,62.739 2.714,59.025L2.714,43.675C2.714,41.692 3.574,39.908 4.941,38.676L4.941,23.857C4.941,21.49 6.144,19.403 8.186,18.218L28.762,6.357C30.813,5.136 33.19,5.136 35.263,6.357L55.817,18.218C57.859,19.403 59.063,21.49 59.063,23.857L59.063,37.932ZM10.076,36.947L27.371,36.947L10.076,27.093L10.076,36.947ZM36.574,36.947L53.923,36.947L53.923,27.065L36.574,36.947ZM31.984,33.577L52.082,22.106C51.964,21.992 51.921,21.927 51.713,21.8L33.492,11.283C32.55,10.719 31.453,10.719 30.511,11.283L12.312,21.8C12.083,21.927 12.03,21.997 11.892,22.125L31.984,33.577ZM58.286,43.675C58.286,42.169 57.064,40.947 55.558,40.947L9.442,40.947C7.936,40.947 6.714,42.169 6.714,43.675L6.714,59.025C6.714,60.531 7.936,61.754 9.442,61.754L55.558,61.754C57.064,61.754 58.286,60.531 58.286,59.025L58.286,43.675Z"/>
|
|
||||||
<g transform="matrix(1.711502,0,0,1.711502,-43.419476,-29.526577)">
|
|
||||||
<path d="M34.865,52.259C37.413,52.259 38.935,51.026 38.935,49.082C38.935,47.56 37.996,46.722 35.931,46.326L34.939,46.139C33.887,45.938 33.451,45.656 33.451,45.147C33.451,44.577 33.974,44.174 34.865,44.174C35.576,44.174 36.112,44.409 36.428,45.012C36.716,45.482 37.051,45.676 37.587,45.676C38.204,45.669 38.62,45.287 38.62,44.717C38.62,44.516 38.586,44.355 38.519,44.188C38.05,42.961 36.696,42.25 34.845,42.25C32.62,42.25 31.004,43.45 31.004,45.314C31.004,46.789 32.01,47.734 33.934,48.096L34.933,48.284C36.079,48.505 36.488,48.78 36.488,49.316C36.488,49.906 35.864,50.335 34.906,50.335C34.128,50.335 33.478,50.081 33.149,49.477C32.834,48.995 32.512,48.827 32.036,48.827C31.413,48.827 30.97,49.243 30.97,49.859C30.97,50.061 31.011,50.268 31.098,50.469C31.5,51.468 32.767,52.259 34.865,52.259Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M41.308,52.239C42.086,52.239 42.535,51.777 42.535,50.959L42.535,49.357L43.433,48.418L45.941,51.549C46.336,52.052 46.691,52.246 47.208,52.246C47.878,52.246 48.388,51.73 48.388,51.059C48.388,50.718 48.22,50.349 47.818,49.853L45.344,46.823L47.657,44.382C47.985,44.027 48.113,43.759 48.113,43.397C48.113,42.767 47.596,42.264 46.953,42.264C46.537,42.264 46.229,42.425 45.88,42.814L42.589,46.46L42.535,46.46L42.535,43.551C42.535,42.733 42.086,42.27 41.308,42.27C40.53,42.27 40.075,42.733 40.075,43.551L40.075,50.959C40.075,51.777 40.53,52.239 41.308,52.239Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M53.583,52.259C56.097,52.259 57.746,50.832 57.746,48.659L57.746,43.551C57.746,42.733 57.297,42.27 56.513,42.27C55.735,42.27 55.286,42.733 55.286,43.551L55.286,48.398C55.286,49.524 54.676,50.195 53.583,50.195C52.484,50.195 51.874,49.524 51.874,48.398L51.874,43.551C51.874,42.733 51.424,42.27 50.647,42.27C49.869,42.27 49.413,42.733 49.413,43.551L49.413,48.659C49.413,50.832 51.062,52.259 53.583,52.259Z" style="fill-rule:nonzero;"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 3.3 KiB |
@ -1,12 +0,0 @@
|
|||||||
<?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.983114,0,0,0.983114,0.872652,-3.62694)">
|
|
||||||
<path d="M1.364,59.66L1.364,41.653C1.364,40.114 2.153,38.751 3.47,37.993L15.368,31.125C15.408,31.101 15.448,31.079 15.488,31.057C15.484,30.981 15.482,30.906 15.482,30.83L15.482,17.094C15.482,15.554 16.271,14.192 17.588,13.433L29.487,6.565C30.819,5.777 32.374,5.777 33.714,6.565L45.605,13.433C46.922,14.192 47.71,15.554 47.71,17.094L47.71,30.83C47.71,30.882 47.71,30.934 47.708,30.986C47.794,31.029 47.879,31.075 47.963,31.125L59.854,37.993C61.171,38.751 61.96,40.114 61.96,41.653L61.96,59.66C61.96,63.437 58.893,66.504 55.116,66.504L8.208,66.504C4.431,66.504 1.364,63.437 1.364,59.66ZM50.74,37.202L46.646,34.839C46.14,34.532 45.551,34.532 45.045,34.839L40.954,37.202L50.74,37.202ZM22.294,37.202L17.928,34.679C17.513,34.548 17.07,34.601 16.678,34.839L12.587,37.202L22.294,37.202ZM31.554,22.132L42.251,15.999C42.197,15.953 42.182,15.93 42.067,15.861L32.397,10.279C31.891,9.973 31.302,9.973 30.796,10.279L21.133,15.861C21.011,15.93 20.98,15.96 20.896,16.029L31.554,22.132ZM29.663,36.94L29.663,25.531L19.341,19.62L19.341,30.103C19.341,30.57 19.539,30.987 19.878,31.288L29.663,36.94ZM33.53,36.986C33.721,36.887 33.805,36.833 34.005,36.718L43.047,31.489C43.553,31.19 43.844,30.685 43.844,30.103L43.844,19.574L33.53,25.478L33.53,36.986ZM57.891,44.046C57.891,42.514 56.648,41.271 55.116,41.271L8.208,41.271C6.676,41.271 5.433,42.514 5.433,44.046L5.433,59.66C5.433,61.191 6.676,62.435 8.208,62.435L55.116,62.435C56.648,62.435 57.891,61.191 57.891,59.66L57.891,44.046Z"/>
|
|
||||||
<g transform="matrix(1.740899,0,0,1.740899,-45.561479,-30.413194)">
|
|
||||||
<path d="M34.865,52.259C37.413,52.259 38.935,51.026 38.935,49.082C38.935,47.56 37.996,46.722 35.931,46.326L34.939,46.139C33.887,45.938 33.451,45.656 33.451,45.147C33.451,44.577 33.974,44.174 34.865,44.174C35.576,44.174 36.112,44.409 36.428,45.012C36.716,45.482 37.051,45.676 37.587,45.676C38.204,45.669 38.62,45.287 38.62,44.717C38.62,44.516 38.586,44.355 38.519,44.188C38.05,42.961 36.696,42.25 34.845,42.25C32.62,42.25 31.004,43.45 31.004,45.314C31.004,46.789 32.01,47.734 33.934,48.096L34.933,48.284C36.079,48.505 36.488,48.78 36.488,49.316C36.488,49.906 35.864,50.335 34.906,50.335C34.128,50.335 33.478,50.081 33.149,49.477C32.834,48.995 32.512,48.827 32.036,48.827C31.413,48.827 30.97,49.243 30.97,49.859C30.97,50.061 31.011,50.268 31.098,50.469C31.5,51.468 32.767,52.259 34.865,52.259Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M41.308,52.239C42.086,52.239 42.535,51.777 42.535,50.959L42.535,49.357L43.433,48.418L45.941,51.549C46.336,52.052 46.691,52.246 47.208,52.246C47.878,52.246 48.388,51.73 48.388,51.059C48.388,50.718 48.22,50.349 47.818,49.853L45.344,46.823L47.657,44.382C47.985,44.027 48.113,43.759 48.113,43.397C48.113,42.767 47.596,42.264 46.953,42.264C46.537,42.264 46.229,42.425 45.88,42.814L42.589,46.46L42.535,46.46L42.535,43.551C42.535,42.733 42.086,42.27 41.308,42.27C40.53,42.27 40.075,42.733 40.075,43.551L40.075,50.959C40.075,51.777 40.53,52.239 41.308,52.239Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M53.583,52.259C56.097,52.259 57.746,50.832 57.746,48.659L57.746,43.551C57.746,42.733 57.297,42.27 56.513,42.27C55.735,42.27 55.286,42.733 55.286,43.551L55.286,48.398C55.286,49.524 54.676,50.195 53.583,50.195C52.484,50.195 51.874,49.524 51.874,48.398L51.874,43.551C51.874,42.733 51.424,42.27 50.647,42.27C49.869,42.27 49.413,42.733 49.413,43.551L49.413,48.659C49.413,50.832 51.062,52.259 53.583,52.259Z" style="fill-rule:nonzero;"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 3.9 KiB |
@ -1,8 +0,0 @@
|
|||||||
<?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.774546,0,0,0.774546,1,13.356447)">
|
|
||||||
<path d="M42.516,48.141C45.406,48.141 46.984,46.891 47.812,43.844L58.703,9.766L58.906,9.766L69.609,43.844C70.438,46.891 72,48.141 74.891,48.141C78.016,48.141 80.047,46.266 80.047,43.375C80.047,42.234 79.891,41.312 79.484,40.141L67.109,5.75C65.766,1.859 63.125,0 58.781,0C54.688,0 52.062,1.859 50.719,5.734L38.141,40.531C37.766,41.594 37.594,42.594 37.594,43.5C37.594,46.375 39.469,48.141 42.516,48.141ZM47.891,36.469L69.562,36.469C71.672,36.469 73.391,34.75 73.391,32.641C73.391,30.516 71.672,28.812 69.562,28.812L47.891,28.812C45.766,28.812 44.062,30.516 44.062,32.641C44.062,34.75 45.766,36.469 47.891,36.469Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M4.25,48.141C6.453,48.141 7.766,46.984 8.531,44.219L10.141,39.25L22.188,39.25L23.781,44.312C24.5,47.047 25.812,48.141 28.188,48.141C30.641,48.141 32.391,46.5 32.391,44.109C32.391,43.156 32.188,42.297 31.797,41.203L22.781,16.75C21.531,13.328 19.469,11.766 16.078,11.766C12.875,11.766 10.812,13.344 9.594,16.75L0.609,41.203C0.234,42.203 0,43.281 0,44.109C0,46.625 1.609,48.141 4.25,48.141ZM11.875,32.938L15.797,19.891L16.328,19.891L20.344,32.938L11.875,32.938Z" style="fill-rule:nonzero;"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.6 KiB |
@ -1,11 +0,0 @@
|
|||||||
<?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.862654,0,0,0.862654,3,7.576119)">
|
|
||||||
<rect x="0" y="0" width="67.234" height="56.625" style="fill-opacity:0;"/>
|
|
||||||
<path d="M3.656,56.578L63.359,56.578C65.406,56.578 67.047,54.844 67.047,52.828C67.047,50.75 65.422,49.062 63.359,49.062L3.656,49.062C1.609,49.062 0,50.797 0,52.828C0,54.812 1.625,56.578 3.656,56.578Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M3.656,40.234L63.359,40.234C65.406,40.234 67.047,38.5 67.047,36.484C67.047,34.391 65.422,32.719 63.359,32.719L3.656,32.719C1.609,32.719 0,34.422 0,36.484C0,38.453 1.625,40.234 3.656,40.234Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M3.656,23.875L63.359,23.875C65.406,23.875 67.047,22.125 67.047,20.109C67.047,18.047 65.422,16.359 63.359,16.359L3.656,16.359C1.609,16.359 0,18.078 0,20.109C0,22.094 1.625,23.875 3.656,23.875Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M3.656,7.516L63.359,7.516C65.406,7.516 67.047,5.781 67.047,3.766C67.047,1.688 65.422,0 63.359,0L3.656,0C1.609,0 0,1.734 0,3.766C0,5.75 1.625,7.516 3.656,7.516Z" style="fill-rule:nonzero;"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.5 KiB |
@ -1,8 +0,0 @@
|
|||||||
<?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(1,0,0,1,12.21875,-7.71875)">
|
|
||||||
<path d="M2.859,68.875L36.688,68.875C38.328,68.875 39.562,67.719 39.562,66.109C39.562,64.516 38.328,63.328 36.688,63.328L2.859,63.328C1.234,63.328 0,64.516 0,66.109C0,67.719 1.234,68.875 2.859,68.875Z" style="fill-rule:nonzero;"/>
|
|
||||||
<path d="M19.781,58.359C31.812,58.359 39.562,51.5 39.562,41.203L39.562,15.281C39.562,12.328 37.672,10.562 34.703,10.562C31.766,10.562 29.875,12.328 29.875,15.281L29.875,40.234C29.875,46.328 26.203,50.156 19.781,50.156C13.359,50.156 9.703,46.328 9.703,40.234L9.703,15.281C9.703,12.328 7.781,10.562 4.828,10.562C1.906,10.562 0.016,12.328 0.016,15.281L0.016,41.203C0.016,51.5 7.75,58.359 19.781,58.359Z" style="fill-rule:nonzero;"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.2 KiB |
@ -1,7 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!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 clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" version="1.1" viewBox="0 0 72 69" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
|
||||||
<g transform="matrix(0.773655,0,0,0.773655,3,3.979177)">
|
<path d="m20.601 66.402v-19.472h8.932v19.472h28.517c4.163 0 6.597-2.375 6.597-6.48v-23.76c3.033-1.711 5.043-4.945 5.043-8.699v-0.498c0-1.144-0.293-2.17-0.88-3.167l-7.77-13.283v-2.433c0-3.724-2.287-5.952-6.069-5.952h-37.912c-3.783 0-6.099 2.228-6.099 5.952v2.433l-7.77 13.283c-0.587 0.997-0.88 2.023-0.88 3.167v0.498c0 3.754 2.01 6.988 5.043 8.699v23.76c0 4.105 2.434 6.48 6.597 6.48h6.651zm39.325-28.945c-0.098 3e-3 -0.195 5e-3 -0.293 5e-3 -3.255 0-6.099-1.496-7.858-3.871-1.789 2.375-4.604 3.871-7.888 3.871s-6.128-1.496-7.887-3.871c-1.759 2.375-4.603 3.871-7.887 3.871-3.255 0-6.099-1.496-7.858-3.871-1.789 2.375-4.633 3.871-7.888 3.871-0.098 0-0.195-2e-3 -0.293-5e-3v21.262c0 1.906 1.026 2.962 2.903 2.962h1.759v-16.449c0-1.349 0.909-2.229 2.258-2.229h12.432c1.349 0 2.228 0.88 2.228 2.229v16.449h23.399c1.876 0 2.873-1.056 2.873-2.962v-21.262zm-37.443-8.088h11.289c-0.645 2.375-2.639 3.958-5.659 3.958-2.991 0-5.014-1.583-5.63-3.958zm31.52 0h11.289c-0.645 2.375-2.639 3.958-5.659 3.958-2.991 0-5.014-1.583-5.63-3.958zm-47.295 0h11.318c-0.645 2.375-2.639 3.958-5.659 3.958s-5.014-1.583-5.659-3.958zm31.52 0h11.318c-0.645 2.375-2.639 3.958-5.659 3.958s-5.013-1.583-5.659-3.958zm-30.846-4.134 6.363-11.201h44.275l6.539 11.201h-57.177zm8.005-15.629v-0.703c0-1.466 0.851-2.346 2.287-2.346h36.652c1.437 0 2.287 0.88 2.287 2.346v0.703h-41.226z"/>
|
||||||
<path d="M6.922,23.938L68.547,23.938C70.812,23.938 72.156,22.234 72.156,20.547C72.156,19.312 71.453,18.188 69.984,17.328L42.109,1.25C40.734,0.453 39.188,0 37.719,0C36.25,0 34.688,0.453 33.344,1.25L5.469,17.328C3.984,18.188 3.297,19.312 3.297,20.547C3.297,22.234 4.641,23.938 6.922,23.938ZM15.047,19.719L36.859,7.5C37.141,7.344 37.469,7.25 37.719,7.25C37.984,7.25 38.297,7.344 38.594,7.5L60.406,19.719L61.016,17.516L14.438,17.516L15.047,19.719ZM8.516,31.609L17.281,31.609C18.797,31.609 19.734,30.75 19.734,29.234L19.734,28.781C19.734,27.25 18.812,26.312 17.281,26.312L8.516,26.312C7,26.312 6.094,27.25 6.094,28.781L6.094,29.234C6.094,30.75 7.031,31.609 8.516,31.609ZM9.891,59.516L15.938,59.516L15.938,30.047L9.891,30.047L9.891,59.516ZM8.516,63.25L17.281,63.25C18.812,63.25 19.734,62.359 19.734,60.812L19.734,60.359C19.734,58.844 18.797,57.953 17.281,57.953L8.516,57.953C7.031,57.953 6.094,58.844 6.094,60.359L6.094,60.812C6.094,62.359 7,63.25 8.516,63.25ZM25.062,31.609L33.828,31.609C35.344,31.609 36.281,30.75 36.281,29.234L36.281,28.781C36.281,27.25 35.359,26.312 33.828,26.312L25.062,26.312C23.547,26.312 22.641,27.25 22.641,28.781L22.641,29.234C22.641,30.75 23.562,31.609 25.062,31.609ZM26.422,59.516L32.469,59.516L32.469,30.047L26.422,30.047L26.422,59.516ZM25.062,63.25L33.828,63.25C35.359,63.25 36.281,62.359 36.281,60.812L36.281,60.359C36.281,58.844 35.344,57.953 33.828,57.953L25.062,57.953C23.562,57.953 22.641,58.844 22.641,60.359L22.641,60.812C22.641,62.359 23.547,63.25 25.062,63.25ZM41.625,31.609L50.375,31.609C51.875,31.609 52.828,30.75 52.828,29.234L52.828,28.781C52.828,27.25 51.891,26.312 50.375,26.312L41.625,26.312C40.078,26.312 39.188,27.25 39.188,28.781L39.188,29.234C39.188,30.75 40.094,31.609 41.625,31.609ZM42.984,59.516L49.031,59.516L49.031,30.047L42.984,30.047L42.984,59.516ZM41.625,63.25L50.375,63.25C51.891,63.25 52.828,62.359 52.828,60.812L52.828,60.359C52.828,58.844 51.875,57.953 50.375,57.953L41.625,57.953C40.094,57.953 39.188,58.844 39.188,60.359L39.188,60.812C39.188,62.359 40.078,63.25 41.625,63.25ZM58.156,31.609L66.922,31.609C68.406,31.609 69.359,30.75 69.359,29.234L69.359,28.781C69.359,27.25 68.422,26.312 66.922,26.312L58.156,26.312C56.625,26.312 55.719,27.25 55.719,28.781L55.719,29.234C55.719,30.75 56.641,31.609 58.156,31.609ZM59.531,59.516L65.578,59.516L65.578,30.047L59.531,30.047L59.531,59.516ZM58.156,63.25L66.922,63.25C68.422,63.25 69.359,62.359 69.359,60.812L69.359,60.359C69.359,58.844 68.406,57.953 66.922,57.953L58.156,57.953C56.641,57.953 55.719,58.844 55.719,60.359L55.719,60.812C55.719,62.359 56.625,63.25 58.156,63.25ZM3.391,72.438L71.547,72.438C73.375,72.438 74.969,70.922 74.969,69.031C74.969,67.188 73.375,65.641 71.547,65.641L3.391,65.641C1.547,65.641 0,67.188 0,69.031C0,70.906 1.547,72.438 3.391,72.438Z" style="fill-rule:nonzero;"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 1.6 KiB |
@ -35,10 +35,6 @@
|
|||||||
.ant-picker-input,
|
.ant-picker-input,
|
||||||
.ant-picker-header-view button,
|
.ant-picker-header-view button,
|
||||||
.ant-badge,
|
.ant-badge,
|
||||||
.ant-select-dropdown,
|
|
||||||
.ant-splitter,
|
|
||||||
.ant-steps-item-title,
|
|
||||||
.ant-steps-icon,
|
|
||||||
[class*=' ant-radio'] {
|
[class*=' ant-radio'] {
|
||||||
font-family: 'DM Sans';
|
font-family: 'DM Sans';
|
||||||
}
|
}
|
||||||
@ -48,15 +44,6 @@
|
|||||||
font-family: 'DM Mono';
|
font-family: 'DM Mono';
|
||||||
}
|
}
|
||||||
|
|
||||||
.ant-steps .ant-steps-item-icon {
|
|
||||||
line-height: 30px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-steps .ant-steps-item-icon .anticon.anticon-check.ant-steps-finish-icon {
|
|
||||||
line-height: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-typography .id-text {
|
.ant-typography .id-text {
|
||||||
font-family: 'DM Mono';
|
font-family: 'DM Mono';
|
||||||
font-size: 11.9px;
|
font-size: 11.9px;
|
||||||
@ -181,6 +168,23 @@ code {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.markdown-display > .ant-space-item *:first-child {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown-display > .ant-space-item *:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown-display > .ant-space-item h1,
|
||||||
|
.markdown-display > .ant-space-item h2,
|
||||||
|
.markdown-display > .ant-space-item h3,
|
||||||
|
.markdown-display > .ant-space-item h4,
|
||||||
|
.markdown-display > .ant-space-item h5,
|
||||||
|
.markdown-display > .ant-space-item h6 {
|
||||||
|
margin-bottom: 0.15em;
|
||||||
|
}
|
||||||
|
|
||||||
.iddisplay .ant-popover-inner {
|
.iddisplay .ant-popover-inner {
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
}
|
}
|
||||||
@ -413,186 +417,3 @@ body {
|
|||||||
.ant-badge .ant-badge-count-sm {
|
.ant-badge .ant-badge-count-sm {
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-number-cal {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-number-cal .ant-input-suffix {
|
|
||||||
margin-right: 28px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-number-cal .ant-input-outlined {
|
|
||||||
border-color: var(--color-purple);
|
|
||||||
box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-purple) 31%, transparent);
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-number-cal .ant-input {
|
|
||||||
font-family: 'DM Mono';
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-number-cal-icon {
|
|
||||||
position: absolute;
|
|
||||||
right: 10px;
|
|
||||||
top: 0;
|
|
||||||
bottom: 1px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --- Start of src/components/Dashboard/common/MarkdownInput.css --- */
|
|
||||||
.md-editor__content {
|
|
||||||
padding: 24px;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 1.6;
|
|
||||||
color: var(--baseText);
|
|
||||||
white-space: pre-wrap;
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.md-editor {
|
|
||||||
color: var(--baseText);
|
|
||||||
}
|
|
||||||
|
|
||||||
.md-editor .tiptap {
|
|
||||||
min-height: var(--md-editor-min-height);
|
|
||||||
}
|
|
||||||
|
|
||||||
.md-editor .tiptap p.is-editor-empty:first-child::before {
|
|
||||||
content: 'Enter text here...';
|
|
||||||
color: var(--baseBorderHover);
|
|
||||||
float: left;
|
|
||||||
height: 0;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.markdown pre,
|
|
||||||
.markdown code,
|
|
||||||
.markdown blockquote {
|
|
||||||
background: var(--baseBgSubtle);
|
|
||||||
color: var(--baseTextContrast);
|
|
||||||
}
|
|
||||||
|
|
||||||
.markdown pre {
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 12px;
|
|
||||||
overflow-x: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.markdown blockquote {
|
|
||||||
border-left: 3px solid var(--color-primary);
|
|
||||||
margin: 0;
|
|
||||||
padding: 8px 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.markdown hr {
|
|
||||||
border: 0;
|
|
||||||
border-top: 1px solid #8484844d;
|
|
||||||
margin: 10px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.markdown *:first-child {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.markdown h1:first-child {
|
|
||||||
margin-top: -4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.markdown h2:first-child {
|
|
||||||
margin-top: -3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.markdown h3:first-child {
|
|
||||||
margin-top: -2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.markdown h4:first-child {
|
|
||||||
margin-top: -1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.markdown *:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.markdown h1,
|
|
||||||
.markdown h2,
|
|
||||||
.markdown h3,
|
|
||||||
.markdown h4,
|
|
||||||
.markdown h5,
|
|
||||||
.markdown h6 {
|
|
||||||
margin-bottom: 10px;
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.markdown p {
|
|
||||||
font-size: 14px;
|
|
||||||
margin: 10px 0;
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.markdown h1 {
|
|
||||||
font-size: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.markdown h2 {
|
|
||||||
font-size: 26px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.markdown h3 {
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.markdown h4 {
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.markdown {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.markdown ul,
|
|
||||||
.markdown ol {
|
|
||||||
padding-left: 20px;
|
|
||||||
margin: 10px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.markdown li {
|
|
||||||
margin: 10px 0;
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.markdown-code-editor {
|
|
||||||
padding: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.markdown-splitter > .ant-splitter-bar {
|
|
||||||
margin: 8px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.markdown-code-editor .cm-editor {
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.markdown-code-editor .cm-editor.cm-focused {
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.markdown-code-editor .cm-editor .cm-gutters {
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h-100 {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-table.ant-table-middle .ant-table-filter-trigger {
|
|
||||||
height: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-table-wrapper .ant-table-filter-column {
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|||||||
4805
dist-test/index.js
Normal file
31
electrobun.config.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import type { ElectrobunConfig } from 'electrobun'
|
||||||
|
import { readFileSync } from 'fs'
|
||||||
|
|
||||||
|
const packageJson = JSON.parse(readFileSync('./package.json', 'utf8'))
|
||||||
|
|
||||||
|
export default {
|
||||||
|
app: {
|
||||||
|
name: 'Farm Control',
|
||||||
|
identifier: 'com.tombutcher.farmcontrol',
|
||||||
|
version: packageJson.version,
|
||||||
|
urlSchemes: ['farmcontrol']
|
||||||
|
},
|
||||||
|
runtime: {
|
||||||
|
exitOnLastWindowClosed: true
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
bun: {
|
||||||
|
entrypoint: 'src/bun/index.ts'
|
||||||
|
},
|
||||||
|
views: {
|
||||||
|
preload: {
|
||||||
|
entrypoint: 'src/preload/index.ts'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
copy: {
|
||||||
|
'build/index.html': 'views/main/index.html',
|
||||||
|
'build/assets': 'views/main/assets'
|
||||||
|
},
|
||||||
|
watch: ['build']
|
||||||
|
}
|
||||||
|
} satisfies ElectrobunConfig
|
||||||
29
package.json
@ -29,13 +29,6 @@
|
|||||||
"@codemirror/theme-one-dark": "^6.1.3",
|
"@codemirror/theme-one-dark": "^6.1.3",
|
||||||
"@simplewebauthn/browser": "^13.1.2",
|
"@simplewebauthn/browser": "^13.1.2",
|
||||||
"@tanstack/react-query": "^5.90.10",
|
"@tanstack/react-query": "^5.90.10",
|
||||||
"@tiptap/extension-link": "^3.20.1",
|
|
||||||
"@tiptap/extension-placeholder": "^3.20.1",
|
|
||||||
"@tiptap/extension-underline": "^3.20.1",
|
|
||||||
"@tiptap/markdown": "^3.20.1",
|
|
||||||
"@tiptap/pm": "^3.20.1",
|
|
||||||
"@tiptap/react": "^3.20.1",
|
|
||||||
"@tiptap/starter-kit": "^3.20.1",
|
|
||||||
"@tsparticles/react": "^3.0.0",
|
"@tsparticles/react": "^3.0.0",
|
||||||
"@tsparticles/slim": "^3.9.1",
|
"@tsparticles/slim": "^3.9.1",
|
||||||
"@uiw/react-codemirror": "^4.25.1",
|
"@uiw/react-codemirror": "^4.25.1",
|
||||||
@ -48,7 +41,6 @@
|
|||||||
"dotenv": "^17.2.1",
|
"dotenv": "^17.2.1",
|
||||||
"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",
|
||||||
"online-3d-viewer": "^0.16.0",
|
"online-3d-viewer": "^0.16.0",
|
||||||
@ -70,15 +62,15 @@
|
|||||||
"tsparticles": "^3.9.1",
|
"tsparticles": "^3.9.1",
|
||||||
"web-vitals": "^5.1.0"
|
"web-vitals": "^5.1.0"
|
||||||
},
|
},
|
||||||
"main": "build/electron.js",
|
"main": "src/bun/index.ts",
|
||||||
"description": "3D Printer ERP and Control Software.",
|
"description": "3D Printer ERP and Control Software.",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "cross-env NODE_ENV=development vite",
|
"dev": "cross-env NODE_ENV=development vite",
|
||||||
"electron": "cross-env ELECTRON_START_URL=http://0.0.0.0:5780 && cross-env NODE_ENV=development && electron .",
|
"electrobun": "cross-env ELECTROBUN_START_URL=http://localhost:5173 electrobun dev",
|
||||||
"start": "serve -s build",
|
"start": "serve -s build",
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"dev:electron": "concurrently \"cross-env NODE_ENV=development vite --no-open\" \"cross-env ELECTRON_START_URL=http://localhost:5780 cross-env NODE_ENV=development electron public/electron.js\"",
|
"dev:electrobun": "concurrently \"cross-env NODE_ENV=development vite --no-open\" \"cross-env ELECTROBUN_START_URL=http://localhost:5173 electrobun dev\"",
|
||||||
"build:electron": "vite build && electron-builder",
|
"build:electrobun": "vite build && electrobun build",
|
||||||
"build:cloudflare": "cross-env VITE_DEPLOY_TARGET=cloudflare vite build",
|
"build:cloudflare": "cross-env VITE_DEPLOY_TARGET=cloudflare vite build",
|
||||||
"deploy": "npm run build:cloudflare && wrangler pages deploy --branch main"
|
"deploy": "npm run build:cloudflare && wrangler pages deploy --branch main"
|
||||||
},
|
},
|
||||||
@ -104,9 +96,8 @@
|
|||||||
"@eslint/js": "^9.39.2",
|
"@eslint/js": "^9.39.2",
|
||||||
"@vitejs/plugin-react": "^5.0.2",
|
"@vitejs/plugin-react": "^5.0.2",
|
||||||
"concurrently": "^9.2.1",
|
"concurrently": "^9.2.1",
|
||||||
"electron": "^38.7.1",
|
"electrobun": "^1.13.1",
|
||||||
"electron-builder": "^26.0.12",
|
"typescript": "^5.0.0",
|
||||||
"electron-packager": "^17.1.2",
|
|
||||||
"eslint": "^9.34.0",
|
"eslint": "^9.34.0",
|
||||||
"eslint-config-prettier": "^10.1.8",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"eslint-plugin-prettier": "^5.5.4",
|
"eslint-plugin-prettier": "^5.5.4",
|
||||||
@ -144,13 +135,7 @@
|
|||||||
{
|
{
|
||||||
"target": "dmg",
|
"target": "dmg",
|
||||||
"arch": [
|
"arch": [
|
||||||
"arm64"
|
"universal"
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"target": "dmg",
|
|
||||||
"arch": [
|
|
||||||
"x64"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
662
pnpm-lock.yaml
generated
@ -68,27 +68,6 @@ importers:
|
|||||||
'@tanstack/react-query':
|
'@tanstack/react-query':
|
||||||
specifier: ^5.90.10
|
specifier: ^5.90.10
|
||||||
version: 5.90.20(react@19.2.4)
|
version: 5.90.20(react@19.2.4)
|
||||||
'@tiptap/extension-link':
|
|
||||||
specifier: ^3.20.1
|
|
||||||
version: 3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1)
|
|
||||||
'@tiptap/extension-placeholder':
|
|
||||||
specifier: ^3.20.1
|
|
||||||
version: 3.20.1(@tiptap/extensions@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1))
|
|
||||||
'@tiptap/extension-underline':
|
|
||||||
specifier: ^3.20.1
|
|
||||||
version: 3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))
|
|
||||||
'@tiptap/markdown':
|
|
||||||
specifier: ^3.20.1
|
|
||||||
version: 3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1)
|
|
||||||
'@tiptap/pm':
|
|
||||||
specifier: ^3.20.1
|
|
||||||
version: 3.20.1
|
|
||||||
'@tiptap/react':
|
|
||||||
specifier: ^3.20.1
|
|
||||||
version: 3.20.1(@floating-ui/dom@1.7.6)(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1)(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
|
||||||
'@tiptap/starter-kit':
|
|
||||||
specifier: ^3.20.1
|
|
||||||
version: 3.20.1
|
|
||||||
'@tsparticles/react':
|
'@tsparticles/react':
|
||||||
specifier: ^3.0.0
|
specifier: ^3.0.0
|
||||||
version: 3.0.0(@tsparticles/engine@3.9.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
version: 3.0.0(@tsparticles/engine@3.9.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||||
@ -1130,15 +1109,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==}
|
resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
|
|
||||||
'@floating-ui/core@1.7.5':
|
|
||||||
resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==}
|
|
||||||
|
|
||||||
'@floating-ui/dom@1.7.6':
|
|
||||||
resolution: {integrity: sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==}
|
|
||||||
|
|
||||||
'@floating-ui/utils@0.2.11':
|
|
||||||
resolution: {integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==}
|
|
||||||
|
|
||||||
'@humanfs/core@0.19.1':
|
'@humanfs/core@0.19.1':
|
||||||
resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==}
|
resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==}
|
||||||
engines: {node: '>=18.18.0'}
|
engines: {node: '>=18.18.0'}
|
||||||
@ -1468,9 +1438,6 @@ packages:
|
|||||||
react: '>=18.0.0'
|
react: '>=18.0.0'
|
||||||
react-dom: '>=18.0.0'
|
react-dom: '>=18.0.0'
|
||||||
|
|
||||||
'@remirror/core-constants@3.0.0':
|
|
||||||
resolution: {integrity: sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==}
|
|
||||||
|
|
||||||
'@rolldown/pluginutils@1.0.0-beta.53':
|
'@rolldown/pluginutils@1.0.0-beta.53':
|
||||||
resolution: {integrity: sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ==}
|
resolution: {integrity: sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ==}
|
||||||
|
|
||||||
@ -1711,166 +1678,6 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
react: ^18 || ^19
|
react: ^18 || ^19
|
||||||
|
|
||||||
'@tiptap/core@3.20.1':
|
|
||||||
resolution: {integrity: sha512-SwkPEWIfaDEZjC8SEIi4kZjqIYUbRgLUHUuQezo5GbphUNC8kM1pi3C3EtoOPtxXrEbY6e4pWEzW54Pcrd+rVA==}
|
|
||||||
peerDependencies:
|
|
||||||
'@tiptap/pm': ^3.20.1
|
|
||||||
|
|
||||||
'@tiptap/extension-blockquote@3.20.1':
|
|
||||||
resolution: {integrity: sha512-WzNXk/63PQI2fav4Ta6P0GmYRyu8Gap1pV3VUqaVK829iJ6Zt1T21xayATHEHWMK27VT1GLPJkx9Ycr2jfDyQw==}
|
|
||||||
peerDependencies:
|
|
||||||
'@tiptap/core': ^3.20.1
|
|
||||||
|
|
||||||
'@tiptap/extension-bold@3.20.1':
|
|
||||||
resolution: {integrity: sha512-fz++Qv6Rk/Hov0IYG/r7TJ1Y4zWkuGONe0UN5g0KY32NIMg3HeOHicbi4xsNWTm9uAOl3eawWDkezEMrleObMw==}
|
|
||||||
peerDependencies:
|
|
||||||
'@tiptap/core': ^3.20.1
|
|
||||||
|
|
||||||
'@tiptap/extension-bubble-menu@3.20.1':
|
|
||||||
resolution: {integrity: sha512-XaPvO6aCoWdFnCBus0s88lnj17NR/OopV79i8Qhgz3WMR0vrsL5zsd45l0lZuu9pSvm5VW47SoxakkJiZC1suw==}
|
|
||||||
peerDependencies:
|
|
||||||
'@tiptap/core': ^3.20.1
|
|
||||||
'@tiptap/pm': ^3.20.1
|
|
||||||
|
|
||||||
'@tiptap/extension-bullet-list@3.20.1':
|
|
||||||
resolution: {integrity: sha512-mbrlvOZo5OF3vLhp+3fk9KuL/6J/wsN0QxF6ZFRAHzQ9NkJdtdfARcBeBnkWXGN8inB6YxbTGY1/E4lmBkOpOw==}
|
|
||||||
peerDependencies:
|
|
||||||
'@tiptap/extension-list': ^3.20.1
|
|
||||||
|
|
||||||
'@tiptap/extension-code-block@3.20.1':
|
|
||||||
resolution: {integrity: sha512-vKejwBq+Nlj4Ybd3qOyDxIQKzYymdNH+8eXkKwGShk2nfLJIxq69DCyGvmuHgipIO1qcYPJ149UNpGN+YGcdmA==}
|
|
||||||
peerDependencies:
|
|
||||||
'@tiptap/core': ^3.20.1
|
|
||||||
'@tiptap/pm': ^3.20.1
|
|
||||||
|
|
||||||
'@tiptap/extension-code@3.20.1':
|
|
||||||
resolution: {integrity: sha512-509DHINIA/Gg+eTG7TEkfsS8RUiPLH5xZNyLRT0A1oaoaJmECKfrV6aAm05IdfTyqDqz6LW5pbnX6DdUC4keug==}
|
|
||||||
peerDependencies:
|
|
||||||
'@tiptap/core': ^3.20.1
|
|
||||||
|
|
||||||
'@tiptap/extension-document@3.20.1':
|
|
||||||
resolution: {integrity: sha512-9vrqdGmRV7bQCSY3NLgu7UhIwgOCDp4sKqMNsoNRX0aZ021QQMTvBQDPkiRkCf7MNsnWrNNnr52PVnULEn3vFQ==}
|
|
||||||
peerDependencies:
|
|
||||||
'@tiptap/core': ^3.20.1
|
|
||||||
|
|
||||||
'@tiptap/extension-dropcursor@3.20.1':
|
|
||||||
resolution: {integrity: sha512-K18L9FX4znn+ViPSIbTLOGcIaXMx/gLNwAPE8wPLwswbHhQqdiY1zzdBw6drgOc1Hicvebo2dIoUlSXOZsOEcw==}
|
|
||||||
peerDependencies:
|
|
||||||
'@tiptap/extensions': ^3.20.1
|
|
||||||
|
|
||||||
'@tiptap/extension-floating-menu@3.20.1':
|
|
||||||
resolution: {integrity: sha512-BeDC6nfOesIMn5pFuUnkEjOxGv80sOJ8uk1mdt9/3Fkvra8cB9NIYYCVtd6PU8oQFmJ8vFqPrRkUWrG5tbqnOg==}
|
|
||||||
peerDependencies:
|
|
||||||
'@floating-ui/dom': ^1.0.0
|
|
||||||
'@tiptap/core': ^3.20.1
|
|
||||||
'@tiptap/pm': ^3.20.1
|
|
||||||
|
|
||||||
'@tiptap/extension-gapcursor@3.20.1':
|
|
||||||
resolution: {integrity: sha512-kZOtttV6Ai8VUAgEng3h4WKFbtdSNJ6ps7r0cRPY+FctWhVmgNb/JJwwyC+vSilR7nRENAhrA/Cv/RxVlvLw+g==}
|
|
||||||
peerDependencies:
|
|
||||||
'@tiptap/extensions': ^3.20.1
|
|
||||||
|
|
||||||
'@tiptap/extension-hard-break@3.20.1':
|
|
||||||
resolution: {integrity: sha512-9sKpmg/IIdlLXimYWUZ3PplIRcehv4Oc7V1miTqlnAthMzjMqigDkjjgte4JZV67RdnDJTQkRw8TklCAU28Emg==}
|
|
||||||
peerDependencies:
|
|
||||||
'@tiptap/core': ^3.20.1
|
|
||||||
|
|
||||||
'@tiptap/extension-heading@3.20.1':
|
|
||||||
resolution: {integrity: sha512-unudyfQP6FxnyWinxvPqe/51DG91J6AaJm666RnAubgYMCgym+33kBftx4j4A6qf+ddWYbD00thMNKOnVLjAEQ==}
|
|
||||||
peerDependencies:
|
|
||||||
'@tiptap/core': ^3.20.1
|
|
||||||
|
|
||||||
'@tiptap/extension-horizontal-rule@3.20.1':
|
|
||||||
resolution: {integrity: sha512-rjFKFXNntdl0jay8oIGFvvykHlpyQTLmrH3Ag2fj3i8yh6MVvqhtaDomYQbw5sxECd5hBkL+T4n2d2DRuVw/QQ==}
|
|
||||||
peerDependencies:
|
|
||||||
'@tiptap/core': ^3.20.1
|
|
||||||
'@tiptap/pm': ^3.20.1
|
|
||||||
|
|
||||||
'@tiptap/extension-italic@3.20.1':
|
|
||||||
resolution: {integrity: sha512-ZYRX13Kt8tR8JOzSXirH3pRpi8x30o7LHxZY58uXBdUvr3tFzOkh03qbN523+diidSVeHP/aMd/+IrplHRkQug==}
|
|
||||||
peerDependencies:
|
|
||||||
'@tiptap/core': ^3.20.1
|
|
||||||
|
|
||||||
'@tiptap/extension-link@3.20.1':
|
|
||||||
resolution: {integrity: sha512-oYTTIgsQMqpkSnJAuAc+UtIKMuI4lv9e1y4LfI1iYm6NkEUHhONppU59smhxHLzb3Ww7YpDffbp5IgDTAiJztA==}
|
|
||||||
peerDependencies:
|
|
||||||
'@tiptap/core': ^3.20.1
|
|
||||||
'@tiptap/pm': ^3.20.1
|
|
||||||
|
|
||||||
'@tiptap/extension-list-item@3.20.1':
|
|
||||||
resolution: {integrity: sha512-tzgnyTW82lYJkUnadYbatwkI9dLz/OWRSWuFpQPRje/ItmFMWuQ9c9NDD8qLbXPdEYnvrgSAA+ipCD/1G0qA0Q==}
|
|
||||||
peerDependencies:
|
|
||||||
'@tiptap/extension-list': ^3.20.1
|
|
||||||
|
|
||||||
'@tiptap/extension-list-keymap@3.20.1':
|
|
||||||
resolution: {integrity: sha512-Dr0xsQKx0XPOgDg7xqoWwfv7FFwZ3WeF3eOjqh3rDXlNHMj1v+UW5cj1HLphrsAZHTrVTn2C+VWPJkMZrSbpvQ==}
|
|
||||||
peerDependencies:
|
|
||||||
'@tiptap/extension-list': ^3.20.1
|
|
||||||
|
|
||||||
'@tiptap/extension-list@3.20.1':
|
|
||||||
resolution: {integrity: sha512-euBRAn0mkV7R2VEE+AuOt3R0j9RHEMFXamPFmtvTo8IInxDClusrm6mJoDjS8gCGAXsQCRiAe1SCQBPgGbOOwg==}
|
|
||||||
peerDependencies:
|
|
||||||
'@tiptap/core': ^3.20.1
|
|
||||||
'@tiptap/pm': ^3.20.1
|
|
||||||
|
|
||||||
'@tiptap/extension-ordered-list@3.20.1':
|
|
||||||
resolution: {integrity: sha512-Y+3Ad7OwAdagqdYwCnbqf7/to5ypD4NnUNHA0TXRCs7cAHRA8AdgPoIcGFpaaSpV86oosNU3yfeJouYeroffog==}
|
|
||||||
peerDependencies:
|
|
||||||
'@tiptap/extension-list': ^3.20.1
|
|
||||||
|
|
||||||
'@tiptap/extension-paragraph@3.20.1':
|
|
||||||
resolution: {integrity: sha512-QFrAtXNyv7JSnomMQc1nx5AnG9mMznfbYJAbdOQYVdbLtAzTfiTuNPNbQrufy5ZGtGaHxDCoaygu2QEfzaKG+Q==}
|
|
||||||
peerDependencies:
|
|
||||||
'@tiptap/core': ^3.20.1
|
|
||||||
|
|
||||||
'@tiptap/extension-placeholder@3.20.1':
|
|
||||||
resolution: {integrity: sha512-k+jfbCugYGuIFBdojukgEopGazIMOgHrw46FnyN2X/6ICOIjQP2rh2ObslrsUOsJYoEevxCsNF9hZl1HvWX66g==}
|
|
||||||
peerDependencies:
|
|
||||||
'@tiptap/extensions': ^3.20.1
|
|
||||||
|
|
||||||
'@tiptap/extension-strike@3.20.1':
|
|
||||||
resolution: {integrity: sha512-EYgyma10lpsY+rwbVQL9u+gA7hBlKLSMFH7Zgd37FSxukOjr+HE8iKPQQ+SwbGejyDsPlLT8Z5Jnuxo5Ng90Pg==}
|
|
||||||
peerDependencies:
|
|
||||||
'@tiptap/core': ^3.20.1
|
|
||||||
|
|
||||||
'@tiptap/extension-text@3.20.1':
|
|
||||||
resolution: {integrity: sha512-7PlIbYW8UenV6NPOXHmv8IcmPGlGx6HFq66RmkJAOJRPXPkTLAiX0N8rQtzUJ6jDEHqoJpaHFEHJw0xzW1yF+A==}
|
|
||||||
peerDependencies:
|
|
||||||
'@tiptap/core': ^3.20.1
|
|
||||||
|
|
||||||
'@tiptap/extension-underline@3.20.1':
|
|
||||||
resolution: {integrity: sha512-fmHvDKzwCgnZUwRreq8tYkb1YyEwgzZ6QQkAQ0CsCRtvRMqzerr3Duz0Als4i8voZTuGDEL3VR6nAJbLAb/wPg==}
|
|
||||||
peerDependencies:
|
|
||||||
'@tiptap/core': ^3.20.1
|
|
||||||
|
|
||||||
'@tiptap/extensions@3.20.1':
|
|
||||||
resolution: {integrity: sha512-JRc/v+OBH0qLTdvQ7HvHWTxGJH73QOf1MC0R8NhOX2QnAbg2mPFv1h+FjGa2gfLGuCXBdWQomjekWkUKbC4e5A==}
|
|
||||||
peerDependencies:
|
|
||||||
'@tiptap/core': ^3.20.1
|
|
||||||
'@tiptap/pm': ^3.20.1
|
|
||||||
|
|
||||||
'@tiptap/markdown@3.20.1':
|
|
||||||
resolution: {integrity: sha512-dNrtP7kmabDomgjv9G/6+JSFL6WraPaFbmKh1eHSYKdDGvIwBfJnVPTV2VS3bP1OuYJEDJN/2ydtiCHyOTrQsQ==}
|
|
||||||
peerDependencies:
|
|
||||||
'@tiptap/core': ^3.20.1
|
|
||||||
'@tiptap/pm': ^3.20.1
|
|
||||||
|
|
||||||
'@tiptap/pm@3.20.1':
|
|
||||||
resolution: {integrity: sha512-6kCiGLvpES4AxcEuOhb7HR7/xIeJWMjZlb6J7e8zpiIh5BoQc7NoRdctsnmFEjZvC19bIasccshHQ7H2zchWqw==}
|
|
||||||
|
|
||||||
'@tiptap/react@3.20.1':
|
|
||||||
resolution: {integrity: sha512-UH1NpVpCaZBGB3Yr5N6aTS+rsCMDl9wHfrt/w+6+Gz4KHFZ2OILA82hELxZzhNc1Lmjz8vgCArKcsYql9gbzJA==}
|
|
||||||
peerDependencies:
|
|
||||||
'@tiptap/core': ^3.20.1
|
|
||||||
'@tiptap/pm': ^3.20.1
|
|
||||||
'@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0
|
|
||||||
'@types/react-dom': ^17.0.0 || ^18.0.0 || ^19.0.0
|
|
||||||
react: ^17.0.0 || ^18.0.0 || ^19.0.0
|
|
||||||
react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0
|
|
||||||
|
|
||||||
'@tiptap/starter-kit@3.20.1':
|
|
||||||
resolution: {integrity: sha512-opqWxL/4OTEiqmVC0wsU4o3JhAf6LycJ2G/gRIZVAIFLljI9uHfpPMTFGxZ5w9IVVJaP5PJysfwW/635kKqkrw==}
|
|
||||||
|
|
||||||
'@trysound/sax@0.2.0':
|
'@trysound/sax@0.2.0':
|
||||||
resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
|
resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
|
||||||
engines: {node: '>=10.13.0'}
|
engines: {node: '>=10.13.0'}
|
||||||
@ -2134,18 +1941,9 @@ packages:
|
|||||||
'@types/keyv@3.1.4':
|
'@types/keyv@3.1.4':
|
||||||
resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==}
|
resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==}
|
||||||
|
|
||||||
'@types/linkify-it@5.0.0':
|
|
||||||
resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==}
|
|
||||||
|
|
||||||
'@types/markdown-it@14.1.2':
|
|
||||||
resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==}
|
|
||||||
|
|
||||||
'@types/mdast@4.0.4':
|
'@types/mdast@4.0.4':
|
||||||
resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==}
|
resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==}
|
||||||
|
|
||||||
'@types/mdurl@2.0.0':
|
|
||||||
resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==}
|
|
||||||
|
|
||||||
'@types/ms@2.1.0':
|
'@types/ms@2.1.0':
|
||||||
resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==}
|
resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==}
|
||||||
|
|
||||||
@ -2161,11 +1959,6 @@ packages:
|
|||||||
'@types/plist@3.0.5':
|
'@types/plist@3.0.5':
|
||||||
resolution: {integrity: sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==}
|
resolution: {integrity: sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==}
|
||||||
|
|
||||||
'@types/react-dom@19.2.3':
|
|
||||||
resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==}
|
|
||||||
peerDependencies:
|
|
||||||
'@types/react': ^19.2.0
|
|
||||||
|
|
||||||
'@types/react@19.2.10':
|
'@types/react@19.2.10':
|
||||||
resolution: {integrity: sha512-WPigyYuGhgZ/cTPRXB2EwUw+XvsRA3GqHlsP4qteqrnnjDrApbS7MxcGr/hke5iUoeB7E/gQtrs9I37zAJ0Vjw==}
|
resolution: {integrity: sha512-WPigyYuGhgZ/cTPRXB2EwUw+XvsRA3GqHlsP4qteqrnnjDrApbS7MxcGr/hke5iUoeB7E/gQtrs9I37zAJ0Vjw==}
|
||||||
|
|
||||||
@ -2181,9 +1974,6 @@ packages:
|
|||||||
'@types/unist@3.0.3':
|
'@types/unist@3.0.3':
|
||||||
resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==}
|
resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==}
|
||||||
|
|
||||||
'@types/use-sync-external-store@0.0.6':
|
|
||||||
resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==}
|
|
||||||
|
|
||||||
'@types/verror@1.10.11':
|
'@types/verror@1.10.11':
|
||||||
resolution: {integrity: sha512-RlDm9K7+o5stv0Co8i8ZRGxDbrTxhJtgjqjFyVh/tXQyl/rYtTKlnTvZ88oSTeYREWurwx20Js4kTuKCsFkUtg==}
|
resolution: {integrity: sha512-RlDm9K7+o5stv0Co8i8ZRGxDbrTxhJtgjqjFyVh/tXQyl/rYtTKlnTvZ88oSTeYREWurwx20Js4kTuKCsFkUtg==}
|
||||||
|
|
||||||
@ -3594,10 +3384,6 @@ packages:
|
|||||||
fast-diff@1.3.0:
|
fast-diff@1.3.0:
|
||||||
resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==}
|
resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==}
|
||||||
|
|
||||||
fast-equals@5.4.0:
|
|
||||||
resolution: {integrity: sha512-jt2DW/aNFNwke7AUd+Z+e6pz39KO5rzdbbFCg2sGafS4mk13MI7Z8O5z9cADNn5lhGODIgLwug6TZO2ctf7kcw==}
|
|
||||||
engines: {node: '>=6.0.0'}
|
|
||||||
|
|
||||||
fast-glob@3.3.3:
|
fast-glob@3.3.3:
|
||||||
resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==}
|
resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==}
|
||||||
engines: {node: '>=8.6.0'}
|
engines: {node: '>=8.6.0'}
|
||||||
@ -4307,12 +4093,6 @@ packages:
|
|||||||
lines-and-columns@1.2.4:
|
lines-and-columns@1.2.4:
|
||||||
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
|
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
|
||||||
|
|
||||||
linkify-it@5.0.0:
|
|
||||||
resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==}
|
|
||||||
|
|
||||||
linkifyjs@4.3.2:
|
|
||||||
resolution: {integrity: sha512-NT1CJtq3hHIreOianA8aSXn6Cw0JzYOuDQbOrSPe7gqFnCpKP++MQe3ODgO3oh2GJFORkAAdqredOa60z63GbA==}
|
|
||||||
|
|
||||||
load-json-file@2.0.0:
|
load-json-file@2.0.0:
|
||||||
resolution: {integrity: sha512-3p6ZOGNbiX4CdvEd1VcE6yi78UrGNpjHO33noGwHCnT/o2fyllJDepsm8+mFFv/DvtwFHht5HIHSyOy5a+ChVQ==}
|
resolution: {integrity: sha512-3p6ZOGNbiX4CdvEd1VcE6yi78UrGNpjHO33noGwHCnT/o2fyllJDepsm8+mFFv/DvtwFHht5HIHSyOy5a+ChVQ==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
@ -4396,18 +4176,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ==}
|
resolution: {integrity: sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ==}
|
||||||
engines: {node: ^18.17.0 || >=20.5.0}
|
engines: {node: ^18.17.0 || >=20.5.0}
|
||||||
|
|
||||||
markdown-it@14.1.1:
|
|
||||||
resolution: {integrity: sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==}
|
|
||||||
hasBin: true
|
|
||||||
|
|
||||||
markdown-table@3.0.4:
|
markdown-table@3.0.4:
|
||||||
resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==}
|
resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==}
|
||||||
|
|
||||||
marked@17.0.4:
|
|
||||||
resolution: {integrity: sha512-NOmVMM+KAokHMvjWmC5N/ZOvgmSWuqJB8FoYI019j4ogb/PeRMKoKIjReZ2w3376kkA8dSJIP8uD993Kxc0iRQ==}
|
|
||||||
engines: {node: '>= 20'}
|
|
||||||
hasBin: true
|
|
||||||
|
|
||||||
matcher@3.0.0:
|
matcher@3.0.0:
|
||||||
resolution: {integrity: sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==}
|
resolution: {integrity: sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@ -4473,9 +4244,6 @@ packages:
|
|||||||
mdn-data@2.12.2:
|
mdn-data@2.12.2:
|
||||||
resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==}
|
resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==}
|
||||||
|
|
||||||
mdurl@2.0.0:
|
|
||||||
resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==}
|
|
||||||
|
|
||||||
media-typer@1.1.0:
|
media-typer@1.1.0:
|
||||||
resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==}
|
resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==}
|
||||||
engines: {node: '>= 0.8'}
|
engines: {node: '>= 0.8'}
|
||||||
@ -4850,9 +4618,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==}
|
resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
orderedmap@2.1.1:
|
|
||||||
resolution: {integrity: sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==}
|
|
||||||
|
|
||||||
own-keys@1.0.1:
|
own-keys@1.0.1:
|
||||||
resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==}
|
resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@ -5088,64 +4853,6 @@ packages:
|
|||||||
property-information@7.1.0:
|
property-information@7.1.0:
|
||||||
resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==}
|
resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==}
|
||||||
|
|
||||||
prosemirror-changeset@2.4.0:
|
|
||||||
resolution: {integrity: sha512-LvqH2v7Q2SF6yxatuPP2e8vSUKS/L+xAU7dPDC4RMyHMhZoGDfBC74mYuyYF4gLqOEG758wajtyhNnsTkuhvng==}
|
|
||||||
|
|
||||||
prosemirror-collab@1.3.1:
|
|
||||||
resolution: {integrity: sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==}
|
|
||||||
|
|
||||||
prosemirror-commands@1.7.1:
|
|
||||||
resolution: {integrity: sha512-rT7qZnQtx5c0/y/KlYaGvtG411S97UaL6gdp6RIZ23DLHanMYLyfGBV5DtSnZdthQql7W+lEVbpSfwtO8T+L2w==}
|
|
||||||
|
|
||||||
prosemirror-dropcursor@1.8.2:
|
|
||||||
resolution: {integrity: sha512-CCk6Gyx9+Tt2sbYk5NK0nB1ukHi2ryaRgadV/LvyNuO3ena1payM2z6Cg0vO1ebK8cxbzo41ku2DE5Axj1Zuiw==}
|
|
||||||
|
|
||||||
prosemirror-gapcursor@1.4.0:
|
|
||||||
resolution: {integrity: sha512-z00qvurSdCEWUIulij/isHaqu4uLS8r/Fi61IbjdIPJEonQgggbJsLnstW7Lgdk4zQ68/yr6B6bf7sJXowIgdQ==}
|
|
||||||
|
|
||||||
prosemirror-history@1.5.0:
|
|
||||||
resolution: {integrity: sha512-zlzTiH01eKA55UAf1MEjtssJeHnGxO0j4K4Dpx+gnmX9n+SHNlDqI2oO1Kv1iPN5B1dm5fsljCfqKF9nFL6HRg==}
|
|
||||||
|
|
||||||
prosemirror-inputrules@1.5.1:
|
|
||||||
resolution: {integrity: sha512-7wj4uMjKaXWAQ1CDgxNzNtR9AlsuwzHfdFH1ygEHA2KHF2DOEaXl1CJfNPAKCg9qNEh4rum975QLaCiQPyY6Fw==}
|
|
||||||
|
|
||||||
prosemirror-keymap@1.2.3:
|
|
||||||
resolution: {integrity: sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==}
|
|
||||||
|
|
||||||
prosemirror-markdown@1.13.4:
|
|
||||||
resolution: {integrity: sha512-D98dm4cQ3Hs6EmjK500TdAOew4Z03EV71ajEFiWra3Upr7diytJsjF4mPV2dW+eK5uNectiRj0xFxYI9NLXDbw==}
|
|
||||||
|
|
||||||
prosemirror-menu@1.3.0:
|
|
||||||
resolution: {integrity: sha512-TImyPXCHPcDsSka2/lwJ6WjTASr4re/qWq1yoTTuLOqfXucwF6VcRa2LWCkM/EyTD1UO3CUwiH8qURJoWJRxwg==}
|
|
||||||
|
|
||||||
prosemirror-model@1.25.4:
|
|
||||||
resolution: {integrity: sha512-PIM7E43PBxKce8OQeezAs9j4TP+5yDpZVbuurd1h5phUxEKIu+G2a+EUZzIC5nS1mJktDJWzbqS23n1tsAf5QA==}
|
|
||||||
|
|
||||||
prosemirror-schema-basic@1.2.4:
|
|
||||||
resolution: {integrity: sha512-ELxP4TlX3yr2v5rM7Sb70SqStq5NvI15c0j9j/gjsrO5vaw+fnnpovCLEGIcpeGfifkuqJwl4fon6b+KdrODYQ==}
|
|
||||||
|
|
||||||
prosemirror-schema-list@1.5.1:
|
|
||||||
resolution: {integrity: sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q==}
|
|
||||||
|
|
||||||
prosemirror-state@1.4.4:
|
|
||||||
resolution: {integrity: sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw==}
|
|
||||||
|
|
||||||
prosemirror-tables@1.8.5:
|
|
||||||
resolution: {integrity: sha512-V/0cDCsHKHe/tfWkeCmthNUcEp1IVO3p6vwN8XtwE9PZQLAZJigbw3QoraAdfJPir4NKJtNvOB8oYGKRl+t0Dw==}
|
|
||||||
|
|
||||||
prosemirror-trailing-node@3.0.0:
|
|
||||||
resolution: {integrity: sha512-xiun5/3q0w5eRnGYfNlW1uU9W6x5MoFKWwq/0TIRgt09lv7Hcser2QYV8t4muXbEr+Fwo0geYn79Xs4GKywrRQ==}
|
|
||||||
peerDependencies:
|
|
||||||
prosemirror-model: ^1.22.1
|
|
||||||
prosemirror-state: ^1.4.2
|
|
||||||
prosemirror-view: ^1.33.8
|
|
||||||
|
|
||||||
prosemirror-transform@1.11.0:
|
|
||||||
resolution: {integrity: sha512-4I7Ce4KpygXb9bkiPS3hTEk4dSHorfRw8uI0pE8IhxlK2GXsqv5tIA7JUSxtSu7u8APVOTtbUBxTmnHIxVkIJw==}
|
|
||||||
|
|
||||||
prosemirror-view@1.41.6:
|
|
||||||
resolution: {integrity: sha512-mxpcDG4hNQa/CPtzxjdlir5bJFDlm0/x5nGBbStB2BWX+XOQ9M8ekEG+ojqB5BcVu2Rc80/jssCMZzSstJuSYg==}
|
|
||||||
|
|
||||||
proxy-addr@2.0.7:
|
proxy-addr@2.0.7:
|
||||||
resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
|
resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
|
||||||
engines: {node: '>= 0.10'}
|
engines: {node: '>= 0.10'}
|
||||||
@ -5156,10 +4863,6 @@ packages:
|
|||||||
pump@3.0.3:
|
pump@3.0.3:
|
||||||
resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==}
|
resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==}
|
||||||
|
|
||||||
punycode.js@2.3.1:
|
|
||||||
resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==}
|
|
||||||
engines: {node: '>=6'}
|
|
||||||
|
|
||||||
punycode@2.3.1:
|
punycode@2.3.1:
|
||||||
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
|
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
@ -5623,9 +5326,6 @@ packages:
|
|||||||
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
rope-sequence@1.3.4:
|
|
||||||
resolution: {integrity: sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==}
|
|
||||||
|
|
||||||
router@2.2.0:
|
router@2.2.0:
|
||||||
resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==}
|
resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==}
|
||||||
engines: {node: '>= 18'}
|
engines: {node: '>= 18'}
|
||||||
@ -6204,9 +5904,6 @@ packages:
|
|||||||
engines: {node: '>=14.17'}
|
engines: {node: '>=14.17'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
uc.micro@2.1.0:
|
|
||||||
resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==}
|
|
||||||
|
|
||||||
ufo@1.6.3:
|
ufo@1.6.3:
|
||||||
resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==}
|
resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==}
|
||||||
|
|
||||||
@ -6282,11 +5979,6 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
react: '>= 16.x'
|
react: '>= 16.x'
|
||||||
|
|
||||||
use-sync-external-store@1.6.0:
|
|
||||||
resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==}
|
|
||||||
peerDependencies:
|
|
||||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
|
||||||
|
|
||||||
utf8-byte-length@1.0.5:
|
utf8-byte-length@1.0.5:
|
||||||
resolution: {integrity: sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==}
|
resolution: {integrity: sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==}
|
||||||
|
|
||||||
@ -7690,20 +7382,6 @@ snapshots:
|
|||||||
|
|
||||||
'@fastify/busboy@2.1.1': {}
|
'@fastify/busboy@2.1.1': {}
|
||||||
|
|
||||||
'@floating-ui/core@1.7.5':
|
|
||||||
dependencies:
|
|
||||||
'@floating-ui/utils': 0.2.11
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@floating-ui/dom@1.7.6':
|
|
||||||
dependencies:
|
|
||||||
'@floating-ui/core': 1.7.5
|
|
||||||
'@floating-ui/utils': 0.2.11
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@floating-ui/utils@0.2.11':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@humanfs/core@0.19.1': {}
|
'@humanfs/core@0.19.1': {}
|
||||||
|
|
||||||
'@humanfs/node@0.16.7':
|
'@humanfs/node@0.16.7':
|
||||||
@ -8067,8 +7745,6 @@ snapshots:
|
|||||||
react-dom: 19.2.4(react@19.2.4)
|
react-dom: 19.2.4(react@19.2.4)
|
||||||
react-is: 18.3.1
|
react-is: 18.3.1
|
||||||
|
|
||||||
'@remirror/core-constants@3.0.0': {}
|
|
||||||
|
|
||||||
'@rolldown/pluginutils@1.0.0-beta.53': {}
|
'@rolldown/pluginutils@1.0.0-beta.53': {}
|
||||||
|
|
||||||
'@rollup/pluginutils@4.2.1':
|
'@rollup/pluginutils@4.2.1':
|
||||||
@ -8255,193 +7931,6 @@ snapshots:
|
|||||||
'@tanstack/query-core': 5.90.20
|
'@tanstack/query-core': 5.90.20
|
||||||
react: 19.2.4
|
react: 19.2.4
|
||||||
|
|
||||||
'@tiptap/core@3.20.1(@tiptap/pm@3.20.1)':
|
|
||||||
dependencies:
|
|
||||||
'@tiptap/pm': 3.20.1
|
|
||||||
|
|
||||||
'@tiptap/extension-blockquote@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))':
|
|
||||||
dependencies:
|
|
||||||
'@tiptap/core': 3.20.1(@tiptap/pm@3.20.1)
|
|
||||||
|
|
||||||
'@tiptap/extension-bold@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))':
|
|
||||||
dependencies:
|
|
||||||
'@tiptap/core': 3.20.1(@tiptap/pm@3.20.1)
|
|
||||||
|
|
||||||
'@tiptap/extension-bubble-menu@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1)':
|
|
||||||
dependencies:
|
|
||||||
'@floating-ui/dom': 1.7.6
|
|
||||||
'@tiptap/core': 3.20.1(@tiptap/pm@3.20.1)
|
|
||||||
'@tiptap/pm': 3.20.1
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@tiptap/extension-bullet-list@3.20.1(@tiptap/extension-list@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1))':
|
|
||||||
dependencies:
|
|
||||||
'@tiptap/extension-list': 3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1)
|
|
||||||
|
|
||||||
'@tiptap/extension-code-block@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1)':
|
|
||||||
dependencies:
|
|
||||||
'@tiptap/core': 3.20.1(@tiptap/pm@3.20.1)
|
|
||||||
'@tiptap/pm': 3.20.1
|
|
||||||
|
|
||||||
'@tiptap/extension-code@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))':
|
|
||||||
dependencies:
|
|
||||||
'@tiptap/core': 3.20.1(@tiptap/pm@3.20.1)
|
|
||||||
|
|
||||||
'@tiptap/extension-document@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))':
|
|
||||||
dependencies:
|
|
||||||
'@tiptap/core': 3.20.1(@tiptap/pm@3.20.1)
|
|
||||||
|
|
||||||
'@tiptap/extension-dropcursor@3.20.1(@tiptap/extensions@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1))':
|
|
||||||
dependencies:
|
|
||||||
'@tiptap/extensions': 3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1)
|
|
||||||
|
|
||||||
'@tiptap/extension-floating-menu@3.20.1(@floating-ui/dom@1.7.6)(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1)':
|
|
||||||
dependencies:
|
|
||||||
'@floating-ui/dom': 1.7.6
|
|
||||||
'@tiptap/core': 3.20.1(@tiptap/pm@3.20.1)
|
|
||||||
'@tiptap/pm': 3.20.1
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@tiptap/extension-gapcursor@3.20.1(@tiptap/extensions@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1))':
|
|
||||||
dependencies:
|
|
||||||
'@tiptap/extensions': 3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1)
|
|
||||||
|
|
||||||
'@tiptap/extension-hard-break@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))':
|
|
||||||
dependencies:
|
|
||||||
'@tiptap/core': 3.20.1(@tiptap/pm@3.20.1)
|
|
||||||
|
|
||||||
'@tiptap/extension-heading@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))':
|
|
||||||
dependencies:
|
|
||||||
'@tiptap/core': 3.20.1(@tiptap/pm@3.20.1)
|
|
||||||
|
|
||||||
'@tiptap/extension-horizontal-rule@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1)':
|
|
||||||
dependencies:
|
|
||||||
'@tiptap/core': 3.20.1(@tiptap/pm@3.20.1)
|
|
||||||
'@tiptap/pm': 3.20.1
|
|
||||||
|
|
||||||
'@tiptap/extension-italic@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))':
|
|
||||||
dependencies:
|
|
||||||
'@tiptap/core': 3.20.1(@tiptap/pm@3.20.1)
|
|
||||||
|
|
||||||
'@tiptap/extension-link@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1)':
|
|
||||||
dependencies:
|
|
||||||
'@tiptap/core': 3.20.1(@tiptap/pm@3.20.1)
|
|
||||||
'@tiptap/pm': 3.20.1
|
|
||||||
linkifyjs: 4.3.2
|
|
||||||
|
|
||||||
'@tiptap/extension-list-item@3.20.1(@tiptap/extension-list@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1))':
|
|
||||||
dependencies:
|
|
||||||
'@tiptap/extension-list': 3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1)
|
|
||||||
|
|
||||||
'@tiptap/extension-list-keymap@3.20.1(@tiptap/extension-list@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1))':
|
|
||||||
dependencies:
|
|
||||||
'@tiptap/extension-list': 3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1)
|
|
||||||
|
|
||||||
'@tiptap/extension-list@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1)':
|
|
||||||
dependencies:
|
|
||||||
'@tiptap/core': 3.20.1(@tiptap/pm@3.20.1)
|
|
||||||
'@tiptap/pm': 3.20.1
|
|
||||||
|
|
||||||
'@tiptap/extension-ordered-list@3.20.1(@tiptap/extension-list@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1))':
|
|
||||||
dependencies:
|
|
||||||
'@tiptap/extension-list': 3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1)
|
|
||||||
|
|
||||||
'@tiptap/extension-paragraph@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))':
|
|
||||||
dependencies:
|
|
||||||
'@tiptap/core': 3.20.1(@tiptap/pm@3.20.1)
|
|
||||||
|
|
||||||
'@tiptap/extension-placeholder@3.20.1(@tiptap/extensions@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1))':
|
|
||||||
dependencies:
|
|
||||||
'@tiptap/extensions': 3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1)
|
|
||||||
|
|
||||||
'@tiptap/extension-strike@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))':
|
|
||||||
dependencies:
|
|
||||||
'@tiptap/core': 3.20.1(@tiptap/pm@3.20.1)
|
|
||||||
|
|
||||||
'@tiptap/extension-text@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))':
|
|
||||||
dependencies:
|
|
||||||
'@tiptap/core': 3.20.1(@tiptap/pm@3.20.1)
|
|
||||||
|
|
||||||
'@tiptap/extension-underline@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))':
|
|
||||||
dependencies:
|
|
||||||
'@tiptap/core': 3.20.1(@tiptap/pm@3.20.1)
|
|
||||||
|
|
||||||
'@tiptap/extensions@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1)':
|
|
||||||
dependencies:
|
|
||||||
'@tiptap/core': 3.20.1(@tiptap/pm@3.20.1)
|
|
||||||
'@tiptap/pm': 3.20.1
|
|
||||||
|
|
||||||
'@tiptap/markdown@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1)':
|
|
||||||
dependencies:
|
|
||||||
'@tiptap/core': 3.20.1(@tiptap/pm@3.20.1)
|
|
||||||
'@tiptap/pm': 3.20.1
|
|
||||||
marked: 17.0.4
|
|
||||||
|
|
||||||
'@tiptap/pm@3.20.1':
|
|
||||||
dependencies:
|
|
||||||
prosemirror-changeset: 2.4.0
|
|
||||||
prosemirror-collab: 1.3.1
|
|
||||||
prosemirror-commands: 1.7.1
|
|
||||||
prosemirror-dropcursor: 1.8.2
|
|
||||||
prosemirror-gapcursor: 1.4.0
|
|
||||||
prosemirror-history: 1.5.0
|
|
||||||
prosemirror-inputrules: 1.5.1
|
|
||||||
prosemirror-keymap: 1.2.3
|
|
||||||
prosemirror-markdown: 1.13.4
|
|
||||||
prosemirror-menu: 1.3.0
|
|
||||||
prosemirror-model: 1.25.4
|
|
||||||
prosemirror-schema-basic: 1.2.4
|
|
||||||
prosemirror-schema-list: 1.5.1
|
|
||||||
prosemirror-state: 1.4.4
|
|
||||||
prosemirror-tables: 1.8.5
|
|
||||||
prosemirror-trailing-node: 3.0.0(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.6)
|
|
||||||
prosemirror-transform: 1.11.0
|
|
||||||
prosemirror-view: 1.41.6
|
|
||||||
|
|
||||||
'@tiptap/react@3.20.1(@floating-ui/dom@1.7.6)(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1)(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
|
|
||||||
dependencies:
|
|
||||||
'@tiptap/core': 3.20.1(@tiptap/pm@3.20.1)
|
|
||||||
'@tiptap/pm': 3.20.1
|
|
||||||
'@types/react': 19.2.10
|
|
||||||
'@types/react-dom': 19.2.3(@types/react@19.2.10)
|
|
||||||
'@types/use-sync-external-store': 0.0.6
|
|
||||||
fast-equals: 5.4.0
|
|
||||||
react: 19.2.4
|
|
||||||
react-dom: 19.2.4(react@19.2.4)
|
|
||||||
use-sync-external-store: 1.6.0(react@19.2.4)
|
|
||||||
optionalDependencies:
|
|
||||||
'@tiptap/extension-bubble-menu': 3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1)
|
|
||||||
'@tiptap/extension-floating-menu': 3.20.1(@floating-ui/dom@1.7.6)(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1)
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- '@floating-ui/dom'
|
|
||||||
|
|
||||||
'@tiptap/starter-kit@3.20.1':
|
|
||||||
dependencies:
|
|
||||||
'@tiptap/core': 3.20.1(@tiptap/pm@3.20.1)
|
|
||||||
'@tiptap/extension-blockquote': 3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))
|
|
||||||
'@tiptap/extension-bold': 3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))
|
|
||||||
'@tiptap/extension-bullet-list': 3.20.1(@tiptap/extension-list@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1))
|
|
||||||
'@tiptap/extension-code': 3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))
|
|
||||||
'@tiptap/extension-code-block': 3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1)
|
|
||||||
'@tiptap/extension-document': 3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))
|
|
||||||
'@tiptap/extension-dropcursor': 3.20.1(@tiptap/extensions@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1))
|
|
||||||
'@tiptap/extension-gapcursor': 3.20.1(@tiptap/extensions@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1))
|
|
||||||
'@tiptap/extension-hard-break': 3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))
|
|
||||||
'@tiptap/extension-heading': 3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))
|
|
||||||
'@tiptap/extension-horizontal-rule': 3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1)
|
|
||||||
'@tiptap/extension-italic': 3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))
|
|
||||||
'@tiptap/extension-link': 3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1)
|
|
||||||
'@tiptap/extension-list': 3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1)
|
|
||||||
'@tiptap/extension-list-item': 3.20.1(@tiptap/extension-list@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1))
|
|
||||||
'@tiptap/extension-list-keymap': 3.20.1(@tiptap/extension-list@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1))
|
|
||||||
'@tiptap/extension-ordered-list': 3.20.1(@tiptap/extension-list@3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1))
|
|
||||||
'@tiptap/extension-paragraph': 3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))
|
|
||||||
'@tiptap/extension-strike': 3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))
|
|
||||||
'@tiptap/extension-text': 3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))
|
|
||||||
'@tiptap/extension-underline': 3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))
|
|
||||||
'@tiptap/extensions': 3.20.1(@tiptap/core@3.20.1(@tiptap/pm@3.20.1))(@tiptap/pm@3.20.1)
|
|
||||||
'@tiptap/pm': 3.20.1
|
|
||||||
|
|
||||||
'@trysound/sax@0.2.0': {}
|
'@trysound/sax@0.2.0': {}
|
||||||
|
|
||||||
'@tsparticles/basic@3.9.1':
|
'@tsparticles/basic@3.9.1':
|
||||||
@ -8793,19 +8282,10 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 22.19.7
|
'@types/node': 22.19.7
|
||||||
|
|
||||||
'@types/linkify-it@5.0.0': {}
|
|
||||||
|
|
||||||
'@types/markdown-it@14.1.2':
|
|
||||||
dependencies:
|
|
||||||
'@types/linkify-it': 5.0.0
|
|
||||||
'@types/mdurl': 2.0.0
|
|
||||||
|
|
||||||
'@types/mdast@4.0.4':
|
'@types/mdast@4.0.4':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/unist': 3.0.3
|
'@types/unist': 3.0.3
|
||||||
|
|
||||||
'@types/mdurl@2.0.0': {}
|
|
||||||
|
|
||||||
'@types/ms@2.1.0': {}
|
'@types/ms@2.1.0': {}
|
||||||
|
|
||||||
'@types/node@22.19.7':
|
'@types/node@22.19.7':
|
||||||
@ -8824,10 +8304,6 @@ snapshots:
|
|||||||
xmlbuilder: 15.1.1
|
xmlbuilder: 15.1.1
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@types/react-dom@19.2.3(@types/react@19.2.10)':
|
|
||||||
dependencies:
|
|
||||||
'@types/react': 19.2.10
|
|
||||||
|
|
||||||
'@types/react@19.2.10':
|
'@types/react@19.2.10':
|
||||||
dependencies:
|
dependencies:
|
||||||
csstype: 3.2.3
|
csstype: 3.2.3
|
||||||
@ -8842,8 +8318,6 @@ snapshots:
|
|||||||
|
|
||||||
'@types/unist@3.0.3': {}
|
'@types/unist@3.0.3': {}
|
||||||
|
|
||||||
'@types/use-sync-external-store@0.0.6': {}
|
|
||||||
|
|
||||||
'@types/verror@1.10.11':
|
'@types/verror@1.10.11':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@ -10720,8 +10194,6 @@ snapshots:
|
|||||||
|
|
||||||
fast-diff@1.3.0: {}
|
fast-diff@1.3.0: {}
|
||||||
|
|
||||||
fast-equals@5.4.0: {}
|
|
||||||
|
|
||||||
fast-glob@3.3.3:
|
fast-glob@3.3.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@nodelib/fs.stat': 2.0.5
|
'@nodelib/fs.stat': 2.0.5
|
||||||
@ -11467,12 +10939,6 @@ snapshots:
|
|||||||
|
|
||||||
lines-and-columns@1.2.4: {}
|
lines-and-columns@1.2.4: {}
|
||||||
|
|
||||||
linkify-it@5.0.0:
|
|
||||||
dependencies:
|
|
||||||
uc.micro: 2.1.0
|
|
||||||
|
|
||||||
linkifyjs@4.3.2: {}
|
|
||||||
|
|
||||||
load-json-file@2.0.0:
|
load-json-file@2.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
graceful-fs: 4.2.11
|
graceful-fs: 4.2.11
|
||||||
@ -11572,19 +11038,8 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
markdown-it@14.1.1:
|
|
||||||
dependencies:
|
|
||||||
argparse: 2.0.1
|
|
||||||
entities: 4.5.0
|
|
||||||
linkify-it: 5.0.0
|
|
||||||
mdurl: 2.0.0
|
|
||||||
punycode.js: 2.3.1
|
|
||||||
uc.micro: 2.1.0
|
|
||||||
|
|
||||||
markdown-table@3.0.4: {}
|
markdown-table@3.0.4: {}
|
||||||
|
|
||||||
marked@17.0.4: {}
|
|
||||||
|
|
||||||
matcher@3.0.0:
|
matcher@3.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
escape-string-regexp: 4.0.0
|
escape-string-regexp: 4.0.0
|
||||||
@ -11755,8 +11210,6 @@ snapshots:
|
|||||||
|
|
||||||
mdn-data@2.12.2: {}
|
mdn-data@2.12.2: {}
|
||||||
|
|
||||||
mdurl@2.0.0: {}
|
|
||||||
|
|
||||||
media-typer@1.1.0: {}
|
media-typer@1.1.0: {}
|
||||||
|
|
||||||
merge-descriptors@2.0.0: {}
|
merge-descriptors@2.0.0: {}
|
||||||
@ -12258,8 +11711,6 @@ snapshots:
|
|||||||
strip-ansi: 6.0.1
|
strip-ansi: 6.0.1
|
||||||
wcwidth: 1.0.1
|
wcwidth: 1.0.1
|
||||||
|
|
||||||
orderedmap@2.1.1: {}
|
|
||||||
|
|
||||||
own-keys@1.0.1:
|
own-keys@1.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
get-intrinsic: 1.3.0
|
get-intrinsic: 1.3.0
|
||||||
@ -12487,109 +11938,6 @@ snapshots:
|
|||||||
|
|
||||||
property-information@7.1.0: {}
|
property-information@7.1.0: {}
|
||||||
|
|
||||||
prosemirror-changeset@2.4.0:
|
|
||||||
dependencies:
|
|
||||||
prosemirror-transform: 1.11.0
|
|
||||||
|
|
||||||
prosemirror-collab@1.3.1:
|
|
||||||
dependencies:
|
|
||||||
prosemirror-state: 1.4.4
|
|
||||||
|
|
||||||
prosemirror-commands@1.7.1:
|
|
||||||
dependencies:
|
|
||||||
prosemirror-model: 1.25.4
|
|
||||||
prosemirror-state: 1.4.4
|
|
||||||
prosemirror-transform: 1.11.0
|
|
||||||
|
|
||||||
prosemirror-dropcursor@1.8.2:
|
|
||||||
dependencies:
|
|
||||||
prosemirror-state: 1.4.4
|
|
||||||
prosemirror-transform: 1.11.0
|
|
||||||
prosemirror-view: 1.41.6
|
|
||||||
|
|
||||||
prosemirror-gapcursor@1.4.0:
|
|
||||||
dependencies:
|
|
||||||
prosemirror-keymap: 1.2.3
|
|
||||||
prosemirror-model: 1.25.4
|
|
||||||
prosemirror-state: 1.4.4
|
|
||||||
prosemirror-view: 1.41.6
|
|
||||||
|
|
||||||
prosemirror-history@1.5.0:
|
|
||||||
dependencies:
|
|
||||||
prosemirror-state: 1.4.4
|
|
||||||
prosemirror-transform: 1.11.0
|
|
||||||
prosemirror-view: 1.41.6
|
|
||||||
rope-sequence: 1.3.4
|
|
||||||
|
|
||||||
prosemirror-inputrules@1.5.1:
|
|
||||||
dependencies:
|
|
||||||
prosemirror-state: 1.4.4
|
|
||||||
prosemirror-transform: 1.11.0
|
|
||||||
|
|
||||||
prosemirror-keymap@1.2.3:
|
|
||||||
dependencies:
|
|
||||||
prosemirror-state: 1.4.4
|
|
||||||
w3c-keyname: 2.2.8
|
|
||||||
|
|
||||||
prosemirror-markdown@1.13.4:
|
|
||||||
dependencies:
|
|
||||||
'@types/markdown-it': 14.1.2
|
|
||||||
markdown-it: 14.1.1
|
|
||||||
prosemirror-model: 1.25.4
|
|
||||||
|
|
||||||
prosemirror-menu@1.3.0:
|
|
||||||
dependencies:
|
|
||||||
crelt: 1.0.6
|
|
||||||
prosemirror-commands: 1.7.1
|
|
||||||
prosemirror-history: 1.5.0
|
|
||||||
prosemirror-state: 1.4.4
|
|
||||||
|
|
||||||
prosemirror-model@1.25.4:
|
|
||||||
dependencies:
|
|
||||||
orderedmap: 2.1.1
|
|
||||||
|
|
||||||
prosemirror-schema-basic@1.2.4:
|
|
||||||
dependencies:
|
|
||||||
prosemirror-model: 1.25.4
|
|
||||||
|
|
||||||
prosemirror-schema-list@1.5.1:
|
|
||||||
dependencies:
|
|
||||||
prosemirror-model: 1.25.4
|
|
||||||
prosemirror-state: 1.4.4
|
|
||||||
prosemirror-transform: 1.11.0
|
|
||||||
|
|
||||||
prosemirror-state@1.4.4:
|
|
||||||
dependencies:
|
|
||||||
prosemirror-model: 1.25.4
|
|
||||||
prosemirror-transform: 1.11.0
|
|
||||||
prosemirror-view: 1.41.6
|
|
||||||
|
|
||||||
prosemirror-tables@1.8.5:
|
|
||||||
dependencies:
|
|
||||||
prosemirror-keymap: 1.2.3
|
|
||||||
prosemirror-model: 1.25.4
|
|
||||||
prosemirror-state: 1.4.4
|
|
||||||
prosemirror-transform: 1.11.0
|
|
||||||
prosemirror-view: 1.41.6
|
|
||||||
|
|
||||||
prosemirror-trailing-node@3.0.0(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.6):
|
|
||||||
dependencies:
|
|
||||||
'@remirror/core-constants': 3.0.0
|
|
||||||
escape-string-regexp: 4.0.0
|
|
||||||
prosemirror-model: 1.25.4
|
|
||||||
prosemirror-state: 1.4.4
|
|
||||||
prosemirror-view: 1.41.6
|
|
||||||
|
|
||||||
prosemirror-transform@1.11.0:
|
|
||||||
dependencies:
|
|
||||||
prosemirror-model: 1.25.4
|
|
||||||
|
|
||||||
prosemirror-view@1.41.6:
|
|
||||||
dependencies:
|
|
||||||
prosemirror-model: 1.25.4
|
|
||||||
prosemirror-state: 1.4.4
|
|
||||||
prosemirror-transform: 1.11.0
|
|
||||||
|
|
||||||
proxy-addr@2.0.7:
|
proxy-addr@2.0.7:
|
||||||
dependencies:
|
dependencies:
|
||||||
forwarded: 0.2.0
|
forwarded: 0.2.0
|
||||||
@ -12602,8 +11950,6 @@ snapshots:
|
|||||||
end-of-stream: 1.4.5
|
end-of-stream: 1.4.5
|
||||||
once: 1.4.0
|
once: 1.4.0
|
||||||
|
|
||||||
punycode.js@2.3.1: {}
|
|
||||||
|
|
||||||
punycode@2.3.1: {}
|
punycode@2.3.1: {}
|
||||||
|
|
||||||
qs@6.14.1:
|
qs@6.14.1:
|
||||||
@ -13221,8 +12567,6 @@ snapshots:
|
|||||||
'@rollup/rollup-win32-x64-msvc': 4.57.1
|
'@rollup/rollup-win32-x64-msvc': 4.57.1
|
||||||
fsevents: 2.3.3
|
fsevents: 2.3.3
|
||||||
|
|
||||||
rope-sequence@1.3.4: {}
|
|
||||||
|
|
||||||
router@2.2.0:
|
router@2.2.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: 4.4.3
|
debug: 4.4.3
|
||||||
@ -13963,8 +13307,6 @@ snapshots:
|
|||||||
|
|
||||||
typescript@5.9.3: {}
|
typescript@5.9.3: {}
|
||||||
|
|
||||||
uc.micro@2.1.0: {}
|
|
||||||
|
|
||||||
ufo@1.6.3: {}
|
ufo@1.6.3: {}
|
||||||
|
|
||||||
unbox-primitive@1.1.0:
|
unbox-primitive@1.1.0:
|
||||||
@ -14056,10 +13398,6 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
react: 19.2.4
|
react: 19.2.4
|
||||||
|
|
||||||
use-sync-external-store@1.6.0(react@19.2.4):
|
|
||||||
dependencies:
|
|
||||||
react: 19.2.4
|
|
||||||
|
|
||||||
utf8-byte-length@1.0.5: {}
|
utf8-byte-length@1.0.5: {}
|
||||||
|
|
||||||
util-deprecate@1.0.2: {}
|
util-deprecate@1.0.2: {}
|
||||||
|
|||||||
121
src/App.jsx
@ -17,7 +17,6 @@ import {
|
|||||||
ElectronSpotlightContentPage
|
ElectronSpotlightContentPage
|
||||||
} from './components/Dashboard/context/SpotlightContext.jsx'
|
} from './components/Dashboard/context/SpotlightContext.jsx'
|
||||||
import { ActionsModalProvider } from './components/Dashboard/context/ActionsModalContext.jsx'
|
import { ActionsModalProvider } from './components/Dashboard/context/ActionsModalContext.jsx'
|
||||||
import MissingPlaceholder from './components/Dashboard/common/MissingPlaceholder.jsx'
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ThemeProvider,
|
ThemeProvider,
|
||||||
@ -26,10 +25,9 @@ import {
|
|||||||
import AppError from './components/App/AppError'
|
import AppError from './components/App/AppError'
|
||||||
import { ApiServerProvider } from './components/Dashboard/context/ApiServerContext.jsx'
|
import { ApiServerProvider } from './components/Dashboard/context/ApiServerContext.jsx'
|
||||||
import { NotificationProvider } from './components/Dashboard/context/NotificationContext.jsx'
|
import { NotificationProvider } from './components/Dashboard/context/NotificationContext.jsx'
|
||||||
import { ElectronProvider } from './components/Dashboard/context/ElectronContext.jsx'
|
import { ElectrobunProvider } from './components/Dashboard/context/ElectrobunContext.jsx'
|
||||||
import { MessageProvider } from './components/Dashboard/context/MessageContext.jsx'
|
import { MessageProvider } from './components/Dashboard/context/MessageContext.jsx'
|
||||||
import AuthCallback from './components/App/AuthCallback.jsx'
|
import AuthCallback from './components/App/AuthCallback.jsx'
|
||||||
import EmailNotificationTemplate from './components/Email/EmailNotificationTemplate.jsx'
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ProductionRoutes,
|
ProductionRoutes,
|
||||||
@ -55,17 +53,10 @@ const AppContent = () => {
|
|||||||
const Router = getRouter()
|
const Router = getRouter()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ConfigProvider
|
<ConfigProvider theme={themeConfig}>
|
||||||
theme={themeConfig}
|
|
||||||
renderEmpty={() => (
|
|
||||||
<div style={{ margin: '32px' }}>
|
|
||||||
<MissingPlaceholder message='No data.' hasBackground={false} />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<App>
|
<App>
|
||||||
<Router>
|
<Router>
|
||||||
<ElectronProvider>
|
<ElectrobunProvider>
|
||||||
<AuthProvider>
|
<AuthProvider>
|
||||||
<PrintServerProvider>
|
<PrintServerProvider>
|
||||||
<ApiServerProvider>
|
<ApiServerProvider>
|
||||||
@ -73,60 +64,56 @@ const AppContent = () => {
|
|||||||
<NotificationProvider>
|
<NotificationProvider>
|
||||||
<SpotlightProvider>
|
<SpotlightProvider>
|
||||||
<ActionsModalProvider>
|
<ActionsModalProvider>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route
|
<Route
|
||||||
path='/dashboard/electron/spotlightcontent'
|
path='/dashboard/electron/spotlightcontent'
|
||||||
element={
|
element={
|
||||||
<PrivateRoute
|
<PrivateRoute
|
||||||
component={() => (
|
component={() => (
|
||||||
<ElectronSpotlightContentPage />
|
<ElectronSpotlightContentPage />
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Route
|
<Route
|
||||||
path='/'
|
path='/'
|
||||||
element={
|
element={
|
||||||
<PrivateRoute
|
<PrivateRoute
|
||||||
component={() => (
|
component={() => (
|
||||||
<Navigate
|
<Navigate
|
||||||
to='/dashboard/production/overview'
|
to='/dashboard/production/overview'
|
||||||
replace
|
replace
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Route
|
<Route
|
||||||
path='/auth/callback'
|
path='/auth/callback'
|
||||||
element={<AuthCallback />}
|
element={<AuthCallback />}
|
||||||
/>
|
/>
|
||||||
<Route
|
<Route
|
||||||
path='/email/notification'
|
path='/dashboard'
|
||||||
element={<EmailNotificationTemplate />}
|
element={
|
||||||
/>
|
<PrivateRoute component={() => <Dashboard />} />
|
||||||
<Route
|
}
|
||||||
path='/dashboard'
|
>
|
||||||
element={
|
{ProductionRoutes}
|
||||||
<PrivateRoute component={() => <Dashboard />} />
|
{InventoryRoutes}
|
||||||
}
|
{FinanceRoutes}
|
||||||
>
|
{SalesRoutes}
|
||||||
{ProductionRoutes}
|
{ManagementRoutes}
|
||||||
{InventoryRoutes}
|
{DeveloperRoutes}
|
||||||
{FinanceRoutes}
|
</Route>
|
||||||
{SalesRoutes}
|
<Route
|
||||||
{ManagementRoutes}
|
path='*'
|
||||||
{DeveloperRoutes}
|
element={
|
||||||
</Route>
|
<AppError
|
||||||
<Route
|
message='Error 404. Page not found.'
|
||||||
path='*'
|
showRefresh={false}
|
||||||
element={
|
/>
|
||||||
<AppError
|
}
|
||||||
message='Error 404. Page not found.'
|
/>
|
||||||
showRefresh={false}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</Routes>
|
</Routes>
|
||||||
</ActionsModalProvider>
|
</ActionsModalProvider>
|
||||||
</SpotlightProvider>
|
</SpotlightProvider>
|
||||||
@ -135,7 +122,7 @@ const AppContent = () => {
|
|||||||
</ApiServerProvider>
|
</ApiServerProvider>
|
||||||
</PrintServerProvider>
|
</PrintServerProvider>
|
||||||
</AuthProvider>
|
</AuthProvider>
|
||||||
</ElectronProvider>
|
</ElectrobunProvider>
|
||||||
</Router>
|
</Router>
|
||||||
</App>
|
</App>
|
||||||
</ConfigProvider>
|
</ConfigProvider>
|
||||||
|
|||||||
157
src/bun/index.ts
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
import Electrobun, {
|
||||||
|
BrowserWindow,
|
||||||
|
BrowserView,
|
||||||
|
Utils,
|
||||||
|
GlobalShortcut,
|
||||||
|
ApplicationMenu
|
||||||
|
} from 'electrobun/bun'
|
||||||
|
import { join } from 'path'
|
||||||
|
import { type FarmControlRPCType } from '../shared/rpcTypes'
|
||||||
|
import { createMainWindow, getMainWindow } from './mainWindow'
|
||||||
|
import {
|
||||||
|
openSpotlightContentWindow,
|
||||||
|
registerGlobalShortcuts,
|
||||||
|
setupSpotlightRPC
|
||||||
|
} from './spotlightWindow'
|
||||||
|
|
||||||
|
// Auth session storage (file-based, keytar alternative for Bun)
|
||||||
|
const AUTH_FILE = join(Utils.paths.userData, 'auth-session.json')
|
||||||
|
|
||||||
|
async function readAuthSession(): Promise<object | null> {
|
||||||
|
try {
|
||||||
|
const f = Bun.file(AUTH_FILE)
|
||||||
|
if (!(await f.exists())) return null
|
||||||
|
const raw = await f.text()
|
||||||
|
return JSON.parse(raw) as object
|
||||||
|
} catch {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function writeAuthSession(session: object): Promise<boolean> {
|
||||||
|
try {
|
||||||
|
await Bun.write(AUTH_FILE, JSON.stringify(session))
|
||||||
|
return true
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('[auth] Failed to write session:', e)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function clearAuthSession(): Promise<boolean> {
|
||||||
|
try {
|
||||||
|
const f = Bun.file(AUTH_FILE)
|
||||||
|
if (await f.exists()) {
|
||||||
|
await Bun.write(AUTH_FILE, '{}')
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('[auth] Failed to clear session:', e)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const farmControlRPC = BrowserView.defineRPC<FarmControlRPCType>({
|
||||||
|
maxRequestTime: 5000,
|
||||||
|
handlers: {
|
||||||
|
requests: {
|
||||||
|
osInfo: () => ({ platform: process.platform }),
|
||||||
|
windowState: () => {
|
||||||
|
const win = getMainWindow()
|
||||||
|
if (!win || win.isDestroyed?.()) {
|
||||||
|
return { isFullScreen: false, isMaximized: false }
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
isFullScreen: win.isFullScreen?.(),
|
||||||
|
isMaximized: win.isMaximized?.()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
openExternalUrl: ({ url }) => {
|
||||||
|
Utils.openExternal(url)
|
||||||
|
},
|
||||||
|
openInternalUrl: ({ url }) => {
|
||||||
|
const win = getMainWindow()
|
||||||
|
if (!win || win.isDestroyed?.()) {
|
||||||
|
createMainWindow(farmControlRPC)
|
||||||
|
const newWin = getMainWindow()
|
||||||
|
if (newWin?.webview) {
|
||||||
|
newWin.webview.on?.('dom-ready', () => {
|
||||||
|
;(newWin.webview as any).rpc?.navigate?.({ url })
|
||||||
|
newWin.show?.()
|
||||||
|
newWin.focus?.()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else if (win.webview) {
|
||||||
|
;(win.webview as any).rpc?.navigate?.({ url })
|
||||||
|
win.show?.()
|
||||||
|
win.focus?.()
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
windowControl: ({ action }) => {
|
||||||
|
const win = getMainWindow()
|
||||||
|
if (!win) return
|
||||||
|
switch (action) {
|
||||||
|
case 'minimize':
|
||||||
|
win.minimize?.()
|
||||||
|
break
|
||||||
|
case 'maximize':
|
||||||
|
if (win.isMaximized?.()) {
|
||||||
|
win.unmaximize?.()
|
||||||
|
} else {
|
||||||
|
win.maximize?.()
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'close':
|
||||||
|
win.close?.()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
},
|
||||||
|
authSessionGet: () => readAuthSession(),
|
||||||
|
authSessionSet: ({ session }) => writeAuthSession(session),
|
||||||
|
authSessionClear: () => clearAuthSession(),
|
||||||
|
spotlightWindowResize: ({ height }) => setupSpotlightRPC(height)
|
||||||
|
},
|
||||||
|
messages: {}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
createMainWindow(farmControlRPC)
|
||||||
|
registerGlobalShortcuts()
|
||||||
|
|
||||||
|
// Application menu
|
||||||
|
const env = (process.env.NODE_ENV || 'development').trim()
|
||||||
|
if (env === 'development') {
|
||||||
|
ApplicationMenu.setApplicationMenu([
|
||||||
|
{
|
||||||
|
label: 'Developer',
|
||||||
|
submenu: [
|
||||||
|
{
|
||||||
|
label: 'Toggle Developer Tools',
|
||||||
|
accelerator:
|
||||||
|
process.platform === 'darwin' ? 'Alt+Command+I' : 'Ctrl+Shift+I',
|
||||||
|
action: 'toggle-devtools'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
])
|
||||||
|
} else {
|
||||||
|
ApplicationMenu.setApplicationMenu([])
|
||||||
|
}
|
||||||
|
|
||||||
|
// open-url for farmcontrol:// scheme
|
||||||
|
Electrobun.events.on('open-url', (e: { data: { url: string } }) => {
|
||||||
|
const url = e.data.url
|
||||||
|
if (url.startsWith('farmcontrol://app')) {
|
||||||
|
const redirectPath = url.replace('farmcontrol://app', '') || '/'
|
||||||
|
const win = getMainWindow()
|
||||||
|
if (win?.webview) {
|
||||||
|
;(win.webview as any).rpc?.navigate?.({ url: redirectPath })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Unregister shortcuts on quit
|
||||||
|
Electrobun.events.on('before-quit', () => {
|
||||||
|
GlobalShortcut.unregisterAll()
|
||||||
|
})
|
||||||
90
src/bun/mainWindow.ts
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
import Electrobun, { BrowserWindow, Utils } from 'electrobun/bun'
|
||||||
|
import { join } from 'path'
|
||||||
|
import type { FarmControlRPCType } from '../shared/rpcTypes'
|
||||||
|
|
||||||
|
let win: InstanceType<typeof BrowserWindow> | null = null
|
||||||
|
|
||||||
|
function getAppUrl(): string {
|
||||||
|
if (process.env.ELECTROBUN_START_URL || process.env.ELECTRON_START_URL) {
|
||||||
|
return (
|
||||||
|
process.env.ELECTROBUN_START_URL ||
|
||||||
|
process.env.ELECTRON_START_URL ||
|
||||||
|
'http://localhost:5173'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return 'views://main/index.html'
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupWindowEvents(
|
||||||
|
browserWindow: InstanceType<typeof BrowserWindow>,
|
||||||
|
rpc: any
|
||||||
|
): void {
|
||||||
|
if (!browserWindow) return
|
||||||
|
|
||||||
|
browserWindow.on?.('resize', () => {
|
||||||
|
const webview = browserWindow.webview
|
||||||
|
if (webview?.rpc) {
|
||||||
|
try {
|
||||||
|
;(webview.rpc as any).windowState?.({
|
||||||
|
isMaximized: browserWindow.isMaximized?.(),
|
||||||
|
isFullScreen: browserWindow.isFullScreen?.()
|
||||||
|
})
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Electrobun may use different event names - check docs
|
||||||
|
const sendWindowState = (state: { isMaximized?: boolean; isFullScreen?: boolean }) => {
|
||||||
|
const webview = browserWindow.webview
|
||||||
|
if (webview?.rpc) {
|
||||||
|
try {
|
||||||
|
;(webview.rpc as any).windowState?.(state)
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listen for maximize/unmaximize/fullscreen - Electrobun BrowserWindow events
|
||||||
|
browserWindow.on?.('maximize', () => sendWindowState({ isMaximized: true }))
|
||||||
|
browserWindow.on?.('unmaximize', () => sendWindowState({ isMaximized: false }))
|
||||||
|
browserWindow.on?.('enter-full-screen', () => sendWindowState({ isFullScreen: true }))
|
||||||
|
browserWindow.on?.('leave-full-screen', () => sendWindowState({ isFullScreen: false }))
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createMainWindow(rpc: any): void {
|
||||||
|
const url = getAppUrl()
|
||||||
|
|
||||||
|
win = new BrowserWindow({
|
||||||
|
title: 'Farm Control',
|
||||||
|
url,
|
||||||
|
frame: {
|
||||||
|
width: 1200,
|
||||||
|
height: 800
|
||||||
|
},
|
||||||
|
titleBarStyle: 'hiddenInset',
|
||||||
|
preload: 'views://preload/index.js',
|
||||||
|
rpc,
|
||||||
|
styleMask: {
|
||||||
|
Titled: true,
|
||||||
|
Closable: true,
|
||||||
|
Miniaturizable: true,
|
||||||
|
Resizable: true,
|
||||||
|
FullSizeContentView: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
setupWindowEvents(win, rpc)
|
||||||
|
|
||||||
|
// Handle window-all-closed
|
||||||
|
Electrobun.events.on('close', () => {
|
||||||
|
const wins = (BrowserWindow as any).getAll?.() ?? []
|
||||||
|
if (wins.length <= 1) {
|
||||||
|
if (process.platform !== 'darwin') {
|
||||||
|
Utils.quit?.()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getMainWindow(): InstanceType<typeof BrowserWindow> | null {
|
||||||
|
return win
|
||||||
|
}
|
||||||
80
src/bun/spotlightWindow.ts
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
import { BrowserWindow, GlobalShortcut } from 'electrobun/bun'
|
||||||
|
import { join } from 'path'
|
||||||
|
|
||||||
|
let spotlightWin: InstanceType<typeof BrowserWindow> | null = null
|
||||||
|
|
||||||
|
function getSpotlightRouteUrl(): string {
|
||||||
|
const routePath = '/dashboard/electron/spotlightcontent'
|
||||||
|
|
||||||
|
if (process.env.ELECTROBUN_START_URL || process.env.ELECTRON_START_URL) {
|
||||||
|
const base = String(
|
||||||
|
process.env.ELECTROBUN_START_URL || process.env.ELECTRON_START_URL
|
||||||
|
).replace(/\/$/, '')
|
||||||
|
return `${base}${routePath}`
|
||||||
|
}
|
||||||
|
|
||||||
|
return `views://main/index.html#${routePath}`
|
||||||
|
}
|
||||||
|
|
||||||
|
export function openSpotlightContentWindow(): void {
|
||||||
|
if (spotlightWin && !spotlightWin.isDestroyed?.()) {
|
||||||
|
spotlightWin.show?.()
|
||||||
|
spotlightWin.focus?.()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const target = getSpotlightRouteUrl()
|
||||||
|
|
||||||
|
spotlightWin = new BrowserWindow({
|
||||||
|
title: 'Spotlight',
|
||||||
|
url: target,
|
||||||
|
frame: {
|
||||||
|
width: 700,
|
||||||
|
height: 40
|
||||||
|
},
|
||||||
|
titleBarStyle: 'hidden',
|
||||||
|
transparent: true,
|
||||||
|
resizable: false
|
||||||
|
})
|
||||||
|
|
||||||
|
spotlightWin.on?.('close', (e: any) => {
|
||||||
|
if (e?.preventDefault) e.preventDefault()
|
||||||
|
if (spotlightWin && !spotlightWin.isDestroyed?.()) {
|
||||||
|
spotlightWin.hide?.()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
spotlightWin.on?.('blur', () => {
|
||||||
|
if (spotlightWin && !spotlightWin.isDestroyed?.()) {
|
||||||
|
spotlightWin.hide?.()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function registerGlobalShortcuts(): void {
|
||||||
|
try {
|
||||||
|
const success = GlobalShortcut.register('Alt+Shift+Q', () => {
|
||||||
|
openSpotlightContentWindow()
|
||||||
|
})
|
||||||
|
if (!success) {
|
||||||
|
console.warn('[GlobalShortcut] Failed to register Alt+Shift+Q')
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('[GlobalShortcut] Error:', (e as Error)?.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setupSpotlightRPC(height: number): boolean {
|
||||||
|
if (!spotlightWin || spotlightWin.isDestroyed?.()) return false
|
||||||
|
try {
|
||||||
|
const frame = spotlightWin.getFrame?.()
|
||||||
|
if (frame) {
|
||||||
|
spotlightWin.setSize?.(frame.width, height)
|
||||||
|
spotlightWin.center?.()
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('[spotlight] Failed to resize:', (e as Error)?.message)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,10 +1,15 @@
|
|||||||
|
import { useContext } from 'react'
|
||||||
import { Flex } from 'antd'
|
import { Flex } from 'antd'
|
||||||
import useCollapseState from '../hooks/useCollapseState'
|
import useCollapseState from '../hooks/useCollapseState'
|
||||||
import StatsDisplay from '../common/StatsDisplay'
|
import StatsDisplay from '../common/StatsDisplay'
|
||||||
import InfoCollapse from '../common/InfoCollapse'
|
import InfoCollapse from '../common/InfoCollapse'
|
||||||
import ScrollBox from '../common/ScrollBox'
|
import ScrollBox from '../common/ScrollBox'
|
||||||
|
|
||||||
|
import { ApiServerContext } from '../context/ApiServerContext'
|
||||||
|
|
||||||
const FinanceOverview = () => {
|
const FinanceOverview = () => {
|
||||||
|
const { connected } = useContext(ApiServerContext)
|
||||||
|
|
||||||
const [collapseState, updateCollapseState] = useCollapseState(
|
const [collapseState, updateCollapseState] = useCollapseState(
|
||||||
'FinanceOverview',
|
'FinanceOverview',
|
||||||
{
|
{
|
||||||
@ -13,6 +18,10 @@ const FinanceOverview = () => {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (!connected) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex
|
<Flex
|
||||||
gap='large'
|
gap='large'
|
||||||
|
|||||||
@ -5,12 +5,10 @@ import ObjectTable from '../common/ObjectTable'
|
|||||||
import PlusIcon from '../../Icons/PlusIcon'
|
import PlusIcon from '../../Icons/PlusIcon'
|
||||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
import ReloadIcon from '../../Icons/ReloadIcon'
|
||||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
import useColumnVisibility from '../hooks/useColumnVisibility'
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
import GridIcon from '../../Icons/GridIcon'
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
import ListIcon from '../../Icons/ListIcon'
|
||||||
import useViewMode from '../hooks/useViewMode'
|
import useViewMode from '../hooks/useViewMode'
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
import ColumnViewButton from '../common/ColumnViewButton'
|
import ColumnViewButton from '../common/ColumnViewButton'
|
||||||
import ExportListButton from '../common/ExportListButton'
|
|
||||||
|
|
||||||
const Invoices = () => {
|
const Invoices = () => {
|
||||||
const [newInvoiceOpen, setNewInvoiceOpen] = useState(false)
|
const [newInvoiceOpen, setNewInvoiceOpen] = useState(false)
|
||||||
@ -21,9 +19,6 @@ const Invoices = () => {
|
|||||||
const [columnVisibility, setColumnVisibility] =
|
const [columnVisibility, setColumnVisibility] =
|
||||||
useColumnVisibility('invoices')
|
useColumnVisibility('invoices')
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('Invoices')
|
|
||||||
|
|
||||||
const actionItems = {
|
const actionItems = {
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -49,7 +44,7 @@ const Invoices = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
<Flex vertical={'true'} gap='large'>
|
||||||
<Flex justify={'space-between'}>
|
<Flex justify={'space-between'}>
|
||||||
<Space size='small'>
|
<Space size='small'>
|
||||||
<Dropdown menu={actionItems}>
|
<Dropdown menu={actionItems}>
|
||||||
@ -61,16 +56,13 @@ const Invoices = () => {
|
|||||||
visibleState={columnVisibility}
|
visibleState={columnVisibility}
|
||||||
updateVisibleState={setColumnVisibility}
|
updateVisibleState={setColumnVisibility}
|
||||||
/>
|
/>
|
||||||
<ExportListButton objectType='invoice' />
|
|
||||||
</Space>
|
</Space>
|
||||||
<Space>
|
<Space>
|
||||||
<FilterSidebarButton
|
<Button
|
||||||
active={showFilterSidebar}
|
icon={viewMode === 'cards' ? <ListIcon /> : <GridIcon />}
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
onClick={() =>
|
||||||
/>
|
setViewMode(viewMode === 'cards' ? 'list' : 'cards')
|
||||||
<ObjectTableViewButton
|
}
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -79,7 +71,6 @@ const Invoices = () => {
|
|||||||
visibleColumns={columnVisibility}
|
visibleColumns={columnVisibility}
|
||||||
type='invoice'
|
type='invoice'
|
||||||
cards={viewMode === 'cards'}
|
cards={viewMode === 'cards'}
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Modal
|
<Modal
|
||||||
|
|||||||
@ -5,12 +5,10 @@ import ObjectTable from '../common/ObjectTable'
|
|||||||
import PlusIcon from '../../Icons/PlusIcon'
|
import PlusIcon from '../../Icons/PlusIcon'
|
||||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
import ReloadIcon from '../../Icons/ReloadIcon'
|
||||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
import useColumnVisibility from '../hooks/useColumnVisibility'
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
import GridIcon from '../../Icons/GridIcon'
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
import ListIcon from '../../Icons/ListIcon'
|
||||||
import useViewMode from '../hooks/useViewMode'
|
import useViewMode from '../hooks/useViewMode'
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
import ColumnViewButton from '../common/ColumnViewButton'
|
import ColumnViewButton from '../common/ColumnViewButton'
|
||||||
import ExportListButton from '../common/ExportListButton'
|
|
||||||
|
|
||||||
const Payments = () => {
|
const Payments = () => {
|
||||||
const [newPaymentOpen, setNewPaymentOpen] = useState(false)
|
const [newPaymentOpen, setNewPaymentOpen] = useState(false)
|
||||||
@ -21,9 +19,6 @@ const Payments = () => {
|
|||||||
const [columnVisibility, setColumnVisibility] =
|
const [columnVisibility, setColumnVisibility] =
|
||||||
useColumnVisibility('payments')
|
useColumnVisibility('payments')
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('Payments')
|
|
||||||
|
|
||||||
const actionItems = {
|
const actionItems = {
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -49,7 +44,7 @@ const Payments = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
<Flex vertical={'true'} gap='large'>
|
||||||
<Flex justify={'space-between'}>
|
<Flex justify={'space-between'}>
|
||||||
<Space size='small'>
|
<Space size='small'>
|
||||||
<Dropdown menu={actionItems}>
|
<Dropdown menu={actionItems}>
|
||||||
@ -61,16 +56,13 @@ const Payments = () => {
|
|||||||
visibleState={columnVisibility}
|
visibleState={columnVisibility}
|
||||||
updateVisibleState={setColumnVisibility}
|
updateVisibleState={setColumnVisibility}
|
||||||
/>
|
/>
|
||||||
<ExportListButton objectType='payment' />
|
|
||||||
</Space>
|
</Space>
|
||||||
<Space>
|
<Space>
|
||||||
<FilterSidebarButton
|
<Button
|
||||||
active={showFilterSidebar}
|
icon={viewMode === 'cards' ? <ListIcon /> : <GridIcon />}
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
onClick={() =>
|
||||||
/>
|
setViewMode(viewMode === 'cards' ? 'list' : 'cards')
|
||||||
<ObjectTableViewButton
|
}
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -79,7 +71,6 @@ const Payments = () => {
|
|||||||
visibleColumns={columnVisibility}
|
visibleColumns={columnVisibility}
|
||||||
type='payment'
|
type='payment'
|
||||||
cards={viewMode === 'cards'}
|
cards={viewMode === 'cards'}
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Modal
|
<Modal
|
||||||
|
|||||||
@ -9,12 +9,10 @@ import PlusIcon from '../../Icons/PlusIcon'
|
|||||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
import ReloadIcon from '../../Icons/ReloadIcon'
|
||||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
import useColumnVisibility from '../hooks/useColumnVisibility'
|
||||||
import ObjectTable from '../common/ObjectTable'
|
import ObjectTable from '../common/ObjectTable'
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
import ListIcon from '../../Icons/ListIcon'
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
import GridIcon from '../../Icons/GridIcon'
|
||||||
import useViewMode from '../hooks/useViewMode'
|
import useViewMode from '../hooks/useViewMode'
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
import ColumnViewButton from '../common/ColumnViewButton'
|
import ColumnViewButton from '../common/ColumnViewButton'
|
||||||
import ExportListButton from '../common/ExportListButton'
|
|
||||||
|
|
||||||
const FilamentStocks = () => {
|
const FilamentStocks = () => {
|
||||||
const tableRef = useRef()
|
const tableRef = useRef()
|
||||||
@ -26,9 +24,6 @@ const FilamentStocks = () => {
|
|||||||
const [columnVisibility, setColumnVisibility] =
|
const [columnVisibility, setColumnVisibility] =
|
||||||
useColumnVisibility('filamentStocks')
|
useColumnVisibility('filamentStocks')
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('FilamentStocks')
|
|
||||||
|
|
||||||
const actionItems = {
|
const actionItems = {
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -54,7 +49,7 @@ const FilamentStocks = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
<Flex vertical={'true'} gap='large'>
|
||||||
<Flex justify={'space-between'}>
|
<Flex justify={'space-between'}>
|
||||||
<Space size='small'>
|
<Space size='small'>
|
||||||
<Dropdown menu={actionItems}>
|
<Dropdown menu={actionItems}>
|
||||||
@ -66,16 +61,13 @@ const FilamentStocks = () => {
|
|||||||
visibleState={columnVisibility}
|
visibleState={columnVisibility}
|
||||||
updateVisibleState={setColumnVisibility}
|
updateVisibleState={setColumnVisibility}
|
||||||
/>
|
/>
|
||||||
<ExportListButton objectType='filamentStock' />
|
|
||||||
</Space>
|
</Space>
|
||||||
<Space>
|
<Space>
|
||||||
<FilterSidebarButton
|
<Button
|
||||||
active={showFilterSidebar}
|
icon={viewMode === 'cards' ? <ListIcon /> : <GridIcon />}
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
onClick={() =>
|
||||||
/>
|
setViewMode(viewMode === 'cards' ? 'list' : 'cards')
|
||||||
<ObjectTableViewButton
|
}
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -85,7 +77,6 @@ const FilamentStocks = () => {
|
|||||||
visibleColumns={columnVisibility}
|
visibleColumns={columnVisibility}
|
||||||
type='filamentStock'
|
type='filamentStock'
|
||||||
cards={viewMode === 'cards'}
|
cards={viewMode === 'cards'}
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Modal
|
<Modal
|
||||||
|
|||||||
@ -1,10 +1,15 @@
|
|||||||
|
import { useContext } from 'react'
|
||||||
import { Flex } from 'antd'
|
import { Flex } from 'antd'
|
||||||
import useCollapseState from '../hooks/useCollapseState'
|
import useCollapseState from '../hooks/useCollapseState'
|
||||||
import StatsDisplay from '../common/StatsDisplay'
|
import StatsDisplay from '../common/StatsDisplay'
|
||||||
import InfoCollapse from '../common/InfoCollapse'
|
import InfoCollapse from '../common/InfoCollapse'
|
||||||
import ScrollBox from '../common/ScrollBox'
|
import ScrollBox from '../common/ScrollBox'
|
||||||
|
|
||||||
|
import { ApiServerContext } from '../context/ApiServerContext'
|
||||||
|
|
||||||
const InventoryOverview = () => {
|
const InventoryOverview = () => {
|
||||||
|
const { connected } = useContext(ApiServerContext)
|
||||||
|
|
||||||
const [collapseState, updateCollapseState] = useCollapseState(
|
const [collapseState, updateCollapseState] = useCollapseState(
|
||||||
'InventoryOverview',
|
'InventoryOverview',
|
||||||
{
|
{
|
||||||
@ -13,6 +18,10 @@ const InventoryOverview = () => {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (!connected) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex
|
<Flex
|
||||||
gap='large'
|
gap='large'
|
||||||
|
|||||||
@ -5,12 +5,10 @@ import ObjectTable from '../common/ObjectTable'
|
|||||||
import PlusIcon from '../../Icons/PlusIcon'
|
import PlusIcon from '../../Icons/PlusIcon'
|
||||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
import ReloadIcon from '../../Icons/ReloadIcon'
|
||||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
import useColumnVisibility from '../hooks/useColumnVisibility'
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
import GridIcon from '../../Icons/GridIcon'
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
import ListIcon from '../../Icons/ListIcon'
|
||||||
import useViewMode from '../hooks/useViewMode'
|
import useViewMode from '../hooks/useViewMode'
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
import ColumnViewButton from '../common/ColumnViewButton'
|
import ColumnViewButton from '../common/ColumnViewButton'
|
||||||
import ExportListButton from '../common/ExportListButton'
|
|
||||||
|
|
||||||
const OrderItems = () => {
|
const OrderItems = () => {
|
||||||
const [newOrderItemOpen, setNewOrderItemOpen] = useState(false)
|
const [newOrderItemOpen, setNewOrderItemOpen] = useState(false)
|
||||||
@ -21,9 +19,6 @@ const OrderItems = () => {
|
|||||||
const [columnVisibility, setColumnVisibility] =
|
const [columnVisibility, setColumnVisibility] =
|
||||||
useColumnVisibility('orderItems')
|
useColumnVisibility('orderItems')
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('OrderItems')
|
|
||||||
|
|
||||||
const actionItems = {
|
const actionItems = {
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -49,7 +44,7 @@ const OrderItems = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
<Flex vertical={'true'} gap='large'>
|
||||||
<Flex justify={'space-between'}>
|
<Flex justify={'space-between'}>
|
||||||
<Space size='small'>
|
<Space size='small'>
|
||||||
<Dropdown menu={actionItems}>
|
<Dropdown menu={actionItems}>
|
||||||
@ -61,16 +56,13 @@ const OrderItems = () => {
|
|||||||
visibleState={columnVisibility}
|
visibleState={columnVisibility}
|
||||||
updateVisibleState={setColumnVisibility}
|
updateVisibleState={setColumnVisibility}
|
||||||
/>
|
/>
|
||||||
<ExportListButton objectType='orderItem' />
|
|
||||||
</Space>
|
</Space>
|
||||||
<Space>
|
<Space>
|
||||||
<FilterSidebarButton
|
<Button
|
||||||
active={showFilterSidebar}
|
icon={viewMode === 'cards' ? <ListIcon /> : <GridIcon />}
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
onClick={() =>
|
||||||
/>
|
setViewMode(viewMode === 'cards' ? 'list' : 'cards')
|
||||||
<ObjectTableViewButton
|
}
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -79,7 +71,6 @@ const OrderItems = () => {
|
|||||||
visibleColumns={columnVisibility}
|
visibleColumns={columnVisibility}
|
||||||
type='orderItem'
|
type='orderItem'
|
||||||
cards={viewMode === 'cards'}
|
cards={viewMode === 'cards'}
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Modal
|
<Modal
|
||||||
|
|||||||
@ -46,34 +46,6 @@ const NewOrderItem = ({ onOk, reset, defaultValues }) => {
|
|||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
|
||||||
title: 'Optional',
|
|
||||||
key: 'optional',
|
|
||||||
content: (
|
|
||||||
<ObjectInfo
|
|
||||||
type='orderItem'
|
|
||||||
column={1}
|
|
||||||
bordered={false}
|
|
||||||
isEditing={true}
|
|
||||||
required={false}
|
|
||||||
objectData={objectData}
|
|
||||||
visibleProperties={{
|
|
||||||
sku: true,
|
|
||||||
shipment: true,
|
|
||||||
invoicedAmount: false,
|
|
||||||
invoicedAmountWithTax: false,
|
|
||||||
invoicedQuantity: false,
|
|
||||||
invoicedAmountRemaining: false,
|
|
||||||
invoicedAmountWithTaxRemaining: false,
|
|
||||||
invoicedQuantityRemaining: false,
|
|
||||||
orderedAt: false,
|
|
||||||
receivedAt: false,
|
|
||||||
syncAmount: false
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
title: 'Pricing',
|
title: 'Pricing',
|
||||||
key: 'pricing',
|
key: 'pricing',
|
||||||
@ -95,6 +67,32 @@ const NewOrderItem = ({ onOk, reset, defaultValues }) => {
|
|||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: 'Optional',
|
||||||
|
key: 'optional',
|
||||||
|
content: (
|
||||||
|
<ObjectInfo
|
||||||
|
type='orderItem'
|
||||||
|
column={1}
|
||||||
|
bordered={false}
|
||||||
|
isEditing={true}
|
||||||
|
required={false}
|
||||||
|
objectData={objectData}
|
||||||
|
visibleProperties={{
|
||||||
|
shipment: true,
|
||||||
|
invoicedAmount: false,
|
||||||
|
invoicedAmountWithTax: false,
|
||||||
|
invoicedQuantity: false,
|
||||||
|
invoicedAmountRemaining: false,
|
||||||
|
invoicedAmountWithTaxRemaining: false,
|
||||||
|
invoicedQuantityRemaining: false,
|
||||||
|
orderedAt: false,
|
||||||
|
receivedAt: false,
|
||||||
|
syncAmount: false
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: 'Summary',
|
title: 'Summary',
|
||||||
key: 'summary',
|
key: 'summary',
|
||||||
|
|||||||
@ -9,12 +9,10 @@ import PlusIcon from '../../Icons/PlusIcon'
|
|||||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
import ReloadIcon from '../../Icons/ReloadIcon'
|
||||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
import useColumnVisibility from '../hooks/useColumnVisibility'
|
||||||
import ObjectTable from '../common/ObjectTable'
|
import ObjectTable from '../common/ObjectTable'
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
import ListIcon from '../../Icons/ListIcon'
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
import GridIcon from '../../Icons/GridIcon'
|
||||||
import useViewMode from '../hooks/useViewMode'
|
import useViewMode from '../hooks/useViewMode'
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
import ColumnViewButton from '../common/ColumnViewButton'
|
import ColumnViewButton from '../common/ColumnViewButton'
|
||||||
import ExportListButton from '../common/ExportListButton'
|
|
||||||
|
|
||||||
const PartStocks = () => {
|
const PartStocks = () => {
|
||||||
const tableRef = useRef()
|
const tableRef = useRef()
|
||||||
@ -26,9 +24,6 @@ const PartStocks = () => {
|
|||||||
const [columnVisibility, setColumnVisibility] =
|
const [columnVisibility, setColumnVisibility] =
|
||||||
useColumnVisibility('partStocks')
|
useColumnVisibility('partStocks')
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('PartStocks')
|
|
||||||
|
|
||||||
const actionItems = {
|
const actionItems = {
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -54,7 +49,7 @@ const PartStocks = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
<Flex vertical={'true'} gap='large'>
|
||||||
<Flex justify={'space-between'}>
|
<Flex justify={'space-between'}>
|
||||||
<Space size='small'>
|
<Space size='small'>
|
||||||
<Dropdown menu={actionItems}>
|
<Dropdown menu={actionItems}>
|
||||||
@ -66,16 +61,13 @@ const PartStocks = () => {
|
|||||||
visibleState={columnVisibility}
|
visibleState={columnVisibility}
|
||||||
updateVisibleState={setColumnVisibility}
|
updateVisibleState={setColumnVisibility}
|
||||||
/>
|
/>
|
||||||
<ExportListButton objectType='partStock' />
|
|
||||||
</Space>
|
</Space>
|
||||||
<Space>
|
<Space>
|
||||||
<FilterSidebarButton
|
<Button
|
||||||
active={showFilterSidebar}
|
icon={viewMode === 'cards' ? <ListIcon /> : <GridIcon />}
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
onClick={() =>
|
||||||
/>
|
setViewMode(viewMode === 'cards' ? 'list' : 'cards')
|
||||||
<ObjectTableViewButton
|
}
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -85,7 +77,6 @@ const PartStocks = () => {
|
|||||||
visibleColumns={columnVisibility}
|
visibleColumns={columnVisibility}
|
||||||
type='partStock'
|
type='partStock'
|
||||||
cards={viewMode === 'cards'}
|
cards={viewMode === 'cards'}
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Modal
|
<Modal
|
||||||
|
|||||||
@ -1,114 +0,0 @@
|
|||||||
// src/components/Dashboard/Inventory/ProductStocks.jsx
|
|
||||||
// ProductStocks - tracks assembled products consisting of part stocks
|
|
||||||
|
|
||||||
import { useState, useRef } from 'react'
|
|
||||||
|
|
||||||
import { Button, Flex, Space, Modal, Dropdown } from 'antd'
|
|
||||||
|
|
||||||
import NewProductStock from './ProductStocks/NewProductStock'
|
|
||||||
import PlusIcon from '../../Icons/PlusIcon'
|
|
||||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
|
||||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
|
||||||
import ObjectTable from '../common/ObjectTable'
|
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
|
||||||
import useViewMode from '../hooks/useViewMode'
|
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
import ColumnViewButton from '../common/ColumnViewButton'
|
|
||||||
import ExportListButton from '../common/ExportListButton'
|
|
||||||
|
|
||||||
const ProductStocks = () => {
|
|
||||||
const tableRef = useRef()
|
|
||||||
|
|
||||||
const [newProductStockOpen, setNewProductStockOpen] = useState(false)
|
|
||||||
|
|
||||||
const [viewMode, setViewMode] = useViewMode('productStocks')
|
|
||||||
|
|
||||||
const [columnVisibility, setColumnVisibility] =
|
|
||||||
useColumnVisibility('productStock')
|
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('ProductStocks')
|
|
||||||
|
|
||||||
const actionItems = {
|
|
||||||
items: [
|
|
||||||
{
|
|
||||||
label: 'New Product Stock',
|
|
||||||
key: 'newProductStock',
|
|
||||||
icon: <PlusIcon />
|
|
||||||
},
|
|
||||||
{ type: 'divider' },
|
|
||||||
{
|
|
||||||
label: 'Reload List',
|
|
||||||
key: 'reloadList',
|
|
||||||
icon: <ReloadIcon />
|
|
||||||
}
|
|
||||||
],
|
|
||||||
onClick: ({ key }) => {
|
|
||||||
if (key === 'reloadList') {
|
|
||||||
tableRef.current?.reload()
|
|
||||||
} else if (key === 'newProductStock') {
|
|
||||||
setNewProductStockOpen(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
|
||||||
<Flex justify={'space-between'}>
|
|
||||||
<Space size='small'>
|
|
||||||
<Dropdown menu={actionItems}>
|
|
||||||
<Button>Actions</Button>
|
|
||||||
</Dropdown>
|
|
||||||
<ColumnViewButton
|
|
||||||
type='productStock'
|
|
||||||
loading={false}
|
|
||||||
visibleState={columnVisibility}
|
|
||||||
updateVisibleState={setColumnVisibility}
|
|
||||||
/>
|
|
||||||
<ExportListButton objectType='productStock' />
|
|
||||||
</Space>
|
|
||||||
<Space>
|
|
||||||
<FilterSidebarButton
|
|
||||||
active={showFilterSidebar}
|
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
|
||||||
/>
|
|
||||||
<ObjectTableViewButton
|
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
|
||||||
</Space>
|
|
||||||
</Flex>
|
|
||||||
|
|
||||||
<ObjectTable
|
|
||||||
ref={tableRef}
|
|
||||||
visibleColumns={columnVisibility}
|
|
||||||
type='productStock'
|
|
||||||
cards={viewMode === 'cards'}
|
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
|
||||||
</Flex>
|
|
||||||
<Modal
|
|
||||||
open={newProductStockOpen}
|
|
||||||
styles={{ content: { paddingBottom: '24px' } }}
|
|
||||||
footer={null}
|
|
||||||
width={800}
|
|
||||||
onCancel={() => {
|
|
||||||
setNewProductStockOpen(false)
|
|
||||||
}}
|
|
||||||
destroyOnHidden={true}
|
|
||||||
>
|
|
||||||
<NewProductStock
|
|
||||||
onOk={() => {
|
|
||||||
setNewProductStockOpen(false)
|
|
||||||
tableRef.current?.reload()
|
|
||||||
}}
|
|
||||||
reset={newProductStockOpen}
|
|
||||||
/>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ProductStocks
|
|
||||||
@ -1,77 +0,0 @@
|
|||||||
import PropTypes from 'prop-types'
|
|
||||||
import ObjectInfo from '../../common/ObjectInfo'
|
|
||||||
import NewObjectForm from '../../common/NewObjectForm'
|
|
||||||
import WizardView from '../../common/WizardView'
|
|
||||||
|
|
||||||
const NewProductStock = ({ onOk, reset, defaultValues }) => {
|
|
||||||
return (
|
|
||||||
<NewObjectForm
|
|
||||||
type={'productStock'}
|
|
||||||
reset={reset}
|
|
||||||
defaultValues={{ state: { type: 'draft' }, ...defaultValues }}
|
|
||||||
>
|
|
||||||
{({ handleSubmit, submitLoading, objectData, formValid }) => {
|
|
||||||
const steps = [
|
|
||||||
{
|
|
||||||
title: 'Required',
|
|
||||||
key: 'required',
|
|
||||||
content: (
|
|
||||||
<ObjectInfo
|
|
||||||
type='productStock'
|
|
||||||
column={1}
|
|
||||||
bordered={false}
|
|
||||||
isEditing={true}
|
|
||||||
required={true}
|
|
||||||
objectData={objectData}
|
|
||||||
visibleProperties={{
|
|
||||||
partStocks: false
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Summary',
|
|
||||||
key: 'summary',
|
|
||||||
content: (
|
|
||||||
<ObjectInfo
|
|
||||||
type='productStock'
|
|
||||||
column={1}
|
|
||||||
bordered={false}
|
|
||||||
visibleProperties={{
|
|
||||||
_id: false,
|
|
||||||
createdAt: false,
|
|
||||||
updatedAt: false,
|
|
||||||
partStocks: false
|
|
||||||
}}
|
|
||||||
isEditing={false}
|
|
||||||
objectData={objectData}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
]
|
|
||||||
return (
|
|
||||||
<WizardView
|
|
||||||
steps={steps}
|
|
||||||
loading={submitLoading}
|
|
||||||
formValid={formValid}
|
|
||||||
title='New Product Stock'
|
|
||||||
onSubmit={async () => {
|
|
||||||
const result = await handleSubmit()
|
|
||||||
if (result) {
|
|
||||||
onOk()
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
</NewObjectForm>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
NewProductStock.propTypes = {
|
|
||||||
onOk: PropTypes.func.isRequired,
|
|
||||||
reset: PropTypes.bool,
|
|
||||||
defaultValues: PropTypes.object
|
|
||||||
}
|
|
||||||
|
|
||||||
export default NewProductStock
|
|
||||||
@ -1,46 +0,0 @@
|
|||||||
import { useState, useContext } from 'react'
|
|
||||||
import PropTypes from 'prop-types'
|
|
||||||
import { ApiServerContext } from '../../context/ApiServerContext'
|
|
||||||
import { message } from 'antd'
|
|
||||||
import MessageDialogView from '../../common/MessageDialogView.jsx'
|
|
||||||
|
|
||||||
const PostProductStock = ({ onOk, objectData }) => {
|
|
||||||
const [postLoading, setPostLoading] = useState(false)
|
|
||||||
const { sendObjectFunction } = useContext(ApiServerContext)
|
|
||||||
|
|
||||||
const handlePost = async () => {
|
|
||||||
setPostLoading(true)
|
|
||||||
try {
|
|
||||||
const result = await sendObjectFunction(
|
|
||||||
objectData._id,
|
|
||||||
'ProductStock',
|
|
||||||
'post'
|
|
||||||
)
|
|
||||||
if (result) {
|
|
||||||
message.success('Product stock posted successfully')
|
|
||||||
onOk(result)
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error posting product stock:', error)
|
|
||||||
} finally {
|
|
||||||
setPostLoading(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<MessageDialogView
|
|
||||||
title={'Are you sure you want to post this product stock?'}
|
|
||||||
description={`Posting product stock ${objectData?.name || objectData?._reference || objectData?._id} will finalize it and make it read-only.`}
|
|
||||||
onOk={handlePost}
|
|
||||||
okText='Post'
|
|
||||||
okLoading={postLoading}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
PostProductStock.propTypes = {
|
|
||||||
onOk: PropTypes.func.isRequired,
|
|
||||||
objectData: PropTypes.object
|
|
||||||
}
|
|
||||||
|
|
||||||
export default PostProductStock
|
|
||||||
@ -1,274 +0,0 @@
|
|||||||
import { useRef, useState } from 'react'
|
|
||||||
import { useLocation } from 'react-router-dom'
|
|
||||||
import { Space, Flex, Card, Modal } from 'antd'
|
|
||||||
import { LoadingOutlined } from '@ant-design/icons'
|
|
||||||
import loglevel from 'loglevel'
|
|
||||||
import config from '../../../../config.js'
|
|
||||||
import useCollapseState from '../../hooks/useCollapseState.jsx'
|
|
||||||
import NotesPanel from '../../common/NotesPanel.jsx'
|
|
||||||
import InfoCollapse from '../../common/InfoCollapse.jsx'
|
|
||||||
import ObjectInfo from '../../common/ObjectInfo.jsx'
|
|
||||||
import ObjectProperty from '../../common/ObjectProperty.jsx'
|
|
||||||
import ViewButton from '../../common/ViewButton.jsx'
|
|
||||||
import { getModelProperty, getModelByName } from '../../../../database/ObjectModels.js'
|
|
||||||
import PostProductStock from './PostProductStock.jsx'
|
|
||||||
import InfoCircleIcon from '../../../Icons/InfoCircleIcon.jsx'
|
|
||||||
import NoteIcon from '../../../Icons/NoteIcon.jsx'
|
|
||||||
import AuditLogIcon from '../../../Icons/AuditLogIcon.jsx'
|
|
||||||
import PartStockIcon from '../../../Icons/PartStockIcon.jsx'
|
|
||||||
import ObjectForm from '../../common/ObjectForm.jsx'
|
|
||||||
import EditButtons from '../../common/EditButtons.jsx'
|
|
||||||
import LockIndicator from '../../common/LockIndicator.jsx'
|
|
||||||
import ActionHandler from '../../common/ActionHandler.jsx'
|
|
||||||
import ObjectActions from '../../common/ObjectActions.jsx'
|
|
||||||
import ObjectTable from '../../common/ObjectTable.jsx'
|
|
||||||
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
|
|
||||||
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
|
|
||||||
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
|
|
||||||
import ScrollBox from '../../common/ScrollBox.jsx'
|
|
||||||
|
|
||||||
const log = loglevel.getLogger('ProductStockInfo')
|
|
||||||
log.setLevel(config.logLevel)
|
|
||||||
|
|
||||||
const ProductStockInfo = () => {
|
|
||||||
const location = useLocation()
|
|
||||||
const objectFormRef = useRef(null)
|
|
||||||
const actionHandlerRef = useRef(null)
|
|
||||||
const productStockId = new URLSearchParams(location.search).get(
|
|
||||||
'productStockId'
|
|
||||||
)
|
|
||||||
const [postProductStockOpen, setPostProductStockOpen] = useState(false)
|
|
||||||
const [collapseState, updateCollapseState] = useCollapseState(
|
|
||||||
'ProductStockInfo',
|
|
||||||
{
|
|
||||||
info: true,
|
|
||||||
partStocks: true,
|
|
||||||
notes: true,
|
|
||||||
auditLogs: true
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
const [objectFormState, setEditFormState] = useState({
|
|
||||||
isEditing: false,
|
|
||||||
editLoading: false,
|
|
||||||
formValid: false,
|
|
||||||
locked: false,
|
|
||||||
loading: false,
|
|
||||||
objectData: {}
|
|
||||||
})
|
|
||||||
|
|
||||||
const actions = {
|
|
||||||
reload: () => {
|
|
||||||
objectFormRef?.current.handleFetchObject()
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
edit: () => {
|
|
||||||
objectFormRef?.current.startEditing()
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
cancelEdit: () => {
|
|
||||||
objectFormRef?.current.cancelEditing()
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
finishEdit: () => {
|
|
||||||
objectFormRef?.current.handleUpdate()
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
delete: () => {
|
|
||||||
objectFormRef?.current.handleDelete?.()
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
post: () => {
|
|
||||||
setPostProductStockOpen(true)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const editDisabled =
|
|
||||||
getModelByName('productStock')
|
|
||||||
?.actions?.find((action) => action.name === 'edit')
|
|
||||||
?.disabled(objectFormState.objectData) ?? false
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Flex
|
|
||||||
gap='large'
|
|
||||||
vertical='true'
|
|
||||||
style={{
|
|
||||||
maxHeight: '100%',
|
|
||||||
minHeight: 0
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Flex justify={'space-between'}>
|
|
||||||
<Space size='middle'>
|
|
||||||
<Space size='small'>
|
|
||||||
<ObjectActions
|
|
||||||
type='productStock'
|
|
||||||
id={productStockId}
|
|
||||||
disabled={objectFormState.loading}
|
|
||||||
objectData={objectFormState.objectData}
|
|
||||||
/>
|
|
||||||
<ViewButton
|
|
||||||
disabled={objectFormState.loading}
|
|
||||||
items={[
|
|
||||||
{ key: 'info', label: 'Product Stock Information' },
|
|
||||||
{ key: 'partStocks', label: 'Part Stocks' },
|
|
||||||
{ key: 'notes', label: 'Notes' },
|
|
||||||
{ key: 'auditLogs', label: 'Audit Logs' }
|
|
||||||
]}
|
|
||||||
visibleState={collapseState}
|
|
||||||
updateVisibleState={updateCollapseState}
|
|
||||||
/>
|
|
||||||
<UserNotifierToggle
|
|
||||||
type='productStock'
|
|
||||||
objectData={objectFormState.objectData}
|
|
||||||
disabled={objectFormState.loading}
|
|
||||||
/>
|
|
||||||
<DocumentPrintButton
|
|
||||||
type='productStock'
|
|
||||||
objectData={objectFormState.objectData}
|
|
||||||
disabled={objectFormState.loading}
|
|
||||||
/>
|
|
||||||
</Space>
|
|
||||||
<LockIndicator lock={objectFormState.lock} />
|
|
||||||
</Space>
|
|
||||||
<Space>
|
|
||||||
<EditButtons
|
|
||||||
isEditing={objectFormState.isEditing}
|
|
||||||
handleUpdate={() => {
|
|
||||||
actionHandlerRef.current.callAction('finishEdit')
|
|
||||||
}}
|
|
||||||
cancelEditing={() => {
|
|
||||||
actionHandlerRef.current.callAction('cancelEdit')
|
|
||||||
}}
|
|
||||||
startEditing={() => {
|
|
||||||
actionHandlerRef.current.callAction('edit')
|
|
||||||
}}
|
|
||||||
editLoading={objectFormState.editLoading}
|
|
||||||
formValid={objectFormState.formValid}
|
|
||||||
disabled={
|
|
||||||
objectFormState.lock?.locked ||
|
|
||||||
objectFormState.loading ||
|
|
||||||
editDisabled
|
|
||||||
}
|
|
||||||
loading={objectFormState.editLoading}
|
|
||||||
/>
|
|
||||||
</Space>
|
|
||||||
</Flex>
|
|
||||||
|
|
||||||
<ScrollBox>
|
|
||||||
<Flex vertical gap={'large'}>
|
|
||||||
<ActionHandler
|
|
||||||
actions={actions}
|
|
||||||
loading={objectFormState.loading}
|
|
||||||
ref={actionHandlerRef}
|
|
||||||
>
|
|
||||||
<ObjectForm
|
|
||||||
id={productStockId}
|
|
||||||
type='productStock'
|
|
||||||
style={{ height: '100%' }}
|
|
||||||
ref={objectFormRef}
|
|
||||||
onStateChange={(state) => {
|
|
||||||
setEditFormState((prev) => ({ ...prev, ...state }))
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{({ loading, isEditing, objectData }) => (
|
|
||||||
<Flex vertical gap={'large'}>
|
|
||||||
<InfoCollapse
|
|
||||||
title='Product Stock Information'
|
|
||||||
icon={<InfoCircleIcon />}
|
|
||||||
active={collapseState.info}
|
|
||||||
onToggle={(expanded) =>
|
|
||||||
updateCollapseState('info', expanded)
|
|
||||||
}
|
|
||||||
collapseKey='info'
|
|
||||||
>
|
|
||||||
<ObjectInfo
|
|
||||||
loading={loading}
|
|
||||||
indicator={<LoadingOutlined />}
|
|
||||||
isEditing={isEditing}
|
|
||||||
type='productStock'
|
|
||||||
objectData={objectData}
|
|
||||||
labelWidth='175px'
|
|
||||||
visibleProperties={{ partStocks: false }}
|
|
||||||
/>
|
|
||||||
</InfoCollapse>
|
|
||||||
<InfoCollapse
|
|
||||||
title='Part Stocks'
|
|
||||||
icon={<PartStockIcon />}
|
|
||||||
active={collapseState.partStocks}
|
|
||||||
onToggle={(expanded) =>
|
|
||||||
updateCollapseState('partStocks', expanded)
|
|
||||||
}
|
|
||||||
collapseKey='partStocks'
|
|
||||||
>
|
|
||||||
<ObjectProperty
|
|
||||||
{...getModelProperty('productStock', 'partStocks')}
|
|
||||||
isEditing={isEditing}
|
|
||||||
objectData={objectData}
|
|
||||||
loading={loading}
|
|
||||||
size='medium'
|
|
||||||
/>
|
|
||||||
</InfoCollapse>
|
|
||||||
</Flex>
|
|
||||||
)}
|
|
||||||
</ObjectForm>
|
|
||||||
</ActionHandler>
|
|
||||||
|
|
||||||
<InfoCollapse
|
|
||||||
title='Notes'
|
|
||||||
icon={<NoteIcon />}
|
|
||||||
active={collapseState.notes}
|
|
||||||
onToggle={(expanded) => updateCollapseState('notes', expanded)}
|
|
||||||
collapseKey='notes'
|
|
||||||
>
|
|
||||||
<Card>
|
|
||||||
<NotesPanel _id={productStockId} type='productStock' />
|
|
||||||
</Card>
|
|
||||||
</InfoCollapse>
|
|
||||||
|
|
||||||
<InfoCollapse
|
|
||||||
title='Audit Logs'
|
|
||||||
icon={<AuditLogIcon />}
|
|
||||||
active={collapseState.auditLogs}
|
|
||||||
onToggle={(expanded) =>
|
|
||||||
updateCollapseState('auditLogs', expanded)
|
|
||||||
}
|
|
||||||
collapseKey='auditLogs'
|
|
||||||
>
|
|
||||||
{objectFormState.loading ? (
|
|
||||||
<InfoCollapsePlaceholder />
|
|
||||||
) : (
|
|
||||||
<ObjectTable
|
|
||||||
type='auditLog'
|
|
||||||
masterFilter={{ 'parent._id': productStockId }}
|
|
||||||
visibleColumns={{ _id: false, 'parent._id': false }}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</InfoCollapse>
|
|
||||||
</Flex>
|
|
||||||
</ScrollBox>
|
|
||||||
</Flex>
|
|
||||||
<Modal
|
|
||||||
open={postProductStockOpen}
|
|
||||||
onCancel={() => {
|
|
||||||
setPostProductStockOpen(false)
|
|
||||||
}}
|
|
||||||
width={500}
|
|
||||||
footer={null}
|
|
||||||
destroyOnHidden={true}
|
|
||||||
centered={true}
|
|
||||||
>
|
|
||||||
<PostProductStock
|
|
||||||
onOk={() => {
|
|
||||||
setPostProductStockOpen(false)
|
|
||||||
actions.reload()
|
|
||||||
}}
|
|
||||||
objectData={objectFormState.objectData}
|
|
||||||
/>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ProductStockInfo
|
|
||||||
@ -5,12 +5,10 @@ import ObjectTable from '../common/ObjectTable'
|
|||||||
import PlusIcon from '../../Icons/PlusIcon'
|
import PlusIcon from '../../Icons/PlusIcon'
|
||||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
import ReloadIcon from '../../Icons/ReloadIcon'
|
||||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
import useColumnVisibility from '../hooks/useColumnVisibility'
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
import GridIcon from '../../Icons/GridIcon'
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
import ListIcon from '../../Icons/ListIcon'
|
||||||
import useViewMode from '../hooks/useViewMode'
|
import useViewMode from '../hooks/useViewMode'
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
import ColumnViewButton from '../common/ColumnViewButton'
|
import ColumnViewButton from '../common/ColumnViewButton'
|
||||||
import ExportListButton from '../common/ExportListButton'
|
|
||||||
|
|
||||||
const PurchaseOrders = () => {
|
const PurchaseOrders = () => {
|
||||||
const [newPurchaseOrderOpen, setNewPurchaseOrderOpen] = useState(false)
|
const [newPurchaseOrderOpen, setNewPurchaseOrderOpen] = useState(false)
|
||||||
@ -21,9 +19,6 @@ const PurchaseOrders = () => {
|
|||||||
const [columnVisibility, setColumnVisibility] =
|
const [columnVisibility, setColumnVisibility] =
|
||||||
useColumnVisibility('purchaseOrders')
|
useColumnVisibility('purchaseOrders')
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('PurchaseOrders')
|
|
||||||
|
|
||||||
const actionItems = {
|
const actionItems = {
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -49,7 +44,7 @@ const PurchaseOrders = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
<Flex vertical={'true'} gap='large'>
|
||||||
<Flex justify={'space-between'}>
|
<Flex justify={'space-between'}>
|
||||||
<Space size='small'>
|
<Space size='small'>
|
||||||
<Dropdown menu={actionItems}>
|
<Dropdown menu={actionItems}>
|
||||||
@ -61,16 +56,13 @@ const PurchaseOrders = () => {
|
|||||||
visibleState={columnVisibility}
|
visibleState={columnVisibility}
|
||||||
updateVisibleState={setColumnVisibility}
|
updateVisibleState={setColumnVisibility}
|
||||||
/>
|
/>
|
||||||
<ExportListButton objectType='purchaseOrder' />
|
|
||||||
</Space>
|
</Space>
|
||||||
<Space>
|
<Space>
|
||||||
<FilterSidebarButton
|
<Button
|
||||||
active={showFilterSidebar}
|
icon={viewMode === 'cards' ? <ListIcon /> : <GridIcon />}
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
onClick={() =>
|
||||||
/>
|
setViewMode(viewMode === 'cards' ? 'list' : 'cards')
|
||||||
<ObjectTableViewButton
|
}
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -79,7 +71,6 @@ const PurchaseOrders = () => {
|
|||||||
visibleColumns={columnVisibility}
|
visibleColumns={columnVisibility}
|
||||||
type='purchaseOrder'
|
type='purchaseOrder'
|
||||||
cards={viewMode === 'cards'}
|
cards={viewMode === 'cards'}
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Modal
|
<Modal
|
||||||
|
|||||||
@ -5,12 +5,10 @@ import ObjectTable from '../common/ObjectTable'
|
|||||||
import PlusIcon from '../../Icons/PlusIcon'
|
import PlusIcon from '../../Icons/PlusIcon'
|
||||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
import ReloadIcon from '../../Icons/ReloadIcon'
|
||||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
import useColumnVisibility from '../hooks/useColumnVisibility'
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
import GridIcon from '../../Icons/GridIcon'
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
import ListIcon from '../../Icons/ListIcon'
|
||||||
import useViewMode from '../hooks/useViewMode'
|
import useViewMode from '../hooks/useViewMode'
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
import ColumnViewButton from '../common/ColumnViewButton'
|
import ColumnViewButton from '../common/ColumnViewButton'
|
||||||
import ExportListButton from '../common/ExportListButton'
|
|
||||||
|
|
||||||
const Shipments = () => {
|
const Shipments = () => {
|
||||||
const [newShipmentOpen, setNewShipmentOpen] = useState(false)
|
const [newShipmentOpen, setNewShipmentOpen] = useState(false)
|
||||||
@ -21,9 +19,6 @@ const Shipments = () => {
|
|||||||
const [columnVisibility, setColumnVisibility] =
|
const [columnVisibility, setColumnVisibility] =
|
||||||
useColumnVisibility('shipments')
|
useColumnVisibility('shipments')
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('Shipments')
|
|
||||||
|
|
||||||
const actionItems = {
|
const actionItems = {
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -49,7 +44,7 @@ const Shipments = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
<Flex vertical={'true'} gap='large'>
|
||||||
<Flex justify={'space-between'}>
|
<Flex justify={'space-between'}>
|
||||||
<Space size='small'>
|
<Space size='small'>
|
||||||
<Dropdown menu={actionItems}>
|
<Dropdown menu={actionItems}>
|
||||||
@ -61,16 +56,13 @@ const Shipments = () => {
|
|||||||
visibleState={columnVisibility}
|
visibleState={columnVisibility}
|
||||||
updateVisibleState={setColumnVisibility}
|
updateVisibleState={setColumnVisibility}
|
||||||
/>
|
/>
|
||||||
<ExportListButton objectType='shipment' />
|
|
||||||
</Space>
|
</Space>
|
||||||
<Space>
|
<Space>
|
||||||
<FilterSidebarButton
|
<Button
|
||||||
active={showFilterSidebar}
|
icon={viewMode === 'cards' ? <ListIcon /> : <GridIcon />}
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
onClick={() =>
|
||||||
/>
|
setViewMode(viewMode === 'cards' ? 'list' : 'cards')
|
||||||
<ObjectTableViewButton
|
}
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -79,7 +71,6 @@ const Shipments = () => {
|
|||||||
visibleColumns={columnVisibility}
|
visibleColumns={columnVisibility}
|
||||||
type='shipment'
|
type='shipment'
|
||||||
cards={viewMode === 'cards'}
|
cards={viewMode === 'cards'}
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Modal
|
<Modal
|
||||||
|
|||||||
@ -9,12 +9,10 @@ import PlusIcon from '../../Icons/PlusIcon'
|
|||||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
import ReloadIcon from '../../Icons/ReloadIcon'
|
||||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
import useColumnVisibility from '../hooks/useColumnVisibility'
|
||||||
import ObjectTable from '../common/ObjectTable'
|
import ObjectTable from '../common/ObjectTable'
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
import ListIcon from '../../Icons/ListIcon'
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
import GridIcon from '../../Icons/GridIcon'
|
||||||
import useViewMode from '../hooks/useViewMode'
|
import useViewMode from '../hooks/useViewMode'
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
import ColumnViewButton from '../common/ColumnViewButton'
|
import ColumnViewButton from '../common/ColumnViewButton'
|
||||||
import ExportListButton from '../common/ExportListButton'
|
|
||||||
|
|
||||||
const StockAudits = () => {
|
const StockAudits = () => {
|
||||||
const tableRef = useRef()
|
const tableRef = useRef()
|
||||||
@ -26,9 +24,6 @@ const StockAudits = () => {
|
|||||||
const [columnVisibility, setColumnVisibility] =
|
const [columnVisibility, setColumnVisibility] =
|
||||||
useColumnVisibility('stockAudits')
|
useColumnVisibility('stockAudits')
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('StockAudits')
|
|
||||||
|
|
||||||
const actionItems = {
|
const actionItems = {
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -54,7 +49,7 @@ const StockAudits = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
<Flex vertical={'true'} gap='large'>
|
||||||
<Flex justify={'space-between'}>
|
<Flex justify={'space-between'}>
|
||||||
<Space size='small'>
|
<Space size='small'>
|
||||||
<Dropdown menu={actionItems}>
|
<Dropdown menu={actionItems}>
|
||||||
@ -66,16 +61,13 @@ const StockAudits = () => {
|
|||||||
visibleState={columnVisibility}
|
visibleState={columnVisibility}
|
||||||
updateVisibleState={setColumnVisibility}
|
updateVisibleState={setColumnVisibility}
|
||||||
/>
|
/>
|
||||||
<ExportListButton objectType='stockAudit' />
|
|
||||||
</Space>
|
</Space>
|
||||||
<Space>
|
<Space>
|
||||||
<FilterSidebarButton
|
<Button
|
||||||
active={showFilterSidebar}
|
icon={viewMode === 'cards' ? <ListIcon /> : <GridIcon />}
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
onClick={() =>
|
||||||
/>
|
setViewMode(viewMode === 'cards' ? 'list' : 'cards')
|
||||||
<ObjectTableViewButton
|
}
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -85,7 +77,6 @@ const StockAudits = () => {
|
|||||||
visibleColumns={columnVisibility}
|
visibleColumns={columnVisibility}
|
||||||
type='stockAudit'
|
type='stockAudit'
|
||||||
cards={viewMode === 'cards'}
|
cards={viewMode === 'cards'}
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Modal
|
<Modal
|
||||||
|
|||||||
@ -2,12 +2,10 @@ import { useRef } from 'react'
|
|||||||
import { Button, Flex, Space, Dropdown } from 'antd'
|
import { Button, Flex, Space, Dropdown } from 'antd'
|
||||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
import useColumnVisibility from '../hooks/useColumnVisibility'
|
||||||
import ObjectTable from '../common/ObjectTable'
|
import ObjectTable from '../common/ObjectTable'
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
import GridIcon from '../../Icons/GridIcon'
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
import ListIcon from '../../Icons/ListIcon'
|
||||||
import useViewMode from '../hooks/useViewMode'
|
import useViewMode from '../hooks/useViewMode'
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
import ColumnViewButton from '../common/ColumnViewButton'
|
import ColumnViewButton from '../common/ColumnViewButton'
|
||||||
import ExportListButton from '../common/ExportListButton'
|
|
||||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
import ReloadIcon from '../../Icons/ReloadIcon'
|
||||||
|
|
||||||
const StockEvents = () => {
|
const StockEvents = () => {
|
||||||
@ -15,10 +13,7 @@ const StockEvents = () => {
|
|||||||
const [viewMode, setViewMode] = useViewMode('stockEvents')
|
const [viewMode, setViewMode] = useViewMode('stockEvents')
|
||||||
|
|
||||||
const [columnVisibility, setColumnVisibility] =
|
const [columnVisibility, setColumnVisibility] =
|
||||||
useColumnVisibility('stockEvent')
|
useColumnVisibility('stockEvents')
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('StockEvents')
|
|
||||||
|
|
||||||
const actionItems = {
|
const actionItems = {
|
||||||
items: [
|
items: [
|
||||||
@ -37,7 +32,7 @@ const StockEvents = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
<Flex vertical={'true'} gap='large'>
|
||||||
<Flex justify={'space-between'}>
|
<Flex justify={'space-between'}>
|
||||||
<Space size='small'>
|
<Space size='small'>
|
||||||
<Dropdown menu={actionItems}>
|
<Dropdown menu={actionItems}>
|
||||||
@ -49,16 +44,13 @@ const StockEvents = () => {
|
|||||||
visibleState={columnVisibility}
|
visibleState={columnVisibility}
|
||||||
updateVisibleState={setColumnVisibility}
|
updateVisibleState={setColumnVisibility}
|
||||||
/>
|
/>
|
||||||
<ExportListButton objectType='stockEvent' />
|
|
||||||
</Space>
|
</Space>
|
||||||
<Space>
|
<Space>
|
||||||
<FilterSidebarButton
|
<Button
|
||||||
active={showFilterSidebar}
|
icon={viewMode === 'cards' ? <ListIcon /> : <GridIcon />}
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
onClick={() =>
|
||||||
/>
|
setViewMode(viewMode === 'cards' ? 'list' : 'cards')
|
||||||
<ObjectTableViewButton
|
}
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -68,7 +60,6 @@ const StockEvents = () => {
|
|||||||
visibleColumns={columnVisibility}
|
visibleColumns={columnVisibility}
|
||||||
type='stockEvent'
|
type='stockEvent'
|
||||||
cards={viewMode === 'cards'}
|
cards={viewMode === 'cards'}
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -1,106 +0,0 @@
|
|||||||
import { useRef, useState } from 'react'
|
|
||||||
import { Button, Flex, Space, Modal, Dropdown } from 'antd'
|
|
||||||
import NewAppPassword from './AppPasswords/NewAppPassword'
|
|
||||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
|
||||||
import ColumnViewButton from '../common/ColumnViewButton'
|
|
||||||
import ObjectTable from '../common/ObjectTable'
|
|
||||||
import PlusIcon from '../../Icons/PlusIcon'
|
|
||||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
|
||||||
import useViewMode from '../hooks/useViewMode'
|
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
import ExportListButton from '../common/ExportListButton'
|
|
||||||
|
|
||||||
const AppPasswords = () => {
|
|
||||||
const [newAppPasswordOpen, setNewAppPasswordOpen] = useState(false)
|
|
||||||
const tableRef = useRef()
|
|
||||||
|
|
||||||
const [viewMode, setViewMode] = useViewMode('appPassword')
|
|
||||||
const [columnVisibility, setColumnVisibility] =
|
|
||||||
useColumnVisibility('appPassword')
|
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('AppPasswords')
|
|
||||||
|
|
||||||
const actionItems = {
|
|
||||||
items: [
|
|
||||||
{
|
|
||||||
label: 'New App Password',
|
|
||||||
key: 'newAppPassword',
|
|
||||||
icon: <PlusIcon />
|
|
||||||
},
|
|
||||||
{ type: 'divider' },
|
|
||||||
{
|
|
||||||
label: 'Reload List',
|
|
||||||
key: 'reloadList',
|
|
||||||
icon: <ReloadIcon />
|
|
||||||
}
|
|
||||||
],
|
|
||||||
onClick: ({ key }) => {
|
|
||||||
if (key === 'reloadList') {
|
|
||||||
tableRef.current?.reload()
|
|
||||||
} else if (key === 'newAppPassword') {
|
|
||||||
setNewAppPasswordOpen(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
|
||||||
<Flex justify={'space-between'}>
|
|
||||||
<Space>
|
|
||||||
<Dropdown menu={actionItems}>
|
|
||||||
<Button>Actions</Button>
|
|
||||||
</Dropdown>
|
|
||||||
<ColumnViewButton
|
|
||||||
type='appPassword'
|
|
||||||
loading={false}
|
|
||||||
visibleState={columnVisibility}
|
|
||||||
updateVisibleState={setColumnVisibility}
|
|
||||||
/>
|
|
||||||
<ExportListButton objectType='appPassword' />
|
|
||||||
</Space>
|
|
||||||
<Space>
|
|
||||||
<FilterSidebarButton
|
|
||||||
active={showFilterSidebar}
|
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
|
||||||
/>
|
|
||||||
<ObjectTableViewButton
|
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
|
||||||
</Space>
|
|
||||||
</Flex>
|
|
||||||
|
|
||||||
<ObjectTable
|
|
||||||
ref={tableRef}
|
|
||||||
type='appPassword'
|
|
||||||
cards={viewMode === 'cards'}
|
|
||||||
visibleColumns={columnVisibility}
|
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Modal
|
|
||||||
open={newAppPasswordOpen}
|
|
||||||
footer={null}
|
|
||||||
width={700}
|
|
||||||
onCancel={() => {
|
|
||||||
setNewAppPasswordOpen(false)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<NewAppPassword
|
|
||||||
onOk={() => {
|
|
||||||
setNewAppPasswordOpen(false)
|
|
||||||
tableRef.current?.reload()
|
|
||||||
}}
|
|
||||||
reset={newAppPasswordOpen}
|
|
||||||
/>
|
|
||||||
</Modal>
|
|
||||||
</Flex>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default AppPasswords
|
|
||||||
@ -1,212 +0,0 @@
|
|||||||
import { useRef, useState, useContext } from 'react'
|
|
||||||
import { useLocation } from 'react-router-dom'
|
|
||||||
import { Space, Flex, Modal } from 'antd'
|
|
||||||
import { LoadingOutlined } from '@ant-design/icons'
|
|
||||||
import useCollapseState from '../../hooks/useCollapseState'
|
|
||||||
import InfoCollapse from '../../common/InfoCollapse'
|
|
||||||
import ObjectInfo from '../../common/ObjectInfo'
|
|
||||||
import ViewButton from '../../common/ViewButton'
|
|
||||||
import InfoCircleIcon from '../../../Icons/InfoCircleIcon.jsx'
|
|
||||||
import AuditLogIcon from '../../../Icons/AuditLogIcon.jsx'
|
|
||||||
import ObjectForm from '../../common/ObjectForm'
|
|
||||||
import EditButtons from '../../common/EditButtons'
|
|
||||||
import LockIndicator from '../../common/LockIndicator.jsx'
|
|
||||||
import ActionHandler from '../../common/ActionHandler.jsx'
|
|
||||||
import ObjectActions from '../../common/ObjectActions.jsx'
|
|
||||||
import ObjectTable from '../../common/ObjectTable.jsx'
|
|
||||||
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
|
|
||||||
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
|
|
||||||
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
|
|
||||||
import ScrollBox from '../../common/ScrollBox.jsx'
|
|
||||||
import RegenerateAppPasswordSecret from './RegenerateAppPasswordSecret.jsx'
|
|
||||||
import { getModelByName } from '../../../../database/ObjectModels.js'
|
|
||||||
import { AuthContext } from '../../context/AuthContext.jsx'
|
|
||||||
|
|
||||||
const AppPasswordInfo = () => {
|
|
||||||
const location = useLocation()
|
|
||||||
const objectFormRef = useRef(null)
|
|
||||||
const actionHandlerRef = useRef(null)
|
|
||||||
const { userProfile } = useContext(AuthContext)
|
|
||||||
const appPasswordId = new URLSearchParams(location.search).get(
|
|
||||||
'appPasswordId'
|
|
||||||
)
|
|
||||||
const [regenerateSecretOpen, setRegenerateSecretOpen] = useState(false)
|
|
||||||
const [collapseState, updateCollapseState] = useCollapseState(
|
|
||||||
'AppPasswordInfo',
|
|
||||||
{
|
|
||||||
info: true,
|
|
||||||
auditLogs: true
|
|
||||||
}
|
|
||||||
)
|
|
||||||
const [objectFormState, setEditFormState] = useState({
|
|
||||||
isEditing: false,
|
|
||||||
editLoading: false,
|
|
||||||
formValid: false,
|
|
||||||
lock: null,
|
|
||||||
loading: false,
|
|
||||||
objectData: {}
|
|
||||||
})
|
|
||||||
|
|
||||||
const actions = {
|
|
||||||
reload: () => {
|
|
||||||
objectFormRef?.current?.handleFetchObject?.()
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
regenerateSecret: () => {
|
|
||||||
setRegenerateSecretOpen(true)
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
edit: () => {
|
|
||||||
objectFormRef?.current?.startEditing?.()
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
cancelEdit: () => {
|
|
||||||
objectFormRef?.current?.cancelEditing?.()
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
finishEdit: () => {
|
|
||||||
objectFormRef?.current?.handleUpdate?.()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const editDisabled = getModelByName('appPassword')
|
|
||||||
.actions.find((action) => action.name === 'edit')
|
|
||||||
.disabled({ ...objectFormState.objectData, _user: userProfile })
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Flex
|
|
||||||
gap='large'
|
|
||||||
vertical='true'
|
|
||||||
style={{ maxHeight: '100%', minHeight: 0 }}
|
|
||||||
>
|
|
||||||
<Flex justify={'space-between'}>
|
|
||||||
<Space size='middle'>
|
|
||||||
<Space size='small'>
|
|
||||||
<ObjectActions
|
|
||||||
type='appPassword'
|
|
||||||
id={appPasswordId}
|
|
||||||
disabled={objectFormState.loading}
|
|
||||||
objectData={objectFormState.objectData}
|
|
||||||
/>
|
|
||||||
<ViewButton
|
|
||||||
disabled={objectFormState.loading}
|
|
||||||
items={[
|
|
||||||
{ key: 'info', label: 'App Password Information' },
|
|
||||||
{ key: 'auditLogs', label: 'Audit Logs' }
|
|
||||||
]}
|
|
||||||
visibleState={collapseState}
|
|
||||||
updateVisibleState={updateCollapseState}
|
|
||||||
/>
|
|
||||||
<UserNotifierToggle
|
|
||||||
type='appPassword'
|
|
||||||
objectData={objectFormState.objectData}
|
|
||||||
disabled={objectFormState.loading}
|
|
||||||
/>
|
|
||||||
<DocumentPrintButton
|
|
||||||
type='appPassword'
|
|
||||||
objectData={objectFormState.objectData}
|
|
||||||
disabled={objectFormState.loading}
|
|
||||||
/>
|
|
||||||
</Space>
|
|
||||||
<LockIndicator lock={objectFormState.lock} />
|
|
||||||
</Space>
|
|
||||||
<Space>
|
|
||||||
<EditButtons
|
|
||||||
isEditing={objectFormState.isEditing}
|
|
||||||
handleUpdate={() => {
|
|
||||||
actionHandlerRef.current.callAction('finishEdit')
|
|
||||||
}}
|
|
||||||
cancelEditing={() => {
|
|
||||||
actionHandlerRef.current.callAction('cancelEdit')
|
|
||||||
}}
|
|
||||||
startEditing={() => {
|
|
||||||
actionHandlerRef.current.callAction('edit')
|
|
||||||
}}
|
|
||||||
editLoading={objectFormState.editLoading}
|
|
||||||
formValid={objectFormState.formValid}
|
|
||||||
disabled={
|
|
||||||
objectFormState.lock?.locked ||
|
|
||||||
objectFormState.loading ||
|
|
||||||
editDisabled
|
|
||||||
}
|
|
||||||
loading={objectFormState.editLoading}
|
|
||||||
/>
|
|
||||||
</Space>
|
|
||||||
</Flex>
|
|
||||||
<ScrollBox>
|
|
||||||
<Flex vertical gap={'large'}>
|
|
||||||
<ActionHandler
|
|
||||||
actions={actions}
|
|
||||||
loading={objectFormState.loading}
|
|
||||||
ref={actionHandlerRef}
|
|
||||||
>
|
|
||||||
<InfoCollapse
|
|
||||||
title='App Password Information'
|
|
||||||
icon={<InfoCircleIcon />}
|
|
||||||
active={collapseState.info}
|
|
||||||
onToggle={(expanded) => updateCollapseState('info', expanded)}
|
|
||||||
collapseKey='info'
|
|
||||||
>
|
|
||||||
<ObjectForm
|
|
||||||
id={appPasswordId}
|
|
||||||
type='appPassword'
|
|
||||||
style={{ height: '100%' }}
|
|
||||||
ref={objectFormRef}
|
|
||||||
onStateChange={(state) => {
|
|
||||||
setEditFormState((prev) => ({ ...prev, ...state }))
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{({ loading, isEditing, objectData }) => (
|
|
||||||
<ObjectInfo
|
|
||||||
loading={loading}
|
|
||||||
indicator={<LoadingOutlined />}
|
|
||||||
isEditing={isEditing}
|
|
||||||
type='appPassword'
|
|
||||||
objectData={objectData}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</ObjectForm>
|
|
||||||
</InfoCollapse>
|
|
||||||
</ActionHandler>
|
|
||||||
<InfoCollapse
|
|
||||||
title='Audit Logs'
|
|
||||||
icon={<AuditLogIcon />}
|
|
||||||
active={collapseState.auditLogs}
|
|
||||||
onToggle={(expanded) =>
|
|
||||||
updateCollapseState('auditLogs', expanded)
|
|
||||||
}
|
|
||||||
collapseKey='auditLogs'
|
|
||||||
>
|
|
||||||
{objectFormState.loading ? (
|
|
||||||
<InfoCollapsePlaceholder />
|
|
||||||
) : (
|
|
||||||
<ObjectTable
|
|
||||||
type='auditLog'
|
|
||||||
masterFilter={{ 'parent._id': appPasswordId }}
|
|
||||||
visibleColumns={{ _id: false, 'parent._id': false }}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</InfoCollapse>
|
|
||||||
</Flex>
|
|
||||||
</ScrollBox>
|
|
||||||
</Flex>
|
|
||||||
|
|
||||||
<Modal
|
|
||||||
open={regenerateSecretOpen}
|
|
||||||
destroyOnClose
|
|
||||||
width={650}
|
|
||||||
onCancel={() => {
|
|
||||||
actionHandlerRef.current?.clearAction?.()
|
|
||||||
setRegenerateSecretOpen(false)
|
|
||||||
}}
|
|
||||||
footer={null}
|
|
||||||
>
|
|
||||||
<RegenerateAppPasswordSecret id={appPasswordId} />
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default AppPasswordInfo
|
|
||||||
@ -1,91 +0,0 @@
|
|||||||
import PropTypes from 'prop-types'
|
|
||||||
import ObjectInfo from '../../common/ObjectInfo'
|
|
||||||
import NewObjectForm from '../../common/NewObjectForm'
|
|
||||||
import WizardView from '../../common/WizardView'
|
|
||||||
|
|
||||||
const NewAppPassword = ({ onOk, reset, defaultValues = {} }) => {
|
|
||||||
return (
|
|
||||||
<NewObjectForm
|
|
||||||
type='appPassword'
|
|
||||||
reset={reset}
|
|
||||||
defaultValues={{
|
|
||||||
active: true,
|
|
||||||
...defaultValues
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{({ handleSubmit, submitLoading, objectData, formValid }) => {
|
|
||||||
const steps = [
|
|
||||||
{
|
|
||||||
title: 'Required',
|
|
||||||
key: 'required',
|
|
||||||
content: (
|
|
||||||
<ObjectInfo
|
|
||||||
type='appPassword'
|
|
||||||
column={1}
|
|
||||||
bordered={false}
|
|
||||||
isEditing={true}
|
|
||||||
required={true}
|
|
||||||
objectData={objectData}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Optional',
|
|
||||||
key: 'optional',
|
|
||||||
content: (
|
|
||||||
<ObjectInfo
|
|
||||||
type='appPassword'
|
|
||||||
column={1}
|
|
||||||
bordered={false}
|
|
||||||
isEditing={true}
|
|
||||||
required={false}
|
|
||||||
objectData={objectData}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Summary',
|
|
||||||
key: 'summary',
|
|
||||||
content: (
|
|
||||||
<ObjectInfo
|
|
||||||
type='appPassword'
|
|
||||||
column={1}
|
|
||||||
bordered={false}
|
|
||||||
visibleProperties={{
|
|
||||||
_id: false,
|
|
||||||
createdAt: false,
|
|
||||||
updatedAt: false,
|
|
||||||
secret: false
|
|
||||||
}}
|
|
||||||
isEditing={false}
|
|
||||||
objectData={objectData}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
]
|
|
||||||
return (
|
|
||||||
<WizardView
|
|
||||||
steps={steps}
|
|
||||||
loading={submitLoading}
|
|
||||||
formValid={formValid}
|
|
||||||
title='New App Password'
|
|
||||||
onSubmit={async () => {
|
|
||||||
const result = await handleSubmit()
|
|
||||||
if (result) {
|
|
||||||
onOk()
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
</NewObjectForm>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
NewAppPassword.propTypes = {
|
|
||||||
onOk: PropTypes.func.isRequired,
|
|
||||||
reset: PropTypes.bool,
|
|
||||||
defaultValues: PropTypes.object
|
|
||||||
}
|
|
||||||
|
|
||||||
export default NewAppPassword
|
|
||||||
@ -1,77 +0,0 @@
|
|||||||
import PropTypes from 'prop-types'
|
|
||||||
import { useContext, useState } from 'react'
|
|
||||||
import { Result, Typography, Flex, Button } from 'antd'
|
|
||||||
import { ApiServerContext } from '../../context/ApiServerContext'
|
|
||||||
import CopyButton from '../../common/CopyButton'
|
|
||||||
import AppPasswordIcon from '../../../Icons/AppPasswordIcon.jsx'
|
|
||||||
import ReloadIcon from '../../../Icons/ReloadIcon'
|
|
||||||
|
|
||||||
const { Text } = Typography
|
|
||||||
|
|
||||||
const RegenerateAppPasswordSecret = ({ id }) => {
|
|
||||||
const { sendObjectFunction } = useContext(ApiServerContext)
|
|
||||||
const [appPassword, setAppPassword] = useState(null)
|
|
||||||
const [loading, setLoading] = useState(false)
|
|
||||||
const [passwordGenerated, setPasswordGenerated] = useState(false)
|
|
||||||
|
|
||||||
const handleRegenerate = async () => {
|
|
||||||
setLoading(true)
|
|
||||||
setAppPassword(null)
|
|
||||||
try {
|
|
||||||
const result = await sendObjectFunction(
|
|
||||||
id,
|
|
||||||
'appPassword',
|
|
||||||
'regenerateSecret',
|
|
||||||
{}
|
|
||||||
)
|
|
||||||
if (result?.appPassword) {
|
|
||||||
setAppPassword(result.appPassword)
|
|
||||||
setPasswordGenerated(true)
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
setLoading(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Flex vertical align='center'>
|
|
||||||
<Result
|
|
||||||
title={
|
|
||||||
passwordGenerated ? 'Secret Regenerated' : 'Regenerate Secret'
|
|
||||||
}
|
|
||||||
disabled={passwordGenerated}
|
|
||||||
subTitle={
|
|
||||||
appPassword ? (
|
|
||||||
<Text>Copy this secret now. It will not be shown again.</Text>
|
|
||||||
) : (
|
|
||||||
<Text>Generate a new secret for this app password.</Text>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
icon={<AppPasswordIcon />}
|
|
||||||
>
|
|
||||||
<Flex justify='center' style={{ minWidth: '395px' }}>
|
|
||||||
<Flex justify='center'>
|
|
||||||
<Flex gap='small' align='center' justify='center'>
|
|
||||||
<CopyButton size='default' text={appPassword} />
|
|
||||||
<Text code style={{ fontSize: '18px' }}>
|
|
||||||
{appPassword || '••••••••••••••••••••••••••••••••'}
|
|
||||||
</Text>
|
|
||||||
<Button
|
|
||||||
type='text'
|
|
||||||
loading={loading}
|
|
||||||
onClick={handleRegenerate}
|
|
||||||
icon={<ReloadIcon />}
|
|
||||||
/>
|
|
||||||
</Flex>
|
|
||||||
</Flex>
|
|
||||||
</Flex>
|
|
||||||
</Result>
|
|
||||||
</Flex>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
RegenerateAppPasswordSecret.propTypes = {
|
|
||||||
id: PropTypes.string.isRequired
|
|
||||||
}
|
|
||||||
|
|
||||||
export default RegenerateAppPasswordSecret
|
|
||||||
@ -3,20 +3,14 @@ import { Button, Flex, Space, Dropdown } from 'antd'
|
|||||||
|
|
||||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
import ReloadIcon from '../../Icons/ReloadIcon'
|
||||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
import useColumnVisibility from '../hooks/useColumnVisibility'
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
import ObjectTable from '../common/ObjectTable'
|
import ObjectTable from '../common/ObjectTable'
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
|
||||||
import ColumnViewButton from '../common/ColumnViewButton'
|
import ColumnViewButton from '../common/ColumnViewButton'
|
||||||
import ExportListButton from '../common/ExportListButton'
|
|
||||||
|
|
||||||
const AuditLogs = () => {
|
const AuditLogs = () => {
|
||||||
const tableRef = useRef()
|
const tableRef = useRef()
|
||||||
|
|
||||||
const [columnVisibility, updateColumnVisibility] =
|
const [columnVisibility, updateColumnVisibility] =
|
||||||
useColumnVisibility('auditLog')
|
useColumnVisibility('auditLogs')
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('AuditLogs')
|
|
||||||
|
|
||||||
const actionItems = {
|
const actionItems = {
|
||||||
items: [
|
items: [
|
||||||
@ -35,7 +29,7 @@ const AuditLogs = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
<Flex vertical={'true'} gap='large'>
|
||||||
<Flex justify={'space-between'}>
|
<Flex justify={'space-between'}>
|
||||||
<Space size='small'>
|
<Space size='small'>
|
||||||
<Dropdown menu={actionItems}>
|
<Dropdown menu={actionItems}>
|
||||||
@ -47,13 +41,6 @@ const AuditLogs = () => {
|
|||||||
visibleState={columnVisibility}
|
visibleState={columnVisibility}
|
||||||
updateVisibleState={updateColumnVisibility}
|
updateVisibleState={updateColumnVisibility}
|
||||||
/>
|
/>
|
||||||
<ExportListButton objectType='auditLog' />
|
|
||||||
</Space>
|
|
||||||
<Space>
|
|
||||||
<FilterSidebarButton
|
|
||||||
active={showFilterSidebar}
|
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
|
||||||
/>
|
|
||||||
</Space>
|
</Space>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
@ -61,7 +48,6 @@ const AuditLogs = () => {
|
|||||||
ref={tableRef}
|
ref={tableRef}
|
||||||
visibleColumns={columnVisibility}
|
visibleColumns={columnVisibility}
|
||||||
type='auditLog'
|
type='auditLog'
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -5,12 +5,10 @@ import ObjectTable from '../common/ObjectTable'
|
|||||||
import PlusIcon from '../../Icons/PlusIcon'
|
import PlusIcon from '../../Icons/PlusIcon'
|
||||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
import ReloadIcon from '../../Icons/ReloadIcon'
|
||||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
import useColumnVisibility from '../hooks/useColumnVisibility'
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
import GridIcon from '../../Icons/GridIcon'
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
import ListIcon from '../../Icons/ListIcon'
|
||||||
import useViewMode from '../hooks/useViewMode'
|
import useViewMode from '../hooks/useViewMode'
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
import ColumnViewButton from '../common/ColumnViewButton'
|
import ColumnViewButton from '../common/ColumnViewButton'
|
||||||
import ExportListButton from '../common/ExportListButton'
|
|
||||||
|
|
||||||
const CourierServices = () => {
|
const CourierServices = () => {
|
||||||
const [newCourierServiceOpen, setNewCourierServiceOpen] = useState(false)
|
const [newCourierServiceOpen, setNewCourierServiceOpen] = useState(false)
|
||||||
@ -21,9 +19,6 @@ const CourierServices = () => {
|
|||||||
const [columnVisibility, setColumnVisibility] =
|
const [columnVisibility, setColumnVisibility] =
|
||||||
useColumnVisibility('courierService')
|
useColumnVisibility('courierService')
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('CourierServices')
|
|
||||||
|
|
||||||
const actionItems = {
|
const actionItems = {
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -49,7 +44,7 @@ const CourierServices = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
<Flex vertical={'true'} gap='large'>
|
||||||
<Flex justify={'space-between'}>
|
<Flex justify={'space-between'}>
|
||||||
<Space size='small'>
|
<Space size='small'>
|
||||||
<Dropdown menu={actionItems}>
|
<Dropdown menu={actionItems}>
|
||||||
@ -58,19 +53,16 @@ const CourierServices = () => {
|
|||||||
<ColumnViewButton
|
<ColumnViewButton
|
||||||
type='courierService'
|
type='courierService'
|
||||||
loading={false}
|
loading={false}
|
||||||
visibleState={columnVisibility}
|
collapseState={columnVisibility}
|
||||||
updateVisibleState={setColumnVisibility}
|
updateCollapseState={setColumnVisibility}
|
||||||
/>
|
/>
|
||||||
<ExportListButton objectType='courierService' />
|
|
||||||
</Space>
|
</Space>
|
||||||
<Space>
|
<Space>
|
||||||
<FilterSidebarButton
|
<Button
|
||||||
active={showFilterSidebar}
|
icon={viewMode === 'cards' ? <ListIcon /> : <GridIcon />}
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
onClick={() =>
|
||||||
/>
|
setViewMode(viewMode === 'cards' ? 'list' : 'cards')
|
||||||
<ObjectTableViewButton
|
}
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -79,7 +71,6 @@ const CourierServices = () => {
|
|||||||
visibleColumns={columnVisibility}
|
visibleColumns={columnVisibility}
|
||||||
type='courierService'
|
type='courierService'
|
||||||
cards={viewMode === 'cards'}
|
cards={viewMode === 'cards'}
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Modal
|
<Modal
|
||||||
|
|||||||
@ -5,12 +5,10 @@ import ObjectTable from '../common/ObjectTable'
|
|||||||
import PlusIcon from '../../Icons/PlusIcon'
|
import PlusIcon from '../../Icons/PlusIcon'
|
||||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
import ReloadIcon from '../../Icons/ReloadIcon'
|
||||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
import useColumnVisibility from '../hooks/useColumnVisibility'
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
import GridIcon from '../../Icons/GridIcon'
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
import ListIcon from '../../Icons/ListIcon'
|
||||||
import useViewMode from '../hooks/useViewMode'
|
import useViewMode from '../hooks/useViewMode'
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
import ColumnViewButton from '../common/ColumnViewButton'
|
import ColumnViewButton from '../common/ColumnViewButton'
|
||||||
import ExportListButton from '../common/ExportListButton'
|
|
||||||
|
|
||||||
const Couriers = () => {
|
const Couriers = () => {
|
||||||
const [newCourierOpen, setNewCourierOpen] = useState(false)
|
const [newCourierOpen, setNewCourierOpen] = useState(false)
|
||||||
@ -20,9 +18,6 @@ const Couriers = () => {
|
|||||||
|
|
||||||
const [columnVisibility, setColumnVisibility] = useColumnVisibility('courier')
|
const [columnVisibility, setColumnVisibility] = useColumnVisibility('courier')
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('Couriers')
|
|
||||||
|
|
||||||
const actionItems = {
|
const actionItems = {
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -48,7 +43,7 @@ const Couriers = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
<Flex vertical={'true'} gap='large'>
|
||||||
<Flex justify={'space-between'}>
|
<Flex justify={'space-between'}>
|
||||||
<Space size='small'>
|
<Space size='small'>
|
||||||
<Dropdown menu={actionItems}>
|
<Dropdown menu={actionItems}>
|
||||||
@ -57,19 +52,16 @@ const Couriers = () => {
|
|||||||
<ColumnViewButton
|
<ColumnViewButton
|
||||||
type='courier'
|
type='courier'
|
||||||
loading={false}
|
loading={false}
|
||||||
visibleState={columnVisibility}
|
collapseState={columnVisibility}
|
||||||
updateVisibleState={setColumnVisibility}
|
updateCollapseState={setColumnVisibility}
|
||||||
/>
|
/>
|
||||||
<ExportListButton objectType='courier' />
|
|
||||||
</Space>
|
</Space>
|
||||||
<Space>
|
<Space>
|
||||||
<FilterSidebarButton
|
<Button
|
||||||
active={showFilterSidebar}
|
icon={viewMode === 'cards' ? <ListIcon /> : <GridIcon />}
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
onClick={() =>
|
||||||
/>
|
setViewMode(viewMode === 'cards' ? 'list' : 'cards')
|
||||||
<ObjectTableViewButton
|
}
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -78,7 +70,6 @@ const Couriers = () => {
|
|||||||
visibleColumns={columnVisibility}
|
visibleColumns={columnVisibility}
|
||||||
type='courier'
|
type='courier'
|
||||||
cards={viewMode === 'cards'}
|
cards={viewMode === 'cards'}
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Modal
|
<Modal
|
||||||
|
|||||||
@ -5,12 +5,10 @@ import ObjectTable from '../common/ObjectTable'
|
|||||||
import PlusIcon from '../../Icons/PlusIcon'
|
import PlusIcon from '../../Icons/PlusIcon'
|
||||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
import ReloadIcon from '../../Icons/ReloadIcon'
|
||||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
import useColumnVisibility from '../hooks/useColumnVisibility'
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
import GridIcon from '../../Icons/GridIcon'
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
import ListIcon from '../../Icons/ListIcon'
|
||||||
import useViewMode from '../hooks/useViewMode'
|
import useViewMode from '../hooks/useViewMode'
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
import ColumnViewButton from '../common/ColumnViewButton'
|
import ColumnViewButton from '../common/ColumnViewButton'
|
||||||
import ExportListButton from '../common/ExportListButton'
|
|
||||||
|
|
||||||
const DocumentJobs = () => {
|
const DocumentJobs = () => {
|
||||||
const [newDocumentJobOpen, setNewDocumentJobOpen] = useState(false)
|
const [newDocumentJobOpen, setNewDocumentJobOpen] = useState(false)
|
||||||
@ -21,9 +19,6 @@ const DocumentJobs = () => {
|
|||||||
const [columnVisibility, setColumnVisibility] =
|
const [columnVisibility, setColumnVisibility] =
|
||||||
useColumnVisibility('documentJob')
|
useColumnVisibility('documentJob')
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('DocumentJobs')
|
|
||||||
|
|
||||||
const actionItems = {
|
const actionItems = {
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -49,7 +44,7 @@ const DocumentJobs = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
<Flex vertical={'true'} gap='large'>
|
||||||
<Flex justify={'space-between'}>
|
<Flex justify={'space-between'}>
|
||||||
<Space size='small'>
|
<Space size='small'>
|
||||||
<Dropdown menu={actionItems}>
|
<Dropdown menu={actionItems}>
|
||||||
@ -58,19 +53,16 @@ const DocumentJobs = () => {
|
|||||||
<ColumnViewButton
|
<ColumnViewButton
|
||||||
type='documentJob'
|
type='documentJob'
|
||||||
loading={false}
|
loading={false}
|
||||||
visibleState={columnVisibility}
|
collapseState={columnVisibility}
|
||||||
updateVisibleState={setColumnVisibility}
|
updateCollapseState={setColumnVisibility}
|
||||||
/>
|
/>
|
||||||
<ExportListButton objectType='documentJob' />
|
|
||||||
</Space>
|
</Space>
|
||||||
<Space>
|
<Space>
|
||||||
<FilterSidebarButton
|
<Button
|
||||||
active={showFilterSidebar}
|
icon={viewMode === 'cards' ? <ListIcon /> : <GridIcon />}
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
onClick={() =>
|
||||||
/>
|
setViewMode(viewMode === 'cards' ? 'list' : 'cards')
|
||||||
<ObjectTableViewButton
|
}
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -79,7 +71,6 @@ const DocumentJobs = () => {
|
|||||||
visibleColumns={columnVisibility}
|
visibleColumns={columnVisibility}
|
||||||
type='documentJob'
|
type='documentJob'
|
||||||
cards={viewMode === 'cards'}
|
cards={viewMode === 'cards'}
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Modal
|
<Modal
|
||||||
|
|||||||
@ -4,12 +4,10 @@ import PlusIcon from '../../Icons/PlusIcon'
|
|||||||
import ObjectTable from '../common/ObjectTable'
|
import ObjectTable from '../common/ObjectTable'
|
||||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
import ReloadIcon from '../../Icons/ReloadIcon'
|
||||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
import useColumnVisibility from '../hooks/useColumnVisibility'
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
import GridIcon from '../../Icons/GridIcon'
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
import ListIcon from '../../Icons/ListIcon'
|
||||||
import useViewMode from '../hooks/useViewMode'
|
import useViewMode from '../hooks/useViewMode'
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
import ColumnViewButton from '../common/ColumnViewButton'
|
import ColumnViewButton from '../common/ColumnViewButton'
|
||||||
import ExportListButton from '../common/ExportListButton'
|
|
||||||
import NewDocumentPrinter from './DocumentPrinters/NewDocumentPrinter'
|
import NewDocumentPrinter from './DocumentPrinters/NewDocumentPrinter'
|
||||||
|
|
||||||
const DocumentPrinters = () => {
|
const DocumentPrinters = () => {
|
||||||
@ -20,9 +18,6 @@ const DocumentPrinters = () => {
|
|||||||
const [columnVisibility, setColumnVisibility] =
|
const [columnVisibility, setColumnVisibility] =
|
||||||
useColumnVisibility('documentPrinter')
|
useColumnVisibility('documentPrinter')
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('DocumentPrinters')
|
|
||||||
|
|
||||||
const actionItems = {
|
const actionItems = {
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -48,7 +43,7 @@ const DocumentPrinters = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
<Flex vertical={'true'} gap='large'>
|
||||||
<Flex justify={'space-between'}>
|
<Flex justify={'space-between'}>
|
||||||
<Space size='small'>
|
<Space size='small'>
|
||||||
<Dropdown menu={actionItems}>
|
<Dropdown menu={actionItems}>
|
||||||
@ -57,19 +52,16 @@ const DocumentPrinters = () => {
|
|||||||
<ColumnViewButton
|
<ColumnViewButton
|
||||||
type='documentPrinter'
|
type='documentPrinter'
|
||||||
loading={false}
|
loading={false}
|
||||||
visibleState={columnVisibility}
|
collapseState={columnVisibility}
|
||||||
updateVisibleState={setColumnVisibility}
|
updateCollapseState={setColumnVisibility}
|
||||||
/>
|
/>
|
||||||
<ExportListButton objectType='documentPrinter' />
|
|
||||||
</Space>
|
</Space>
|
||||||
<Space>
|
<Space>
|
||||||
<FilterSidebarButton
|
<Button
|
||||||
active={showFilterSidebar}
|
icon={viewMode === 'cards' ? <ListIcon /> : <GridIcon />}
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
onClick={() =>
|
||||||
/>
|
setViewMode(viewMode === 'cards' ? 'list' : 'cards')
|
||||||
<ObjectTableViewButton
|
}
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -78,7 +70,6 @@ const DocumentPrinters = () => {
|
|||||||
visibleColumns={columnVisibility}
|
visibleColumns={columnVisibility}
|
||||||
type='documentPrinter'
|
type='documentPrinter'
|
||||||
cards={viewMode === 'cards'}
|
cards={viewMode === 'cards'}
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Modal
|
<Modal
|
||||||
|
|||||||
@ -5,12 +5,10 @@ import ObjectTable from '../common/ObjectTable'
|
|||||||
import PlusIcon from '../../Icons/PlusIcon'
|
import PlusIcon from '../../Icons/PlusIcon'
|
||||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
import ReloadIcon from '../../Icons/ReloadIcon'
|
||||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
import useColumnVisibility from '../hooks/useColumnVisibility'
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
import GridIcon from '../../Icons/GridIcon'
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
import ListIcon from '../../Icons/ListIcon'
|
||||||
import useViewMode from '../hooks/useViewMode'
|
import useViewMode from '../hooks/useViewMode'
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
import ColumnViewButton from '../common/ColumnViewButton'
|
import ColumnViewButton from '../common/ColumnViewButton'
|
||||||
import ExportListButton from '../common/ExportListButton'
|
|
||||||
|
|
||||||
const DocumentSizes = () => {
|
const DocumentSizes = () => {
|
||||||
const [newDocumentSizeOpen, setNewDocumentSizeOpen] = useState(false)
|
const [newDocumentSizeOpen, setNewDocumentSizeOpen] = useState(false)
|
||||||
@ -19,9 +17,6 @@ const DocumentSizes = () => {
|
|||||||
const [columnVisibility, setColumnVisibility] =
|
const [columnVisibility, setColumnVisibility] =
|
||||||
useColumnVisibility('documentSize')
|
useColumnVisibility('documentSize')
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('DocumentSizes')
|
|
||||||
|
|
||||||
const actionItems = {
|
const actionItems = {
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -47,7 +42,7 @@ const DocumentSizes = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
<Flex vertical={'true'} gap='large'>
|
||||||
<Flex justify={'space-between'}>
|
<Flex justify={'space-between'}>
|
||||||
<Space size='small'>
|
<Space size='small'>
|
||||||
<Dropdown menu={actionItems}>
|
<Dropdown menu={actionItems}>
|
||||||
@ -59,16 +54,13 @@ const DocumentSizes = () => {
|
|||||||
collapseState={columnVisibility}
|
collapseState={columnVisibility}
|
||||||
updateCollapseState={setColumnVisibility}
|
updateCollapseState={setColumnVisibility}
|
||||||
/>
|
/>
|
||||||
<ExportListButton objectType='documentSize' />
|
|
||||||
</Space>
|
</Space>
|
||||||
<Space>
|
<Space>
|
||||||
<FilterSidebarButton
|
<Button
|
||||||
active={showFilterSidebar}
|
icon={viewMode === 'cards' ? <ListIcon /> : <GridIcon />}
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
onClick={() =>
|
||||||
/>
|
setViewMode(viewMode === 'cards' ? 'list' : 'cards')
|
||||||
<ObjectTableViewButton
|
}
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -77,7 +69,6 @@ const DocumentSizes = () => {
|
|||||||
visibleColumns={columnVisibility}
|
visibleColumns={columnVisibility}
|
||||||
type='documentSize'
|
type='documentSize'
|
||||||
cards={viewMode === 'cards'}
|
cards={viewMode === 'cards'}
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Modal
|
<Modal
|
||||||
|
|||||||
@ -5,12 +5,10 @@ import ObjectTable from '../common/ObjectTable'
|
|||||||
import PlusIcon from '../../Icons/PlusIcon'
|
import PlusIcon from '../../Icons/PlusIcon'
|
||||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
import ReloadIcon from '../../Icons/ReloadIcon'
|
||||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
import useColumnVisibility from '../hooks/useColumnVisibility'
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
import GridIcon from '../../Icons/GridIcon'
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
import ListIcon from '../../Icons/ListIcon'
|
||||||
import useViewMode from '../hooks/useViewMode'
|
import useViewMode from '../hooks/useViewMode'
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
import ColumnViewButton from '../common/ColumnViewButton'
|
import ColumnViewButton from '../common/ColumnViewButton'
|
||||||
import ExportListButton from '../common/ExportListButton'
|
|
||||||
|
|
||||||
const DocumentTemplates = () => {
|
const DocumentTemplates = () => {
|
||||||
const [newDocumentTemplateOpen, setNewDocumentTemplateOpen] = useState(false)
|
const [newDocumentTemplateOpen, setNewDocumentTemplateOpen] = useState(false)
|
||||||
@ -21,9 +19,6 @@ const DocumentTemplates = () => {
|
|||||||
const [columnVisibility, setColumnVisibility] =
|
const [columnVisibility, setColumnVisibility] =
|
||||||
useColumnVisibility('documentTemplate')
|
useColumnVisibility('documentTemplate')
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('DocumentTemplates')
|
|
||||||
|
|
||||||
const actionItems = {
|
const actionItems = {
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -49,7 +44,7 @@ const DocumentTemplates = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
<Flex vertical={'true'} gap='large'>
|
||||||
<Flex justify={'space-between'}>
|
<Flex justify={'space-between'}>
|
||||||
<Space size='small'>
|
<Space size='small'>
|
||||||
<Dropdown menu={actionItems}>
|
<Dropdown menu={actionItems}>
|
||||||
@ -58,19 +53,16 @@ const DocumentTemplates = () => {
|
|||||||
<ColumnViewButton
|
<ColumnViewButton
|
||||||
type='documentTemplate'
|
type='documentTemplate'
|
||||||
loading={false}
|
loading={false}
|
||||||
visibleState={columnVisibility}
|
collapseState={columnVisibility}
|
||||||
updateVisibleState={setColumnVisibility}
|
updateCollapseState={setColumnVisibility}
|
||||||
/>
|
/>
|
||||||
<ExportListButton objectType='documentTemplate' />
|
|
||||||
</Space>
|
</Space>
|
||||||
<Space>
|
<Space>
|
||||||
<FilterSidebarButton
|
<Button
|
||||||
active={showFilterSidebar}
|
icon={viewMode === 'cards' ? <ListIcon /> : <GridIcon />}
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
onClick={() =>
|
||||||
/>
|
setViewMode(viewMode === 'cards' ? 'list' : 'cards')
|
||||||
<ObjectTableViewButton
|
}
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -79,7 +71,6 @@ const DocumentTemplates = () => {
|
|||||||
visibleColumns={columnVisibility}
|
visibleColumns={columnVisibility}
|
||||||
type='documentTemplate'
|
type='documentTemplate'
|
||||||
cards={viewMode === 'cards'}
|
cards={viewMode === 'cards'}
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Modal
|
<Modal
|
||||||
|
|||||||
@ -1,111 +0,0 @@
|
|||||||
import { useState, useRef } from 'react'
|
|
||||||
|
|
||||||
import { Button, Flex, Space, Modal, Dropdown } from 'antd'
|
|
||||||
|
|
||||||
import NewFilamentSku from './FilamentSkus/NewFilamentSku'
|
|
||||||
import PlusIcon from '../../Icons/PlusIcon'
|
|
||||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
|
||||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
|
||||||
import ObjectTable from '../common/ObjectTable'
|
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
|
||||||
import useViewMode from '../hooks/useViewMode'
|
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
import ColumnViewButton from '../common/ColumnViewButton'
|
|
||||||
import ExportListButton from '../common/ExportListButton'
|
|
||||||
|
|
||||||
const FilamentSkus = () => {
|
|
||||||
const tableRef = useRef()
|
|
||||||
|
|
||||||
const [newFilamentSkuOpen, setNewFilamentSkuOpen] = useState(false)
|
|
||||||
|
|
||||||
const [viewMode, setViewMode] = useViewMode('filamentSkus')
|
|
||||||
|
|
||||||
const [columnVisibility, setColumnVisibility] =
|
|
||||||
useColumnVisibility('filamentSku')
|
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('FilamentSkus')
|
|
||||||
|
|
||||||
const actionItems = {
|
|
||||||
items: [
|
|
||||||
{
|
|
||||||
label: 'New Filament SKU',
|
|
||||||
key: 'newFilamentSku',
|
|
||||||
icon: <PlusIcon />
|
|
||||||
},
|
|
||||||
{ type: 'divider' },
|
|
||||||
{
|
|
||||||
label: 'Reload List',
|
|
||||||
key: 'reloadList',
|
|
||||||
icon: <ReloadIcon />
|
|
||||||
}
|
|
||||||
],
|
|
||||||
onClick: ({ key }) => {
|
|
||||||
if (key === 'reloadList') {
|
|
||||||
tableRef.current?.reload()
|
|
||||||
} else if (key === 'newFilamentSku') {
|
|
||||||
setNewFilamentSkuOpen(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
|
||||||
<Flex justify={'space-between'}>
|
|
||||||
<Space size='small'>
|
|
||||||
<Dropdown menu={actionItems}>
|
|
||||||
<Button>Actions</Button>
|
|
||||||
</Dropdown>
|
|
||||||
<ColumnViewButton
|
|
||||||
type='filamentSku'
|
|
||||||
loading={false}
|
|
||||||
visibleState={columnVisibility}
|
|
||||||
updateVisibleState={setColumnVisibility}
|
|
||||||
/>
|
|
||||||
<ExportListButton objectType='filamentSku' />
|
|
||||||
</Space>
|
|
||||||
<Space>
|
|
||||||
<FilterSidebarButton
|
|
||||||
active={showFilterSidebar}
|
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
|
||||||
/>
|
|
||||||
<ObjectTableViewButton
|
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
|
||||||
</Space>
|
|
||||||
</Flex>
|
|
||||||
|
|
||||||
<ObjectTable
|
|
||||||
ref={tableRef}
|
|
||||||
visibleColumns={columnVisibility}
|
|
||||||
type='filamentSku'
|
|
||||||
cards={viewMode === 'cards'}
|
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
|
||||||
</Flex>
|
|
||||||
<Modal
|
|
||||||
open={newFilamentSkuOpen}
|
|
||||||
styles={{ content: { paddingBottom: '24px' } }}
|
|
||||||
footer={null}
|
|
||||||
width={700}
|
|
||||||
onCancel={() => {
|
|
||||||
setNewFilamentSkuOpen(false)
|
|
||||||
}}
|
|
||||||
destroyOnHidden={true}
|
|
||||||
>
|
|
||||||
<NewFilamentSku
|
|
||||||
onOk={() => {
|
|
||||||
setNewFilamentSkuOpen(false)
|
|
||||||
tableRef.current?.reload()
|
|
||||||
}}
|
|
||||||
reset={newFilamentSkuOpen}
|
|
||||||
/>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default FilamentSkus
|
|
||||||
@ -1,197 +0,0 @@
|
|||||||
import { useRef, useState } from 'react'
|
|
||||||
import { useLocation } from 'react-router-dom'
|
|
||||||
import { Space, Flex, Card } from 'antd'
|
|
||||||
import useCollapseState from '../../hooks/useCollapseState'
|
|
||||||
import NotesPanel from '../../common/NotesPanel'
|
|
||||||
import InfoCollapse from '../../common/InfoCollapse'
|
|
||||||
import ObjectInfo from '../../common/ObjectInfo'
|
|
||||||
import ViewButton from '../../common/ViewButton'
|
|
||||||
import ObjectForm from '../../common/ObjectForm'
|
|
||||||
import EditButtons from '../../common/EditButtons'
|
|
||||||
import LockIndicator from '../../common/LockIndicator.jsx'
|
|
||||||
import InfoCircleIcon from '../../../Icons/InfoCircleIcon.jsx'
|
|
||||||
import NoteIcon from '../../../Icons/NoteIcon.jsx'
|
|
||||||
import AuditLogIcon from '../../../Icons/AuditLogIcon.jsx'
|
|
||||||
import ActionHandler from '../../common/ActionHandler.jsx'
|
|
||||||
import ObjectActions from '../../common/ObjectActions.jsx'
|
|
||||||
import ObjectTable from '../../common/ObjectTable.jsx'
|
|
||||||
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
|
|
||||||
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
|
|
||||||
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
|
|
||||||
import ScrollBox from '../../common/ScrollBox.jsx'
|
|
||||||
|
|
||||||
const FilamentSkuInfo = () => {
|
|
||||||
const location = useLocation()
|
|
||||||
const objectFormRef = useRef(null)
|
|
||||||
const actionHandlerRef = useRef(null)
|
|
||||||
const filamentSkuId = new URLSearchParams(location.search).get('filamentSkuId')
|
|
||||||
const [collapseState, updateCollapseState] = useCollapseState(
|
|
||||||
'FilamentSkuInfo',
|
|
||||||
{
|
|
||||||
info: true,
|
|
||||||
notes: true,
|
|
||||||
auditLogs: true
|
|
||||||
}
|
|
||||||
)
|
|
||||||
const [objectFormState, setEditFormState] = useState({
|
|
||||||
isEditing: false,
|
|
||||||
editLoading: false,
|
|
||||||
formValid: false,
|
|
||||||
lock: null,
|
|
||||||
loading: false,
|
|
||||||
objectData: {}
|
|
||||||
})
|
|
||||||
|
|
||||||
const actions = {
|
|
||||||
reload: () => {
|
|
||||||
objectFormRef?.current?.fetchObject?.()
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
edit: () => {
|
|
||||||
objectFormRef?.current?.startEditing?.()
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
cancelEdit: () => {
|
|
||||||
objectFormRef?.current?.cancelEditing?.()
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
finishEdit: () => {
|
|
||||||
objectFormRef?.current?.handleUpdate?.()
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
delete: () => {
|
|
||||||
objectFormRef?.current?.handleDelete?.()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Flex
|
|
||||||
gap='large'
|
|
||||||
vertical='true'
|
|
||||||
style={{ maxHeight: '100%', minHeight: 0 }}
|
|
||||||
>
|
|
||||||
<Flex justify={'space-between'}>
|
|
||||||
<Space size='middle'>
|
|
||||||
<Space size='small'>
|
|
||||||
<ObjectActions
|
|
||||||
type='filamentSku'
|
|
||||||
id={filamentSkuId}
|
|
||||||
disabled={objectFormState.loading}
|
|
||||||
objectData={objectFormState.objectData}
|
|
||||||
/>
|
|
||||||
<ViewButton
|
|
||||||
disabled={objectFormState.loading}
|
|
||||||
items={[
|
|
||||||
{ key: 'info', label: 'Filament SKU Information' },
|
|
||||||
{ key: 'notes', label: 'Notes' },
|
|
||||||
{ key: 'auditLogs', label: 'Audit Logs' }
|
|
||||||
]}
|
|
||||||
visibleState={collapseState}
|
|
||||||
updateVisibleState={updateCollapseState}
|
|
||||||
/>
|
|
||||||
<UserNotifierToggle
|
|
||||||
type='filamentSku'
|
|
||||||
objectData={objectFormState.objectData}
|
|
||||||
disabled={objectFormState.loading}
|
|
||||||
/>
|
|
||||||
<DocumentPrintButton
|
|
||||||
type='filamentSku'
|
|
||||||
objectData={objectFormState.objectData}
|
|
||||||
disabled={objectFormState.loading}
|
|
||||||
/>
|
|
||||||
</Space>
|
|
||||||
<LockIndicator lock={objectFormState.lock} />
|
|
||||||
</Space>
|
|
||||||
<Space>
|
|
||||||
<EditButtons
|
|
||||||
isEditing={objectFormState.isEditing}
|
|
||||||
handleUpdate={() => {
|
|
||||||
actionHandlerRef.current.callAction('finishEdit')
|
|
||||||
}}
|
|
||||||
cancelEditing={() => {
|
|
||||||
actionHandlerRef.current.callAction('cancelEdit')
|
|
||||||
}}
|
|
||||||
startEditing={() => {
|
|
||||||
actionHandlerRef.current.callAction('edit')
|
|
||||||
}}
|
|
||||||
editLoading={objectFormState.editLoading}
|
|
||||||
formValid={objectFormState.formValid}
|
|
||||||
disabled={objectFormState.lock?.locked || objectFormState.loading}
|
|
||||||
loading={objectFormState.editLoading}
|
|
||||||
/>
|
|
||||||
</Space>
|
|
||||||
</Flex>
|
|
||||||
<ScrollBox>
|
|
||||||
<Flex vertical gap={'large'}>
|
|
||||||
<ActionHandler
|
|
||||||
actions={actions}
|
|
||||||
loading={objectFormState.loading}
|
|
||||||
ref={actionHandlerRef}
|
|
||||||
>
|
|
||||||
<InfoCollapse
|
|
||||||
title='Filament SKU Information'
|
|
||||||
icon={<InfoCircleIcon />}
|
|
||||||
active={collapseState.info}
|
|
||||||
onToggle={(expanded) => updateCollapseState('info', expanded)}
|
|
||||||
collapseKey='info'
|
|
||||||
>
|
|
||||||
<ObjectForm
|
|
||||||
id={filamentSkuId}
|
|
||||||
type='filamentSku'
|
|
||||||
style={{ height: '100%' }}
|
|
||||||
ref={objectFormRef}
|
|
||||||
onStateChange={(state) => {
|
|
||||||
setEditFormState((prev) => ({ ...prev, ...state }))
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{({ loading, isEditing, objectData }) => (
|
|
||||||
<ObjectInfo
|
|
||||||
loading={loading}
|
|
||||||
isEditing={isEditing}
|
|
||||||
type='filamentSku'
|
|
||||||
objectData={objectData}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</ObjectForm>
|
|
||||||
</InfoCollapse>
|
|
||||||
</ActionHandler>
|
|
||||||
<InfoCollapse
|
|
||||||
title='Notes'
|
|
||||||
icon={<NoteIcon />}
|
|
||||||
active={collapseState.notes}
|
|
||||||
onToggle={(expanded) => updateCollapseState('notes', expanded)}
|
|
||||||
collapseKey='notes'
|
|
||||||
>
|
|
||||||
<Card>
|
|
||||||
<NotesPanel _id={filamentSkuId} type='filamentSku' />
|
|
||||||
</Card>
|
|
||||||
</InfoCollapse>
|
|
||||||
<InfoCollapse
|
|
||||||
title='Audit Logs'
|
|
||||||
icon={<AuditLogIcon />}
|
|
||||||
active={collapseState.auditLogs}
|
|
||||||
onToggle={(expanded) =>
|
|
||||||
updateCollapseState('auditLogs', expanded)
|
|
||||||
}
|
|
||||||
collapseKey='auditLogs'
|
|
||||||
>
|
|
||||||
{objectFormState.loading ? (
|
|
||||||
<InfoCollapsePlaceholder />
|
|
||||||
) : (
|
|
||||||
<ObjectTable
|
|
||||||
type='auditLog'
|
|
||||||
masterFilter={{ 'parent._id': filamentSkuId }}
|
|
||||||
visibleColumns={{ _id: false, 'parent._id': false }}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</InfoCollapse>
|
|
||||||
</Flex>
|
|
||||||
</ScrollBox>
|
|
||||||
</Flex>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default FilamentSkuInfo
|
|
||||||
@ -1,123 +0,0 @@
|
|||||||
import PropTypes from 'prop-types'
|
|
||||||
import ObjectInfo from '../../common/ObjectInfo'
|
|
||||||
import NewObjectForm from '../../common/NewObjectForm'
|
|
||||||
import WizardView from '../../common/WizardView'
|
|
||||||
|
|
||||||
const NewFilamentSku = ({ onOk, reset, defaultValues }) => {
|
|
||||||
return (
|
|
||||||
<NewObjectForm
|
|
||||||
type='filamentSku'
|
|
||||||
reset={reset}
|
|
||||||
defaultValues={defaultValues}
|
|
||||||
>
|
|
||||||
{({ handleSubmit, submitLoading, objectData, formValid }) => {
|
|
||||||
const steps = [
|
|
||||||
{
|
|
||||||
title: 'Required',
|
|
||||||
key: 'required',
|
|
||||||
content: (
|
|
||||||
<ObjectInfo
|
|
||||||
type='filamentSku'
|
|
||||||
column={1}
|
|
||||||
labelWidth={70}
|
|
||||||
bordered={false}
|
|
||||||
isEditing={true}
|
|
||||||
required={true}
|
|
||||||
objectData={objectData}
|
|
||||||
visibleProperties={{
|
|
||||||
description: false,
|
|
||||||
cost: false,
|
|
||||||
costWithTax: false,
|
|
||||||
costTaxRate: false,
|
|
||||||
vendor: false
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Color & Cost',
|
|
||||||
key: 'colorCost',
|
|
||||||
content: (
|
|
||||||
<ObjectInfo
|
|
||||||
type='filamentSku'
|
|
||||||
column={1}
|
|
||||||
labelWidth={100}
|
|
||||||
visibleProperties={{
|
|
||||||
_id: false,
|
|
||||||
createdAt: false,
|
|
||||||
updatedAt: false,
|
|
||||||
barcode: false,
|
|
||||||
filament: false,
|
|
||||||
name: false,
|
|
||||||
description: false
|
|
||||||
}}
|
|
||||||
bordered={false}
|
|
||||||
isEditing={true}
|
|
||||||
objectData={objectData}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Optional',
|
|
||||||
key: 'optional',
|
|
||||||
content: (
|
|
||||||
<ObjectInfo
|
|
||||||
type='filamentSku'
|
|
||||||
column={1}
|
|
||||||
labelWidth={100}
|
|
||||||
visibleProperties={{
|
|
||||||
barcode: true,
|
|
||||||
description: true
|
|
||||||
}}
|
|
||||||
bordered={false}
|
|
||||||
isEditing={true}
|
|
||||||
objectData={objectData}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Summary',
|
|
||||||
key: 'summary',
|
|
||||||
content: (
|
|
||||||
<ObjectInfo
|
|
||||||
type='filamentSku'
|
|
||||||
column={1}
|
|
||||||
visibleProperties={{
|
|
||||||
createdAt: false,
|
|
||||||
updatedAt: false,
|
|
||||||
_id: false
|
|
||||||
}}
|
|
||||||
labelWidth={100}
|
|
||||||
bordered={false}
|
|
||||||
isEditing={false}
|
|
||||||
objectData={objectData}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
]
|
|
||||||
return (
|
|
||||||
<WizardView
|
|
||||||
steps={steps}
|
|
||||||
loading={submitLoading}
|
|
||||||
formValid={formValid}
|
|
||||||
title='New Filament SKU'
|
|
||||||
onSubmit={async () => {
|
|
||||||
const result = await handleSubmit()
|
|
||||||
if (result) {
|
|
||||||
onOk()
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
</NewObjectForm>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
NewFilamentSku.propTypes = {
|
|
||||||
onOk: PropTypes.func.isRequired,
|
|
||||||
reset: PropTypes.bool,
|
|
||||||
defaultValues: PropTypes.object
|
|
||||||
}
|
|
||||||
|
|
||||||
export default NewFilamentSku
|
|
||||||
@ -10,11 +10,9 @@ import ColumnViewButton from '../common/ColumnViewButton'
|
|||||||
import ObjectTable from '../common/ObjectTable'
|
import ObjectTable from '../common/ObjectTable'
|
||||||
import PlusIcon from '../../Icons/PlusIcon'
|
import PlusIcon from '../../Icons/PlusIcon'
|
||||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
import ReloadIcon from '../../Icons/ReloadIcon'
|
||||||
|
import ListIcon from '../../Icons/ListIcon'
|
||||||
|
import GridIcon from '../../Icons/GridIcon'
|
||||||
import useViewMode from '../hooks/useViewMode'
|
import useViewMode from '../hooks/useViewMode'
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
|
||||||
import ExportListButton from '../common/ExportListButton'
|
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
|
|
||||||
const Filaments = () => {
|
const Filaments = () => {
|
||||||
const [newFilamentOpen, setNewFilamentOpen] = useState(false)
|
const [newFilamentOpen, setNewFilamentOpen] = useState(false)
|
||||||
@ -26,9 +24,6 @@ const Filaments = () => {
|
|||||||
const [columnVisibility, setColumnVisibility] =
|
const [columnVisibility, setColumnVisibility] =
|
||||||
useColumnVisibility('filament')
|
useColumnVisibility('filament')
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('Filaments')
|
|
||||||
|
|
||||||
const actionItems = {
|
const actionItems = {
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -54,7 +49,7 @@ const Filaments = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
<Flex vertical={'true'} gap='large'>
|
||||||
<Flex justify={'space-between'}>
|
<Flex justify={'space-between'}>
|
||||||
<Space>
|
<Space>
|
||||||
<Dropdown menu={actionItems}>
|
<Dropdown menu={actionItems}>
|
||||||
@ -66,16 +61,13 @@ const Filaments = () => {
|
|||||||
visibleState={columnVisibility}
|
visibleState={columnVisibility}
|
||||||
updateVisibleState={setColumnVisibility}
|
updateVisibleState={setColumnVisibility}
|
||||||
/>
|
/>
|
||||||
<ExportListButton objectType='filament' />
|
|
||||||
</Space>
|
</Space>
|
||||||
<Space>
|
<Space>
|
||||||
<FilterSidebarButton
|
<Button
|
||||||
active={showFilterSidebar}
|
icon={viewMode === 'cards' ? <ListIcon /> : <GridIcon />}
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
onClick={() =>
|
||||||
/>
|
setViewMode(viewMode === 'cards' ? 'list' : 'cards')
|
||||||
<ObjectTableViewButton
|
}
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -85,7 +77,6 @@ const Filaments = () => {
|
|||||||
type='filament'
|
type='filament'
|
||||||
cards={viewMode === 'cards'}
|
cards={viewMode === 'cards'}
|
||||||
visibleColumns={columnVisibility}
|
visibleColumns={columnVisibility}
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Modal
|
<Modal
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { useRef, useState } from 'react'
|
import { useRef, useState } from 'react'
|
||||||
import { useLocation } from 'react-router-dom'
|
import { useLocation } from 'react-router-dom'
|
||||||
import { Space, Flex, Card, Modal } from 'antd'
|
import { Space, Flex, Card } from 'antd'
|
||||||
import { LoadingOutlined } from '@ant-design/icons'
|
import { LoadingOutlined } from '@ant-design/icons'
|
||||||
import loglevel from 'loglevel'
|
import loglevel from 'loglevel'
|
||||||
import config from '../../../../config'
|
import config from '../../../../config'
|
||||||
@ -20,11 +20,9 @@ import ObjectActions from '../../common/ObjectActions.jsx'
|
|||||||
import ObjectTable from '../../common/ObjectTable.jsx'
|
import ObjectTable from '../../common/ObjectTable.jsx'
|
||||||
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
|
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
|
||||||
import FilamentIcon from '../../../Icons/FilamentIcon.jsx'
|
import FilamentIcon from '../../../Icons/FilamentIcon.jsx'
|
||||||
import FilamentSkuIcon from '../../../Icons/FilamentSkuIcon.jsx'
|
|
||||||
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
|
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
|
||||||
import ScrollBox from '../../common/ScrollBox.jsx'
|
import ScrollBox from '../../common/ScrollBox.jsx'
|
||||||
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
|
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
|
||||||
import NewFilamentSku from '../FilamentSkus/NewFilamentSku'
|
|
||||||
|
|
||||||
const log = loglevel.getLogger('FilamentInfo')
|
const log = loglevel.getLogger('FilamentInfo')
|
||||||
log.setLevel(config.logLevel)
|
log.setLevel(config.logLevel)
|
||||||
@ -34,13 +32,10 @@ const FilamentInfo = () => {
|
|||||||
const objectFormRef = useRef(null)
|
const objectFormRef = useRef(null)
|
||||||
const actionHandlerRef = useRef(null)
|
const actionHandlerRef = useRef(null)
|
||||||
const filamentId = new URLSearchParams(location.search).get('filamentId')
|
const filamentId = new URLSearchParams(location.search).get('filamentId')
|
||||||
const [newFilamentSkuOpen, setNewFilamentSkuOpen] = useState(false)
|
|
||||||
const filamentSkusTableRef = useRef()
|
|
||||||
const [collapseState, updateCollapseState] = useCollapseState(
|
const [collapseState, updateCollapseState] = useCollapseState(
|
||||||
'FilamentInfo',
|
'FilamentInfo',
|
||||||
{
|
{
|
||||||
info: true,
|
info: true,
|
||||||
filamentSkus: true,
|
|
||||||
stocks: true,
|
stocks: true,
|
||||||
notes: true,
|
notes: true,
|
||||||
auditLogs: true
|
auditLogs: true
|
||||||
@ -61,10 +56,6 @@ const FilamentInfo = () => {
|
|||||||
objectFormRef?.current?.fetchObject?.()
|
objectFormRef?.current?.fetchObject?.()
|
||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
newFilamentSku: () => {
|
|
||||||
setNewFilamentSkuOpen(true)
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
edit: () => {
|
edit: () => {
|
||||||
objectFormRef?.current?.startEditing?.()
|
objectFormRef?.current?.startEditing?.()
|
||||||
return false
|
return false
|
||||||
@ -76,10 +67,6 @@ const FilamentInfo = () => {
|
|||||||
finishEdit: () => {
|
finishEdit: () => {
|
||||||
objectFormRef?.current?.handleUpdate?.()
|
objectFormRef?.current?.handleUpdate?.()
|
||||||
return true
|
return true
|
||||||
},
|
|
||||||
delete: () => {
|
|
||||||
objectFormRef?.current?.handleDelete?.()
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,7 +93,6 @@ const FilamentInfo = () => {
|
|||||||
disabled={objectFormState.loading}
|
disabled={objectFormState.loading}
|
||||||
items={[
|
items={[
|
||||||
{ key: 'info', label: 'Filament Information' },
|
{ key: 'info', label: 'Filament Information' },
|
||||||
{ key: 'filamentSkus', label: 'Filament SKUs' },
|
|
||||||
{ key: 'stocks', label: 'Filament Stocks' },
|
{ key: 'stocks', label: 'Filament Stocks' },
|
||||||
{ key: 'notes', label: 'Notes' },
|
{ key: 'notes', label: 'Notes' },
|
||||||
{ key: 'auditLogs', label: 'Audit Logs' }
|
{ key: 'auditLogs', label: 'Audit Logs' }
|
||||||
@ -185,27 +171,6 @@ const FilamentInfo = () => {
|
|||||||
</InfoCollapse>
|
</InfoCollapse>
|
||||||
</ActionHandler>
|
</ActionHandler>
|
||||||
|
|
||||||
<InfoCollapse
|
|
||||||
title='Filament SKUs'
|
|
||||||
icon={<FilamentSkuIcon />}
|
|
||||||
active={collapseState.filamentSkus}
|
|
||||||
onToggle={(expanded) =>
|
|
||||||
updateCollapseState('filamentSkus', expanded)
|
|
||||||
}
|
|
||||||
collapseKey='filamentSkus'
|
|
||||||
>
|
|
||||||
{objectFormState.loading ? (
|
|
||||||
<InfoCollapsePlaceholder />
|
|
||||||
) : (
|
|
||||||
<ObjectTable
|
|
||||||
ref={filamentSkusTableRef}
|
|
||||||
type='filamentSku'
|
|
||||||
masterFilter={{ filament: filamentId }}
|
|
||||||
visibleColumns={{ filament: false }}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</InfoCollapse>
|
|
||||||
|
|
||||||
<InfoCollapse
|
<InfoCollapse
|
||||||
title='Filament Stocks'
|
title='Filament Stocks'
|
||||||
icon={<FilamentIcon />}
|
icon={<FilamentIcon />}
|
||||||
@ -218,36 +183,16 @@ const FilamentInfo = () => {
|
|||||||
) : (
|
) : (
|
||||||
<ObjectTable
|
<ObjectTable
|
||||||
type='filamentStock'
|
type='filamentStock'
|
||||||
masterFilter={{ 'filamentSku.filament._id': filamentId }}
|
masterFilter={{ 'filament._id': filamentId }}
|
||||||
visibleColumns={{
|
visibleColumns={{
|
||||||
filamentSku: false,
|
filament: false,
|
||||||
'filamentSku.filament._id': false,
|
'filament._id': false,
|
||||||
startingWeight: false
|
startingWeight: false
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</InfoCollapse>
|
</InfoCollapse>
|
||||||
|
|
||||||
<Modal
|
|
||||||
open={newFilamentSkuOpen}
|
|
||||||
styles={{ content: { paddingBottom: '24px' } }}
|
|
||||||
footer={null}
|
|
||||||
width={700}
|
|
||||||
onCancel={() => setNewFilamentSkuOpen(false)}
|
|
||||||
destroyOnClose
|
|
||||||
>
|
|
||||||
<NewFilamentSku
|
|
||||||
onOk={() => {
|
|
||||||
setNewFilamentSkuOpen(false)
|
|
||||||
filamentSkusTableRef.current?.reload?.()
|
|
||||||
}}
|
|
||||||
reset={newFilamentSkuOpen}
|
|
||||||
defaultValues={{
|
|
||||||
filament: filamentId ? { _id: filamentId } : undefined
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Modal>
|
|
||||||
|
|
||||||
<InfoCollapse
|
<InfoCollapse
|
||||||
title='Notes'
|
title='Notes'
|
||||||
icon={<NoteIcon />}
|
icon={<NoteIcon />}
|
||||||
|
|||||||
@ -3,12 +3,10 @@ import { Button, Flex, Space, Dropdown } from 'antd'
|
|||||||
import ObjectTable from '../common/ObjectTable'
|
import ObjectTable from '../common/ObjectTable'
|
||||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
import ReloadIcon from '../../Icons/ReloadIcon'
|
||||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
import useColumnVisibility from '../hooks/useColumnVisibility'
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
import GridIcon from '../../Icons/GridIcon'
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
import ListIcon from '../../Icons/ListIcon'
|
||||||
import useViewMode from '../hooks/useViewMode'
|
import useViewMode from '../hooks/useViewMode'
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
import ColumnViewButton from '../common/ColumnViewButton'
|
import ColumnViewButton from '../common/ColumnViewButton'
|
||||||
import ExportListButton from '../common/ExportListButton'
|
|
||||||
|
|
||||||
const Files = () => {
|
const Files = () => {
|
||||||
const tableRef = useRef()
|
const tableRef = useRef()
|
||||||
@ -17,9 +15,6 @@ const Files = () => {
|
|||||||
|
|
||||||
const [columnVisibility, setColumnVisibility] = useColumnVisibility('file')
|
const [columnVisibility, setColumnVisibility] = useColumnVisibility('file')
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('Files')
|
|
||||||
|
|
||||||
const actionItems = {
|
const actionItems = {
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -37,7 +32,7 @@ const Files = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
<Flex vertical={'true'} gap='large'>
|
||||||
<Flex justify={'space-between'}>
|
<Flex justify={'space-between'}>
|
||||||
<Space size='small'>
|
<Space size='small'>
|
||||||
<Dropdown menu={actionItems}>
|
<Dropdown menu={actionItems}>
|
||||||
@ -46,19 +41,16 @@ const Files = () => {
|
|||||||
<ColumnViewButton
|
<ColumnViewButton
|
||||||
type='file'
|
type='file'
|
||||||
loading={false}
|
loading={false}
|
||||||
visibleState={columnVisibility}
|
collapseState={columnVisibility}
|
||||||
updateVisibleState={setColumnVisibility}
|
updateCollapseState={setColumnVisibility}
|
||||||
/>
|
/>
|
||||||
<ExportListButton objectType='file' />
|
|
||||||
</Space>
|
</Space>
|
||||||
<Space>
|
<Space>
|
||||||
<FilterSidebarButton
|
<Button
|
||||||
active={showFilterSidebar}
|
icon={viewMode === 'cards' ? <ListIcon /> : <GridIcon />}
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
onClick={() =>
|
||||||
/>
|
setViewMode(viewMode === 'cards' ? 'list' : 'cards')
|
||||||
<ObjectTableViewButton
|
}
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -67,7 +59,6 @@ const Files = () => {
|
|||||||
visibleColumns={columnVisibility}
|
visibleColumns={columnVisibility}
|
||||||
type='file'
|
type='file'
|
||||||
cards={viewMode === 'cards'}
|
cards={viewMode === 'cards'}
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -7,14 +7,12 @@ import NewHost from './Hosts/NewHost'
|
|||||||
|
|
||||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
import useColumnVisibility from '../hooks/useColumnVisibility'
|
||||||
import ColumnViewButton from '../common/ColumnViewButton'
|
import ColumnViewButton from '../common/ColumnViewButton'
|
||||||
import ExportListButton from '../common/ExportListButton'
|
|
||||||
import ObjectTable from '../common/ObjectTable'
|
import ObjectTable from '../common/ObjectTable'
|
||||||
import PlusIcon from '../../Icons/PlusIcon'
|
import PlusIcon from '../../Icons/PlusIcon'
|
||||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
import ReloadIcon from '../../Icons/ReloadIcon'
|
||||||
|
import ListIcon from '../../Icons/ListIcon'
|
||||||
|
import GridIcon from '../../Icons/GridIcon'
|
||||||
import useViewMode from '../hooks/useViewMode'
|
import useViewMode from '../hooks/useViewMode'
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
|
|
||||||
const Hosts = () => {
|
const Hosts = () => {
|
||||||
const [newHostOpen, setNewHostOpen] = useState(false)
|
const [newHostOpen, setNewHostOpen] = useState(false)
|
||||||
@ -25,9 +23,6 @@ const Hosts = () => {
|
|||||||
|
|
||||||
const [columnVisibility, setColumnVisibility] = useColumnVisibility('host')
|
const [columnVisibility, setColumnVisibility] = useColumnVisibility('host')
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('Hosts')
|
|
||||||
|
|
||||||
const actionItems = {
|
const actionItems = {
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -53,7 +48,7 @@ const Hosts = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
<Flex vertical={'true'} gap='large'>
|
||||||
<Flex justify={'space-between'}>
|
<Flex justify={'space-between'}>
|
||||||
<Space>
|
<Space>
|
||||||
<Dropdown menu={actionItems}>
|
<Dropdown menu={actionItems}>
|
||||||
@ -65,16 +60,13 @@ const Hosts = () => {
|
|||||||
visibleState={columnVisibility}
|
visibleState={columnVisibility}
|
||||||
updateVisibleState={setColumnVisibility}
|
updateVisibleState={setColumnVisibility}
|
||||||
/>
|
/>
|
||||||
<ExportListButton objectType='host' />
|
|
||||||
</Space>
|
</Space>
|
||||||
<Space>
|
<Space>
|
||||||
<FilterSidebarButton
|
<Button
|
||||||
active={showFilterSidebar}
|
icon={viewMode === 'cards' ? <ListIcon /> : <GridIcon />}
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
onClick={() =>
|
||||||
/>
|
setViewMode(viewMode === 'cards' ? 'list' : 'cards')
|
||||||
<ObjectTableViewButton
|
}
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -84,14 +76,12 @@ const Hosts = () => {
|
|||||||
type='host'
|
type='host'
|
||||||
cards={viewMode === 'cards'}
|
cards={viewMode === 'cards'}
|
||||||
visibleColumns={columnVisibility}
|
visibleColumns={columnVisibility}
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Modal
|
<Modal
|
||||||
open={newHostOpen}
|
open={newHostOpen}
|
||||||
footer={null}
|
footer={null}
|
||||||
width={700}
|
width={700}
|
||||||
destroyOnHidden={true}
|
|
||||||
onCancel={() => {
|
onCancel={() => {
|
||||||
setNewHostOpen(false)
|
setNewHostOpen(false)
|
||||||
}}
|
}}
|
||||||
|
|||||||
@ -1,14 +1,21 @@
|
|||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
import { useState } from 'react'
|
||||||
|
import { useMediaQuery } from 'react-responsive'
|
||||||
|
import { Typography, Flex, Steps, Divider } from 'antd'
|
||||||
|
|
||||||
import ObjectInfo from '../../common/ObjectInfo'
|
import ObjectInfo from '../../common/ObjectInfo'
|
||||||
import NewObjectForm from '../../common/NewObjectForm'
|
import NewObjectForm from '../../common/NewObjectForm'
|
||||||
import WizardView from '../../common/WizardView'
|
import NewObjectButtons from '../../common/NewObjectButtons'
|
||||||
|
|
||||||
|
const { Title } = Typography
|
||||||
|
|
||||||
const NewHost = ({ onOk }) => {
|
const NewHost = ({ onOk }) => {
|
||||||
|
const [currentStep, setCurrentStep] = useState(0)
|
||||||
|
|
||||||
|
const isMobile = useMediaQuery({ maxWidth: 768 })
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NewObjectForm
|
<NewObjectForm type={'host'}>
|
||||||
type={'host'}
|
|
||||||
defaultValues={{ active: true, state: { type: 'offline' } }}
|
|
||||||
>
|
|
||||||
{({ handleSubmit, submitLoading, objectData, formValid }) => {
|
{({ handleSubmit, submitLoading, objectData, formValid }) => {
|
||||||
const steps = [
|
const steps = [
|
||||||
{
|
{
|
||||||
@ -36,20 +43,6 @@ const NewHost = ({ onOk }) => {
|
|||||||
isEditing={true}
|
isEditing={true}
|
||||||
required={false}
|
required={false}
|
||||||
objectData={objectData}
|
objectData={objectData}
|
||||||
visibleProperties={{
|
|
||||||
_id: false,
|
|
||||||
createdAt: false,
|
|
||||||
updatedAt: false,
|
|
||||||
operatingSystem: false,
|
|
||||||
'deviceInfo.os': false,
|
|
||||||
'deviceInfo.os.hostname': false,
|
|
||||||
'deviceInfo.cpu': false,
|
|
||||||
'deviceInfo.cpu.model': false,
|
|
||||||
'deviceInfo.user.username': false,
|
|
||||||
'deviceInfo.user.homedir': false,
|
|
||||||
'deviceInfo.process.nodeVersion': false,
|
|
||||||
files: false
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -64,18 +57,7 @@ const NewHost = ({ onOk }) => {
|
|||||||
visibleProperties={{
|
visibleProperties={{
|
||||||
_id: false,
|
_id: false,
|
||||||
createdAt: false,
|
createdAt: false,
|
||||||
updatedAt: false,
|
updatedAt: false
|
||||||
operatingSystem: false,
|
|
||||||
'deviceInfo.os': false,
|
|
||||||
'deviceInfo.os.hostname': false,
|
|
||||||
'deviceInfo.cpu': false,
|
|
||||||
'deviceInfo.cpu.model': false,
|
|
||||||
'deviceInfo.user.username': false,
|
|
||||||
'deviceInfo.user.homedir': false,
|
|
||||||
'deviceInfo.process.nodeVersion': false,
|
|
||||||
files: false,
|
|
||||||
connectedAt: false,
|
|
||||||
online: false
|
|
||||||
}}
|
}}
|
||||||
isEditing={false}
|
isEditing={false}
|
||||||
objectData={objectData}
|
objectData={objectData}
|
||||||
@ -84,18 +66,45 @@ const NewHost = ({ onOk }) => {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
return (
|
return (
|
||||||
<WizardView
|
<Flex gap='middle'>
|
||||||
steps={steps}
|
{!isMobile && (
|
||||||
loading={submitLoading}
|
<div style={{ minWidth: '160px' }}>
|
||||||
formValid={formValid}
|
<Steps
|
||||||
title='New Host'
|
current={currentStep}
|
||||||
onSubmit={async () => {
|
items={steps}
|
||||||
const result = await handleSubmit()
|
direction='vertical'
|
||||||
if (result) {
|
style={{ width: 'fit-content' }}
|
||||||
onOk()
|
/>
|
||||||
}
|
</div>
|
||||||
}}
|
)}
|
||||||
/>
|
|
||||||
|
{!isMobile && (
|
||||||
|
<Divider type='vertical' style={{ height: 'unset' }} />
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Flex vertical gap='middle' style={{ flexGrow: 1 }}>
|
||||||
|
<Title level={2} style={{ margin: 0 }}>
|
||||||
|
New Host
|
||||||
|
</Title>
|
||||||
|
<div style={{ minHeight: '260px', marginBottom: 8 }}>
|
||||||
|
{steps[currentStep].content}
|
||||||
|
</div>
|
||||||
|
<NewObjectButtons
|
||||||
|
currentStep={currentStep}
|
||||||
|
totalSteps={steps.length}
|
||||||
|
onPrevious={() => setCurrentStep((prev) => prev - 1)}
|
||||||
|
onNext={() => setCurrentStep((prev) => prev + 1)}
|
||||||
|
onSubmit={async () => {
|
||||||
|
const result = await handleSubmit()
|
||||||
|
if (result) {
|
||||||
|
onOk()
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
formValid={formValid}
|
||||||
|
submitLoading={submitLoading}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
</NewObjectForm>
|
</NewObjectForm>
|
||||||
|
|||||||
@ -1,11 +1,8 @@
|
|||||||
import { useLocation } from 'react-router-dom'
|
import { useLocation } from 'react-router-dom'
|
||||||
import DashboardSidebar from '../common/DashboardSidebar'
|
import DashboardSidebar from '../common/DashboardSidebar'
|
||||||
import FilamentIcon from '../../Icons/FilamentIcon'
|
import FilamentIcon from '../../Icons/FilamentIcon'
|
||||||
import FilamentSkuIcon from '../../Icons/FilamentSkuIcon'
|
|
||||||
import PartIcon from '../../Icons/PartIcon'
|
import PartIcon from '../../Icons/PartIcon'
|
||||||
import PartSkuIcon from '../../Icons/PartSkuIcon'
|
|
||||||
import ProductIcon from '../../Icons/ProductIcon'
|
import ProductIcon from '../../Icons/ProductIcon'
|
||||||
import ProductSkuIcon from '../../Icons/ProductSkuIcon'
|
|
||||||
import VendorIcon from '../../Icons/VendorIcon'
|
import VendorIcon from '../../Icons/VendorIcon'
|
||||||
import MaterialIcon from '../../Icons/MaterialIcon'
|
import MaterialIcon from '../../Icons/MaterialIcon'
|
||||||
import NoteTypeIcon from '../../Icons/NoteTypeIcon'
|
import NoteTypeIcon from '../../Icons/NoteTypeIcon'
|
||||||
@ -24,7 +21,6 @@ import CourierIcon from '../../Icons/CourierIcon'
|
|||||||
import CourierServiceIcon from '../../Icons/CourierServiceIcon'
|
import CourierServiceIcon from '../../Icons/CourierServiceIcon'
|
||||||
import TaxRateIcon from '../../Icons/TaxRateIcon'
|
import TaxRateIcon from '../../Icons/TaxRateIcon'
|
||||||
import TaxRecordIcon from '../../Icons/TaxRecordIcon'
|
import TaxRecordIcon from '../../Icons/TaxRecordIcon'
|
||||||
import AppPasswordIcon from '../../Icons/AppPasswordIcon'
|
|
||||||
|
|
||||||
const items = [
|
const items = [
|
||||||
{
|
{
|
||||||
@ -33,36 +29,18 @@ const items = [
|
|||||||
label: 'Filaments',
|
label: 'Filaments',
|
||||||
path: '/dashboard/management/filaments'
|
path: '/dashboard/management/filaments'
|
||||||
},
|
},
|
||||||
{
|
|
||||||
key: 'filamentSkus',
|
|
||||||
icon: <FilamentSkuIcon />,
|
|
||||||
label: 'Filament SKUs',
|
|
||||||
path: '/dashboard/management/filamentskus'
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
key: 'parts',
|
key: 'parts',
|
||||||
icon: <PartIcon />,
|
icon: <PartIcon />,
|
||||||
label: 'Parts',
|
label: 'Parts',
|
||||||
path: '/dashboard/management/parts'
|
path: '/dashboard/management/parts'
|
||||||
},
|
},
|
||||||
{
|
|
||||||
key: 'partSkus',
|
|
||||||
icon: <PartSkuIcon />,
|
|
||||||
label: 'Part SKUs',
|
|
||||||
path: '/dashboard/management/partskus'
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
key: 'products',
|
key: 'products',
|
||||||
icon: <ProductIcon />,
|
icon: <ProductIcon />,
|
||||||
label: 'Products',
|
label: 'Products',
|
||||||
path: '/dashboard/management/products'
|
path: '/dashboard/management/products'
|
||||||
},
|
},
|
||||||
{
|
|
||||||
key: 'productSkus',
|
|
||||||
icon: <ProductSkuIcon />,
|
|
||||||
label: 'Product SKUs',
|
|
||||||
path: '/dashboard/management/productskus'
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
key: 'vendors',
|
key: 'vendors',
|
||||||
icon: <VendorIcon />,
|
icon: <VendorIcon />,
|
||||||
@ -153,12 +131,6 @@ const items = [
|
|||||||
label: 'Users',
|
label: 'Users',
|
||||||
path: '/dashboard/management/users'
|
path: '/dashboard/management/users'
|
||||||
},
|
},
|
||||||
{
|
|
||||||
key: 'appPasswords',
|
|
||||||
icon: <AppPasswordIcon />,
|
|
||||||
label: 'App Passwords',
|
|
||||||
path: '/dashboard/management/apppasswords'
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
key: 'settings',
|
key: 'settings',
|
||||||
icon: <SettingsIcon />,
|
icon: <SettingsIcon />,
|
||||||
@ -193,13 +165,9 @@ if (import.meta.env.MODE === 'development') {
|
|||||||
|
|
||||||
const routeKeyMap = {
|
const routeKeyMap = {
|
||||||
'/dashboard/management/filaments': 'filaments',
|
'/dashboard/management/filaments': 'filaments',
|
||||||
'/dashboard/management/filamentskus': 'filamentSkus',
|
|
||||||
'/dashboard/management/parts': 'parts',
|
'/dashboard/management/parts': 'parts',
|
||||||
'/dashboard/management/partskus': 'partSkus',
|
|
||||||
'/dashboard/management/users': 'users',
|
'/dashboard/management/users': 'users',
|
||||||
'/dashboard/management/apppasswords': 'appPasswords',
|
|
||||||
'/dashboard/management/products': 'products',
|
'/dashboard/management/products': 'products',
|
||||||
'/dashboard/management/productskus': 'productSkus',
|
|
||||||
'/dashboard/management/vendors': 'vendors',
|
'/dashboard/management/vendors': 'vendors',
|
||||||
'/dashboard/management/couriers': 'couriers',
|
'/dashboard/management/couriers': 'couriers',
|
||||||
'/dashboard/management/courierservices': 'courierServices',
|
'/dashboard/management/courierservices': 'courierServices',
|
||||||
|
|||||||
@ -1,30 +1,218 @@
|
|||||||
import { useRef, useState } from 'react'
|
// src/materials.js
|
||||||
import { Button, Flex, Space, Modal, Dropdown } from 'antd'
|
|
||||||
|
import { useEffect, useState, useContext, useCallback } from 'react'
|
||||||
|
import { useNavigate } from 'react-router-dom'
|
||||||
|
import axios from 'axios'
|
||||||
|
import {
|
||||||
|
Table,
|
||||||
|
Button,
|
||||||
|
Flex,
|
||||||
|
Space,
|
||||||
|
Modal,
|
||||||
|
Dropdown,
|
||||||
|
Spin
|
||||||
|
} from 'antd'
|
||||||
|
import { createStyles } from 'antd-style'
|
||||||
|
import { LoadingOutlined } from '@ant-design/icons'
|
||||||
|
import { useMessageContext } from '../context/MessageContext'
|
||||||
|
|
||||||
|
import { AuthContext } from '../context/AuthContext'
|
||||||
|
|
||||||
import NewMaterial from './Materials/NewMaterial'
|
import NewMaterial from './Materials/NewMaterial'
|
||||||
|
import IdDisplay from '../common/IdDisplay'
|
||||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
import MaterialIcon from '../../Icons/MaterialIcon'
|
||||||
import ColumnViewButton from '../common/ColumnViewButton'
|
import InfoCircleIcon from '../../Icons/InfoCircleIcon'
|
||||||
import ObjectTable from '../common/ObjectTable'
|
|
||||||
import PlusIcon from '../../Icons/PlusIcon'
|
import PlusIcon from '../../Icons/PlusIcon'
|
||||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
import ReloadIcon from '../../Icons/ReloadIcon'
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
import TimeDisplay from '../common/TimeDisplay'
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
|
||||||
import useViewMode from '../hooks/useViewMode'
|
import config from '../../../config'
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
import ExportListButton from '../common/ExportListButton'
|
const useStyle = createStyles(({ css, token }) => {
|
||||||
|
const { antCls } = token
|
||||||
|
return {
|
||||||
|
customTable: css`
|
||||||
|
${antCls}-table {
|
||||||
|
${antCls}-table-container {
|
||||||
|
${antCls}-table-body,
|
||||||
|
${antCls}-table-content {
|
||||||
|
scrollbar-width: thin;
|
||||||
|
scrollbar-color: #eaeaea transparent;
|
||||||
|
scrollbar-gutter: stable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const Materials = () => {
|
const Materials = () => {
|
||||||
|
const { showError } = useMessageContext()
|
||||||
|
const navigate = useNavigate()
|
||||||
|
const { styles } = useStyle()
|
||||||
|
|
||||||
|
const [materialsData, setMaterialsData] = useState([])
|
||||||
|
const [page, setPage] = useState(1)
|
||||||
|
const [hasMore, setHasMore] = useState(true)
|
||||||
|
const [loading, setLoading] = useState(true)
|
||||||
|
const [lazyLoading, setLazyLoading] = useState(false)
|
||||||
const [newMaterialOpen, setNewMaterialOpen] = useState(false)
|
const [newMaterialOpen, setNewMaterialOpen] = useState(false)
|
||||||
const tableRef = useRef()
|
|
||||||
|
|
||||||
const [viewMode, setViewMode] = useViewMode('material')
|
const { authenticated } = useContext(AuthContext)
|
||||||
|
|
||||||
const [columnVisibility, setColumnVisibility] =
|
const fetchMaterialsData = useCallback(
|
||||||
useColumnVisibility('material')
|
async (pageNum = 1, append = false) => {
|
||||||
|
try {
|
||||||
|
const response = await axios.get(`${config.backendUrl}/materials`, {
|
||||||
|
params: {
|
||||||
|
page: pageNum,
|
||||||
|
limit: 25
|
||||||
|
},
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json'
|
||||||
|
},
|
||||||
|
withCredentials: true
|
||||||
|
})
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
const newData = response.data
|
||||||
useFilterSidebarVisibility('Materials')
|
setHasMore(newData.length === 25) // If we get less than 25 items, we've reached the end
|
||||||
|
|
||||||
|
if (append) {
|
||||||
|
setMaterialsData((prev) => [...prev, ...newData])
|
||||||
|
} else {
|
||||||
|
setMaterialsData(newData)
|
||||||
|
}
|
||||||
|
|
||||||
|
setLoading(false)
|
||||||
|
setLazyLoading(false)
|
||||||
|
} catch (error) {
|
||||||
|
if (error.response) {
|
||||||
|
showError(
|
||||||
|
`Error updating material details: ${error.response.status}`
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
showError(
|
||||||
|
'An unexpected error occurred. Please try again later.'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
setLoading(false)
|
||||||
|
setLazyLoading(false)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[showError]
|
||||||
|
)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (authenticated) {
|
||||||
|
fetchMaterialsData()
|
||||||
|
}
|
||||||
|
}, [authenticated, fetchMaterialsData])
|
||||||
|
|
||||||
|
const handleScroll = useCallback(
|
||||||
|
(e) => {
|
||||||
|
const { target } = e
|
||||||
|
const scrollHeight = target.scrollHeight
|
||||||
|
const scrollTop = target.scrollTop
|
||||||
|
const clientHeight = target.clientHeight
|
||||||
|
|
||||||
|
// If we're near the bottom (within 100px) and not currently loading
|
||||||
|
if (
|
||||||
|
scrollHeight - scrollTop - clientHeight < 100 &&
|
||||||
|
!lazyLoading &&
|
||||||
|
hasMore
|
||||||
|
) {
|
||||||
|
setLazyLoading(true)
|
||||||
|
const nextPage = page + 1
|
||||||
|
setPage(nextPage)
|
||||||
|
fetchMaterialsData(nextPage, true)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[page, lazyLoading, hasMore, fetchMaterialsData]
|
||||||
|
)
|
||||||
|
|
||||||
|
const getMaterialActionItems = (id) => {
|
||||||
|
return {
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
label: 'Info',
|
||||||
|
key: 'info',
|
||||||
|
icon: <InfoCircleIcon />
|
||||||
|
}
|
||||||
|
],
|
||||||
|
onClick: ({ key }) => {
|
||||||
|
if (key === 'info') {
|
||||||
|
navigate(`/dashboard/management/materials/info?materialId=${id}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: '',
|
||||||
|
dataIndex: '',
|
||||||
|
key: 'icon',
|
||||||
|
width: 40,
|
||||||
|
fixed: 'left',
|
||||||
|
render: () => <MaterialIcon></MaterialIcon>
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Name',
|
||||||
|
dataIndex: 'name',
|
||||||
|
key: 'name',
|
||||||
|
width: 200,
|
||||||
|
fixed: 'left'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'ID',
|
||||||
|
dataIndex: '_id',
|
||||||
|
key: 'id',
|
||||||
|
width: 180,
|
||||||
|
render: (text) => <IdDisplay id={text} type={'material'} longId={false} />
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Category',
|
||||||
|
dataIndex: 'category',
|
||||||
|
key: 'category',
|
||||||
|
width: 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Created At',
|
||||||
|
dataIndex: 'createdAt',
|
||||||
|
key: 'createdAt',
|
||||||
|
width: 180,
|
||||||
|
render: (createdAt) => {
|
||||||
|
if (createdAt) {
|
||||||
|
return <TimeDisplay dateTime={createdAt} />
|
||||||
|
} else {
|
||||||
|
return 'n/a'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Actions',
|
||||||
|
key: 'actions',
|
||||||
|
fixed: 'right',
|
||||||
|
width: 150,
|
||||||
|
render: (text, record) => {
|
||||||
|
return (
|
||||||
|
<Space gap='small'>
|
||||||
|
<Button
|
||||||
|
icon={<InfoCircleIcon />}
|
||||||
|
onClick={() =>
|
||||||
|
navigate(
|
||||||
|
`/dashboard/management/materials/info?materialId=${record._id}`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Dropdown menu={getMaterialActionItems(record._id)}>
|
||||||
|
<Button>Actions</Button>
|
||||||
|
</Dropdown>
|
||||||
|
</Space>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
const actionItems = {
|
const actionItems = {
|
||||||
items: [
|
items: [
|
||||||
@ -42,7 +230,7 @@ const Materials = () => {
|
|||||||
],
|
],
|
||||||
onClick: ({ key }) => {
|
onClick: ({ key }) => {
|
||||||
if (key === 'reloadList') {
|
if (key === 'reloadList') {
|
||||||
tableRef.current?.reload()
|
fetchMaterialsData()
|
||||||
} else if (key === 'newMaterial') {
|
} else if (key === 'newMaterial') {
|
||||||
setNewMaterialOpen(true)
|
setNewMaterialOpen(true)
|
||||||
}
|
}
|
||||||
@ -51,57 +239,44 @@ const Materials = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
<Flex vertical={'true'} gap='large'>
|
||||||
<Flex justify={'space-between'}>
|
<Space>
|
||||||
<Space>
|
<Dropdown menu={actionItems}>
|
||||||
<Dropdown menu={actionItems}>
|
<Button>Actions</Button>
|
||||||
<Button>Actions</Button>
|
</Dropdown>
|
||||||
</Dropdown>
|
</Space>
|
||||||
<ColumnViewButton
|
<Table
|
||||||
type='material'
|
dataSource={materialsData}
|
||||||
loading={false}
|
className={styles.customTable}
|
||||||
visibleState={columnVisibility}
|
columns={columns}
|
||||||
updateVisibleState={setColumnVisibility}
|
pagination={false}
|
||||||
/>
|
rowKey='_id'
|
||||||
<ExportListButton objectType='material' />
|
loading={{ spinning: loading, indicator: <LoadingOutlined spin /> }}
|
||||||
</Space>
|
scroll={{ y: 'calc(100vh - 270px)' }}
|
||||||
<Space>
|
onScroll={handleScroll}
|
||||||
<FilterSidebarButton
|
|
||||||
active={showFilterSidebar}
|
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
|
||||||
/>
|
|
||||||
<ObjectTableViewButton
|
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
|
||||||
</Space>
|
|
||||||
</Flex>
|
|
||||||
|
|
||||||
<ObjectTable
|
|
||||||
ref={tableRef}
|
|
||||||
type='material'
|
|
||||||
cards={viewMode === 'cards'}
|
|
||||||
visibleColumns={columnVisibility}
|
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
/>
|
||||||
|
{lazyLoading && (
|
||||||
<Modal
|
<div style={{ textAlign: 'center', padding: '10px' }}>
|
||||||
open={newMaterialOpen}
|
<Spin indicator={<LoadingOutlined spin />} />
|
||||||
footer={null}
|
</div>
|
||||||
width={700}
|
)}
|
||||||
onCancel={() => {
|
|
||||||
setNewMaterialOpen(false)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<NewMaterial
|
|
||||||
onOk={() => {
|
|
||||||
setNewMaterialOpen(false)
|
|
||||||
tableRef.current?.reload()
|
|
||||||
}}
|
|
||||||
reset={newMaterialOpen}
|
|
||||||
/>
|
|
||||||
</Modal>
|
|
||||||
</Flex>
|
</Flex>
|
||||||
|
<Modal
|
||||||
|
open={newMaterialOpen}
|
||||||
|
styles={{ content: { paddingBottom: '24px' } }}
|
||||||
|
footer={null}
|
||||||
|
width={700}
|
||||||
|
onCancel={() => {
|
||||||
|
setNewMaterialOpen(false)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<NewMaterial
|
||||||
|
onSuccess={() => {
|
||||||
|
setNewMaterialOpen(false)
|
||||||
|
fetchMaterialsData()
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Modal>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,199 +0,0 @@
|
|||||||
import { useRef, useState } from 'react'
|
|
||||||
import { useLocation } from 'react-router-dom'
|
|
||||||
import { Space, Flex, Card } from 'antd'
|
|
||||||
import loglevel from 'loglevel'
|
|
||||||
import config from '../../../../config'
|
|
||||||
import useCollapseState from '../../hooks/useCollapseState'
|
|
||||||
import NotesPanel from '../../common/NotesPanel'
|
|
||||||
import InfoCollapse from '../../common/InfoCollapse'
|
|
||||||
import ObjectInfo from '../../common/ObjectInfo'
|
|
||||||
import ViewButton from '../../common/ViewButton'
|
|
||||||
import InfoCircleIcon from '../../../Icons/InfoCircleIcon.jsx'
|
|
||||||
import NoteIcon from '../../../Icons/NoteIcon.jsx'
|
|
||||||
import AuditLogIcon from '../../../Icons/AuditLogIcon.jsx'
|
|
||||||
import ObjectForm from '../../common/ObjectForm'
|
|
||||||
import EditButtons from '../../common/EditButtons'
|
|
||||||
import LockIndicator from '../../common/LockIndicator.jsx'
|
|
||||||
import ActionHandler from '../../common/ActionHandler.jsx'
|
|
||||||
import ObjectActions from '../../common/ObjectActions.jsx'
|
|
||||||
import ObjectTable from '../../common/ObjectTable.jsx'
|
|
||||||
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
|
|
||||||
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
|
|
||||||
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
|
|
||||||
import ScrollBox from '../../common/ScrollBox.jsx'
|
|
||||||
|
|
||||||
const log = loglevel.getLogger('MaterialInfo')
|
|
||||||
log.setLevel(config.logLevel)
|
|
||||||
|
|
||||||
const MaterialInfo = () => {
|
|
||||||
const location = useLocation()
|
|
||||||
const objectFormRef = useRef(null)
|
|
||||||
const actionHandlerRef = useRef(null)
|
|
||||||
const materialId = new URLSearchParams(location.search).get('materialId')
|
|
||||||
const [collapseState, updateCollapseState] = useCollapseState('MaterialInfo', {
|
|
||||||
info: true,
|
|
||||||
notes: true,
|
|
||||||
auditLogs: true
|
|
||||||
})
|
|
||||||
const [objectFormState, setEditFormState] = useState({
|
|
||||||
isEditing: false,
|
|
||||||
editLoading: false,
|
|
||||||
formValid: false,
|
|
||||||
lock: null,
|
|
||||||
loading: false,
|
|
||||||
objectData: {}
|
|
||||||
})
|
|
||||||
|
|
||||||
const actions = {
|
|
||||||
reload: () => {
|
|
||||||
objectFormRef?.current?.handleFetchObject?.()
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
edit: () => {
|
|
||||||
objectFormRef?.current?.startEditing?.()
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
cancelEdit: () => {
|
|
||||||
objectFormRef?.current?.cancelEditing?.()
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
finishEdit: () => {
|
|
||||||
objectFormRef?.current?.handleUpdate?.()
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
delete: () => {
|
|
||||||
objectFormRef?.current?.handleDelete?.()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Flex
|
|
||||||
gap='large'
|
|
||||||
vertical='true'
|
|
||||||
style={{ maxHeight: '100%', minHeight: 0 }}
|
|
||||||
>
|
|
||||||
<Flex justify={'space-between'}>
|
|
||||||
<Space size='middle'>
|
|
||||||
<Space size='small'>
|
|
||||||
<ObjectActions
|
|
||||||
type='material'
|
|
||||||
id={materialId}
|
|
||||||
disabled={objectFormState.loading}
|
|
||||||
objectData={objectFormState.objectData}
|
|
||||||
/>
|
|
||||||
<ViewButton
|
|
||||||
disabled={objectFormState.loading}
|
|
||||||
items={[
|
|
||||||
{ key: 'info', label: 'Material Information' },
|
|
||||||
{ key: 'notes', label: 'Notes' },
|
|
||||||
{ key: 'auditLogs', label: 'Audit Logs' }
|
|
||||||
]}
|
|
||||||
visibleState={collapseState}
|
|
||||||
updateVisibleState={updateCollapseState}
|
|
||||||
/>
|
|
||||||
<UserNotifierToggle
|
|
||||||
type='material'
|
|
||||||
objectData={objectFormState.objectData}
|
|
||||||
disabled={objectFormState.loading}
|
|
||||||
/>
|
|
||||||
<DocumentPrintButton
|
|
||||||
type='material'
|
|
||||||
objectData={objectFormState.objectData}
|
|
||||||
disabled={objectFormState.loading}
|
|
||||||
/>
|
|
||||||
</Space>
|
|
||||||
<LockIndicator lock={objectFormState.lock} />
|
|
||||||
</Space>
|
|
||||||
<Space>
|
|
||||||
<EditButtons
|
|
||||||
isEditing={objectFormState.isEditing}
|
|
||||||
handleUpdate={() => {
|
|
||||||
actionHandlerRef.current.callAction('finishEdit')
|
|
||||||
}}
|
|
||||||
cancelEditing={() => {
|
|
||||||
actionHandlerRef.current.callAction('cancelEdit')
|
|
||||||
}}
|
|
||||||
startEditing={() => {
|
|
||||||
actionHandlerRef.current.callAction('edit')
|
|
||||||
}}
|
|
||||||
editLoading={objectFormState.editLoading}
|
|
||||||
formValid={objectFormState.formValid}
|
|
||||||
disabled={objectFormState.lock?.locked || objectFormState.loading}
|
|
||||||
loading={objectFormState.editLoading}
|
|
||||||
/>
|
|
||||||
</Space>
|
|
||||||
</Flex>
|
|
||||||
<ScrollBox>
|
|
||||||
<Flex vertical gap={'large'}>
|
|
||||||
<ActionHandler
|
|
||||||
actions={actions}
|
|
||||||
loading={objectFormState.loading}
|
|
||||||
ref={actionHandlerRef}
|
|
||||||
>
|
|
||||||
<InfoCollapse
|
|
||||||
title='Material Information'
|
|
||||||
icon={<InfoCircleIcon />}
|
|
||||||
active={collapseState.info}
|
|
||||||
onToggle={(expanded) => updateCollapseState('info', expanded)}
|
|
||||||
collapseKey='info'
|
|
||||||
>
|
|
||||||
<ObjectForm
|
|
||||||
id={materialId}
|
|
||||||
type='material'
|
|
||||||
style={{ height: '100%' }}
|
|
||||||
ref={objectFormRef}
|
|
||||||
onStateChange={(state) => {
|
|
||||||
setEditFormState((prev) => ({ ...prev, ...state }))
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{({ loading, isEditing, objectData }) => (
|
|
||||||
<ObjectInfo
|
|
||||||
loading={loading}
|
|
||||||
isEditing={isEditing}
|
|
||||||
type='material'
|
|
||||||
objectData={objectData}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</ObjectForm>
|
|
||||||
</InfoCollapse>
|
|
||||||
</ActionHandler>
|
|
||||||
<InfoCollapse
|
|
||||||
title='Notes'
|
|
||||||
icon={<NoteIcon />}
|
|
||||||
active={collapseState.notes}
|
|
||||||
onToggle={(expanded) => updateCollapseState('notes', expanded)}
|
|
||||||
collapseKey='notes'
|
|
||||||
>
|
|
||||||
<Card>
|
|
||||||
<NotesPanel _id={materialId} type='material' />
|
|
||||||
</Card>
|
|
||||||
</InfoCollapse>
|
|
||||||
<InfoCollapse
|
|
||||||
title='Audit Logs'
|
|
||||||
icon={<AuditLogIcon />}
|
|
||||||
active={collapseState.auditLogs}
|
|
||||||
onToggle={(expanded) =>
|
|
||||||
updateCollapseState('auditLogs', expanded)
|
|
||||||
}
|
|
||||||
collapseKey='auditLogs'
|
|
||||||
>
|
|
||||||
{objectFormState.loading ? (
|
|
||||||
<InfoCollapsePlaceholder />
|
|
||||||
) : (
|
|
||||||
<ObjectTable
|
|
||||||
type='auditLog'
|
|
||||||
masterFilter={{ 'parent._id': materialId }}
|
|
||||||
visibleColumns={{ _id: false, 'parent._id': false }}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</InfoCollapse>
|
|
||||||
</Flex>
|
|
||||||
</ScrollBox>
|
|
||||||
</Flex>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default MaterialInfo
|
|
||||||
@ -61,11 +61,9 @@ const NewMaterial = ({ onOk }) => {
|
|||||||
loading={submitLoading}
|
loading={submitLoading}
|
||||||
formValid={formValid}
|
formValid={formValid}
|
||||||
title='New Material'
|
title='New Material'
|
||||||
onSubmit={async () => {
|
onSubmit={() => {
|
||||||
const result = await handleSubmit()
|
handleSubmit()
|
||||||
if (result) {
|
onOk()
|
||||||
onOk()
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -5,12 +5,10 @@ import ObjectTable from '../common/ObjectTable'
|
|||||||
import PlusIcon from '../../Icons/PlusIcon'
|
import PlusIcon from '../../Icons/PlusIcon'
|
||||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
import ReloadIcon from '../../Icons/ReloadIcon'
|
||||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
import useColumnVisibility from '../hooks/useColumnVisibility'
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
import GridIcon from '../../Icons/GridIcon'
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
import ListIcon from '../../Icons/ListIcon'
|
||||||
import useViewMode from '../hooks/useViewMode'
|
import useViewMode from '../hooks/useViewMode'
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
import ColumnViewButton from '../common/ColumnViewButton'
|
import ColumnViewButton from '../common/ColumnViewButton'
|
||||||
import ExportListButton from '../common/ExportListButton'
|
|
||||||
|
|
||||||
const NoteTypes = () => {
|
const NoteTypes = () => {
|
||||||
const [newNoteTypeOpen, setNewNoteTypeOpen] = useState(false)
|
const [newNoteTypeOpen, setNewNoteTypeOpen] = useState(false)
|
||||||
@ -21,9 +19,6 @@ const NoteTypes = () => {
|
|||||||
const [columnVisibility, setColumnVisibility] =
|
const [columnVisibility, setColumnVisibility] =
|
||||||
useColumnVisibility('noteType')
|
useColumnVisibility('noteType')
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('NoteTypes')
|
|
||||||
|
|
||||||
const actionItems = {
|
const actionItems = {
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -49,7 +44,7 @@ const NoteTypes = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
<Flex vertical={'true'} gap='large'>
|
||||||
<Flex justify={'space-between'}>
|
<Flex justify={'space-between'}>
|
||||||
<Space size='small'>
|
<Space size='small'>
|
||||||
<Dropdown menu={actionItems}>
|
<Dropdown menu={actionItems}>
|
||||||
@ -58,19 +53,16 @@ const NoteTypes = () => {
|
|||||||
<ColumnViewButton
|
<ColumnViewButton
|
||||||
type='noteType'
|
type='noteType'
|
||||||
loading={false}
|
loading={false}
|
||||||
visibleState={columnVisibility}
|
collapseState={columnVisibility}
|
||||||
updateVisibleState={setColumnVisibility}
|
updateCollapseState={setColumnVisibility}
|
||||||
/>
|
/>
|
||||||
<ExportListButton objectType='noteType' />
|
|
||||||
</Space>
|
</Space>
|
||||||
<Space>
|
<Space>
|
||||||
<FilterSidebarButton
|
<Button
|
||||||
active={showFilterSidebar}
|
icon={viewMode === 'cards' ? <ListIcon /> : <GridIcon />}
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
onClick={() =>
|
||||||
/>
|
setViewMode(viewMode === 'cards' ? 'list' : 'cards')
|
||||||
<ObjectTableViewButton
|
}
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -79,7 +71,6 @@ const NoteTypes = () => {
|
|||||||
visibleColumns={columnVisibility}
|
visibleColumns={columnVisibility}
|
||||||
type='noteType'
|
type='noteType'
|
||||||
cards={viewMode === 'cards'}
|
cards={viewMode === 'cards'}
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Modal
|
<Modal
|
||||||
|
|||||||
@ -19,7 +19,6 @@ const NewNote = ({ onOk, defaultValues = {} }) => {
|
|||||||
bordered={false}
|
bordered={false}
|
||||||
isEditing={true}
|
isEditing={true}
|
||||||
required={true}
|
required={true}
|
||||||
labelWidth='100px'
|
|
||||||
objectData={objectData}
|
objectData={objectData}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,21 +1,18 @@
|
|||||||
import { useRef, useState } from 'react'
|
import { useRef, useState } from 'react'
|
||||||
import { useLocation } from 'react-router-dom'
|
import { useLocation } from 'react-router-dom'
|
||||||
import { Space, Flex, Card } from 'antd'
|
import { Space, Flex, Card } from 'antd'
|
||||||
import { LoadingOutlined } from '@ant-design/icons'
|
|
||||||
import loglevel from 'loglevel'
|
import loglevel from 'loglevel'
|
||||||
import config from '../../../../config.js'
|
import config from '../../../../config'
|
||||||
import useCollapseState from '../../hooks/useCollapseState.jsx'
|
import useCollapseState from '../../hooks/useCollapseState'
|
||||||
import NotesPanel from '../../common/NotesPanel.jsx'
|
import NotesPanel from '../../common/NotesPanel'
|
||||||
import InfoCollapse from '../../common/InfoCollapse.jsx'
|
import InfoCollapse from '../../common/InfoCollapse'
|
||||||
import ObjectInfo from '../../common/ObjectInfo.jsx'
|
import ObjectInfo from '../../common/ObjectInfo'
|
||||||
import ObjectProperty from '../../common/ObjectProperty.jsx'
|
import ViewButton from '../../common/ViewButton'
|
||||||
import ViewButton from '../../common/ViewButton.jsx'
|
|
||||||
import InfoCircleIcon from '../../../Icons/InfoCircleIcon.jsx'
|
import InfoCircleIcon from '../../../Icons/InfoCircleIcon.jsx'
|
||||||
import TextIcon from '../../../Icons/TextIcon.jsx'
|
|
||||||
import NoteIcon from '../../../Icons/NoteIcon.jsx'
|
import NoteIcon from '../../../Icons/NoteIcon.jsx'
|
||||||
import AuditLogIcon from '../../../Icons/AuditLogIcon.jsx'
|
import AuditLogIcon from '../../../Icons/AuditLogIcon.jsx'
|
||||||
import ObjectForm from '../../common/ObjectForm.jsx'
|
import ObjectForm from '../../common/ObjectForm'
|
||||||
import EditButtons from '../../common/EditButtons.jsx'
|
import EditButtons from '../../common/EditButtons'
|
||||||
import LockIndicator from '../../common/LockIndicator.jsx'
|
import LockIndicator from '../../common/LockIndicator.jsx'
|
||||||
import ActionHandler from '../../common/ActionHandler.jsx'
|
import ActionHandler from '../../common/ActionHandler.jsx'
|
||||||
import ObjectActions from '../../common/ObjectActions.jsx'
|
import ObjectActions from '../../common/ObjectActions.jsx'
|
||||||
@ -24,7 +21,6 @@ import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
|
|||||||
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
|
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
|
||||||
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
|
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
|
||||||
import ScrollBox from '../../common/ScrollBox.jsx'
|
import ScrollBox from '../../common/ScrollBox.jsx'
|
||||||
import { getModelProperty } from '../../../../database/ObjectModels.js'
|
|
||||||
|
|
||||||
const log = loglevel.getLogger('NoteInfo')
|
const log = loglevel.getLogger('NoteInfo')
|
||||||
log.setLevel(config.logLevel)
|
log.setLevel(config.logLevel)
|
||||||
@ -36,7 +32,6 @@ const NoteInfo = () => {
|
|||||||
const noteId = new URLSearchParams(location.search).get('noteId')
|
const noteId = new URLSearchParams(location.search).get('noteId')
|
||||||
const [collapseState, updateCollapseState] = useCollapseState('NoteInfo', {
|
const [collapseState, updateCollapseState] = useCollapseState('NoteInfo', {
|
||||||
info: true,
|
info: true,
|
||||||
content: true,
|
|
||||||
notes: true,
|
notes: true,
|
||||||
auditLogs: true
|
auditLogs: true
|
||||||
})
|
})
|
||||||
@ -92,7 +87,6 @@ const NoteInfo = () => {
|
|||||||
disabled={objectFormState.loading}
|
disabled={objectFormState.loading}
|
||||||
items={[
|
items={[
|
||||||
{ key: 'info', label: 'Note Information' },
|
{ key: 'info', label: 'Note Information' },
|
||||||
{ key: 'content', label: 'Note Content' },
|
|
||||||
{ key: 'notes', label: 'Notes' },
|
{ key: 'notes', label: 'Notes' },
|
||||||
{ key: 'auditLogs', label: 'Audit Logs' }
|
{ key: 'auditLogs', label: 'Audit Logs' }
|
||||||
]}
|
]}
|
||||||
@ -138,58 +132,32 @@ const NoteInfo = () => {
|
|||||||
loading={objectFormState.loading}
|
loading={objectFormState.loading}
|
||||||
ref={actionHandlerRef}
|
ref={actionHandlerRef}
|
||||||
>
|
>
|
||||||
<ObjectForm
|
<InfoCollapse
|
||||||
id={noteId}
|
title='Note Information'
|
||||||
type='note'
|
icon={<InfoCircleIcon />}
|
||||||
style={{ height: '100%' }}
|
active={collapseState.info}
|
||||||
ref={objectFormRef}
|
onToggle={(expanded) => updateCollapseState('info', expanded)}
|
||||||
onStateChange={(state) => {
|
collapseKey='info'
|
||||||
setEditFormState((prev) => ({ ...prev, ...state }))
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{({ loading, isEditing, objectData }) => (
|
<ObjectForm
|
||||||
<Flex vertical gap={'large'}>
|
id={noteId}
|
||||||
<InfoCollapse
|
type='note'
|
||||||
title='Note Information'
|
style={{ height: '100%' }}
|
||||||
icon={<InfoCircleIcon />}
|
ref={objectFormRef}
|
||||||
active={collapseState.info}
|
onStateChange={(state) => {
|
||||||
onToggle={(expanded) =>
|
setEditFormState((prev) => ({ ...prev, ...state }))
|
||||||
updateCollapseState('info', expanded)
|
}}
|
||||||
}
|
>
|
||||||
collapseKey='info'
|
{({ loading, isEditing, objectData }) => (
|
||||||
>
|
<ObjectInfo
|
||||||
<ObjectInfo
|
loading={loading}
|
||||||
loading={loading}
|
isEditing={isEditing}
|
||||||
indicator={<LoadingOutlined />}
|
type='note'
|
||||||
isEditing={isEditing}
|
objectData={objectData}
|
||||||
type='note'
|
/>
|
||||||
objectData={objectData}
|
)}
|
||||||
visibleProperties={{ content: false }}
|
</ObjectForm>
|
||||||
/>
|
</InfoCollapse>
|
||||||
</InfoCollapse>
|
|
||||||
<InfoCollapse
|
|
||||||
title='Note Content'
|
|
||||||
icon={<TextIcon />}
|
|
||||||
active={collapseState.content}
|
|
||||||
onToggle={(expanded) =>
|
|
||||||
updateCollapseState('content', expanded)
|
|
||||||
}
|
|
||||||
collapseKey='content'
|
|
||||||
>
|
|
||||||
<Card>
|
|
||||||
<ObjectProperty
|
|
||||||
{...getModelProperty('note', 'content')}
|
|
||||||
isEditing={isEditing}
|
|
||||||
objectData={objectData}
|
|
||||||
loading={loading}
|
|
||||||
size='medium'
|
|
||||||
showCard={false}
|
|
||||||
/>
|
|
||||||
</Card>
|
|
||||||
</InfoCollapse>
|
|
||||||
</Flex>
|
|
||||||
)}
|
|
||||||
</ObjectForm>
|
|
||||||
</ActionHandler>
|
</ActionHandler>
|
||||||
<InfoCollapse
|
<InfoCollapse
|
||||||
title='Notes'
|
title='Notes'
|
||||||
|
|||||||
@ -1,110 +0,0 @@
|
|||||||
import { useState, useRef } from 'react'
|
|
||||||
|
|
||||||
import { Button, Flex, Space, Modal, Dropdown } from 'antd'
|
|
||||||
|
|
||||||
import NewPartSku from './PartSkus/NewPartSku'
|
|
||||||
import PlusIcon from '../../Icons/PlusIcon'
|
|
||||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
|
||||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
|
||||||
import ObjectTable from '../common/ObjectTable'
|
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
|
||||||
import useViewMode from '../hooks/useViewMode'
|
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
import ColumnViewButton from '../common/ColumnViewButton'
|
|
||||||
import ExportListButton from '../common/ExportListButton'
|
|
||||||
|
|
||||||
const PartSkus = () => {
|
|
||||||
const tableRef = useRef()
|
|
||||||
|
|
||||||
const [newPartSkuOpen, setNewPartSkuOpen] = useState(false)
|
|
||||||
|
|
||||||
const [viewMode, setViewMode] = useViewMode('partSkus')
|
|
||||||
|
|
||||||
const [columnVisibility, setColumnVisibility] = useColumnVisibility('partSku')
|
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('PartSkus')
|
|
||||||
|
|
||||||
const actionItems = {
|
|
||||||
items: [
|
|
||||||
{
|
|
||||||
label: 'New Part SKU',
|
|
||||||
key: 'newPartSku',
|
|
||||||
icon: <PlusIcon />
|
|
||||||
},
|
|
||||||
{ type: 'divider' },
|
|
||||||
{
|
|
||||||
label: 'Reload List',
|
|
||||||
key: 'reloadList',
|
|
||||||
icon: <ReloadIcon />
|
|
||||||
}
|
|
||||||
],
|
|
||||||
onClick: ({ key }) => {
|
|
||||||
if (key === 'reloadList') {
|
|
||||||
tableRef.current?.reload()
|
|
||||||
} else if (key === 'newPartSku') {
|
|
||||||
setNewPartSkuOpen(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
|
||||||
<Flex justify={'space-between'}>
|
|
||||||
<Space size='small'>
|
|
||||||
<Dropdown menu={actionItems}>
|
|
||||||
<Button>Actions</Button>
|
|
||||||
</Dropdown>
|
|
||||||
<ColumnViewButton
|
|
||||||
type='partSku'
|
|
||||||
loading={false}
|
|
||||||
visibleState={columnVisibility}
|
|
||||||
updateVisibleState={setColumnVisibility}
|
|
||||||
/>
|
|
||||||
<ExportListButton objectType='partSku' />
|
|
||||||
</Space>
|
|
||||||
<Space>
|
|
||||||
<FilterSidebarButton
|
|
||||||
active={showFilterSidebar}
|
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
|
||||||
/>
|
|
||||||
<ObjectTableViewButton
|
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
|
||||||
</Space>
|
|
||||||
</Flex>
|
|
||||||
|
|
||||||
<ObjectTable
|
|
||||||
ref={tableRef}
|
|
||||||
visibleColumns={columnVisibility}
|
|
||||||
type='partSku'
|
|
||||||
cards={viewMode === 'cards'}
|
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
|
||||||
</Flex>
|
|
||||||
<Modal
|
|
||||||
open={newPartSkuOpen}
|
|
||||||
styles={{ content: { paddingBottom: '24px' } }}
|
|
||||||
footer={null}
|
|
||||||
width={700}
|
|
||||||
onCancel={() => {
|
|
||||||
setNewPartSkuOpen(false)
|
|
||||||
}}
|
|
||||||
destroyOnHidden={true}
|
|
||||||
>
|
|
||||||
<NewPartSku
|
|
||||||
onOk={() => {
|
|
||||||
setNewPartSkuOpen(false)
|
|
||||||
tableRef.current?.reload()
|
|
||||||
}}
|
|
||||||
reset={newPartSkuOpen}
|
|
||||||
/>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default PartSkus
|
|
||||||
@ -1,129 +0,0 @@
|
|||||||
import PropTypes from 'prop-types'
|
|
||||||
import ObjectInfo from '../../common/ObjectInfo'
|
|
||||||
import NewObjectForm from '../../common/NewObjectForm'
|
|
||||||
import WizardView from '../../common/WizardView'
|
|
||||||
|
|
||||||
const NewPartSku = ({ onOk, reset, defaultValues }) => {
|
|
||||||
return (
|
|
||||||
<NewObjectForm
|
|
||||||
type='partSku'
|
|
||||||
reset={reset}
|
|
||||||
defaultValues={defaultValues}
|
|
||||||
>
|
|
||||||
{({ handleSubmit, submitLoading, objectData, formValid }) => {
|
|
||||||
const steps = [
|
|
||||||
{
|
|
||||||
title: 'Required',
|
|
||||||
key: 'required',
|
|
||||||
content: (
|
|
||||||
<ObjectInfo
|
|
||||||
type='partSku'
|
|
||||||
column={1}
|
|
||||||
labelWidth={70}
|
|
||||||
bordered={false}
|
|
||||||
isEditing={true}
|
|
||||||
required={true}
|
|
||||||
objectData={objectData}
|
|
||||||
visibleProperties={{
|
|
||||||
description: false,
|
|
||||||
priceMode: false,
|
|
||||||
cost: false,
|
|
||||||
costWithTax: false,
|
|
||||||
costTaxRate: false,
|
|
||||||
price: false,
|
|
||||||
priceWithTax: false,
|
|
||||||
margin: false,
|
|
||||||
amount: false,
|
|
||||||
priceTaxRate: false,
|
|
||||||
vendor: false
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Pricing',
|
|
||||||
key: 'pricing',
|
|
||||||
content: (
|
|
||||||
<ObjectInfo
|
|
||||||
type='partSku'
|
|
||||||
column={1}
|
|
||||||
labelWidth={100}
|
|
||||||
visibleProperties={{
|
|
||||||
_id: false,
|
|
||||||
createdAt: false,
|
|
||||||
updatedAt: false,
|
|
||||||
barcode: false,
|
|
||||||
part: false,
|
|
||||||
name: false,
|
|
||||||
description: false
|
|
||||||
}}
|
|
||||||
bordered={false}
|
|
||||||
isEditing={true}
|
|
||||||
objectData={objectData}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Optional',
|
|
||||||
key: 'optional',
|
|
||||||
content: (
|
|
||||||
<ObjectInfo
|
|
||||||
type='partSku'
|
|
||||||
column={1}
|
|
||||||
labelWidth={100}
|
|
||||||
visibleProperties={{
|
|
||||||
barcode: true,
|
|
||||||
description: true
|
|
||||||
}}
|
|
||||||
bordered={false}
|
|
||||||
isEditing={true}
|
|
||||||
objectData={objectData}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Summary',
|
|
||||||
key: 'summary',
|
|
||||||
content: (
|
|
||||||
<ObjectInfo
|
|
||||||
type='partSku'
|
|
||||||
column={1}
|
|
||||||
visibleProperties={{
|
|
||||||
createdAt: false,
|
|
||||||
updatedAt: false,
|
|
||||||
_id: false
|
|
||||||
}}
|
|
||||||
labelWidth={100}
|
|
||||||
bordered={false}
|
|
||||||
isEditing={false}
|
|
||||||
objectData={objectData}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
]
|
|
||||||
return (
|
|
||||||
<WizardView
|
|
||||||
steps={steps}
|
|
||||||
loading={submitLoading}
|
|
||||||
formValid={formValid}
|
|
||||||
title='New Part SKU'
|
|
||||||
onSubmit={async () => {
|
|
||||||
const result = await handleSubmit()
|
|
||||||
if (result) {
|
|
||||||
onOk()
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
</NewObjectForm>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
NewPartSku.propTypes = {
|
|
||||||
onOk: PropTypes.func.isRequired,
|
|
||||||
reset: PropTypes.bool,
|
|
||||||
defaultValues: PropTypes.object
|
|
||||||
}
|
|
||||||
|
|
||||||
export default NewPartSku
|
|
||||||
@ -1,194 +0,0 @@
|
|||||||
import { useRef, useState } from 'react'
|
|
||||||
import { useLocation } from 'react-router-dom'
|
|
||||||
import { Space, Flex, Card } from 'antd'
|
|
||||||
import useCollapseState from '../../hooks/useCollapseState'
|
|
||||||
import NotesPanel from '../../common/NotesPanel'
|
|
||||||
import InfoCollapse from '../../common/InfoCollapse'
|
|
||||||
import ObjectInfo from '../../common/ObjectInfo'
|
|
||||||
import ViewButton from '../../common/ViewButton'
|
|
||||||
import ObjectForm from '../../common/ObjectForm'
|
|
||||||
import EditButtons from '../../common/EditButtons'
|
|
||||||
import LockIndicator from '../../common/LockIndicator.jsx'
|
|
||||||
import InfoCircleIcon from '../../../Icons/InfoCircleIcon.jsx'
|
|
||||||
import NoteIcon from '../../../Icons/NoteIcon.jsx'
|
|
||||||
import AuditLogIcon from '../../../Icons/AuditLogIcon.jsx'
|
|
||||||
import ActionHandler from '../../common/ActionHandler.jsx'
|
|
||||||
import ObjectActions from '../../common/ObjectActions.jsx'
|
|
||||||
import ObjectTable from '../../common/ObjectTable.jsx'
|
|
||||||
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
|
|
||||||
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
|
|
||||||
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
|
|
||||||
import ScrollBox from '../../common/ScrollBox.jsx'
|
|
||||||
|
|
||||||
const PartSkuInfo = () => {
|
|
||||||
const location = useLocation()
|
|
||||||
const objectFormRef = useRef(null)
|
|
||||||
const actionHandlerRef = useRef(null)
|
|
||||||
const partSkuId = new URLSearchParams(location.search).get('partSkuId')
|
|
||||||
const [collapseState, updateCollapseState] = useCollapseState('PartSkuInfo', {
|
|
||||||
info: true,
|
|
||||||
notes: true,
|
|
||||||
auditLogs: true
|
|
||||||
})
|
|
||||||
const [objectFormState, setEditFormState] = useState({
|
|
||||||
isEditing: false,
|
|
||||||
editLoading: false,
|
|
||||||
formValid: false,
|
|
||||||
lock: null,
|
|
||||||
loading: false,
|
|
||||||
objectData: {}
|
|
||||||
})
|
|
||||||
|
|
||||||
const actions = {
|
|
||||||
reload: () => {
|
|
||||||
objectFormRef?.current?.fetchObject?.()
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
edit: () => {
|
|
||||||
objectFormRef?.current?.startEditing?.()
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
cancelEdit: () => {
|
|
||||||
objectFormRef?.current?.cancelEditing?.()
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
finishEdit: () => {
|
|
||||||
objectFormRef?.current?.handleUpdate?.()
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
delete: () => {
|
|
||||||
objectFormRef?.current?.handleDelete?.()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Flex
|
|
||||||
gap='large'
|
|
||||||
vertical='true'
|
|
||||||
style={{ maxHeight: '100%', minHeight: 0 }}
|
|
||||||
>
|
|
||||||
<Flex justify={'space-between'}>
|
|
||||||
<Space size='middle'>
|
|
||||||
<Space size='small'>
|
|
||||||
<ObjectActions
|
|
||||||
type='partSku'
|
|
||||||
id={partSkuId}
|
|
||||||
disabled={objectFormState.loading}
|
|
||||||
objectData={objectFormState.objectData}
|
|
||||||
/>
|
|
||||||
<ViewButton
|
|
||||||
disabled={objectFormState.loading}
|
|
||||||
items={[
|
|
||||||
{ key: 'info', label: 'Part SKU Information' },
|
|
||||||
{ key: 'notes', label: 'Notes' },
|
|
||||||
{ key: 'auditLogs', label: 'Audit Logs' }
|
|
||||||
]}
|
|
||||||
visibleState={collapseState}
|
|
||||||
updateVisibleState={updateCollapseState}
|
|
||||||
/>
|
|
||||||
<UserNotifierToggle
|
|
||||||
type='partSku'
|
|
||||||
objectData={objectFormState.objectData}
|
|
||||||
disabled={objectFormState.loading}
|
|
||||||
/>
|
|
||||||
<DocumentPrintButton
|
|
||||||
type='partSku'
|
|
||||||
objectData={objectFormState.objectData}
|
|
||||||
disabled={objectFormState.loading}
|
|
||||||
/>
|
|
||||||
</Space>
|
|
||||||
<LockIndicator lock={objectFormState.lock} />
|
|
||||||
</Space>
|
|
||||||
<Space>
|
|
||||||
<EditButtons
|
|
||||||
isEditing={objectFormState.isEditing}
|
|
||||||
handleUpdate={() => {
|
|
||||||
actionHandlerRef.current.callAction('finishEdit')
|
|
||||||
}}
|
|
||||||
cancelEditing={() => {
|
|
||||||
actionHandlerRef.current.callAction('cancelEdit')
|
|
||||||
}}
|
|
||||||
startEditing={() => {
|
|
||||||
actionHandlerRef.current.callAction('edit')
|
|
||||||
}}
|
|
||||||
editLoading={objectFormState.editLoading}
|
|
||||||
formValid={objectFormState.formValid}
|
|
||||||
disabled={objectFormState.lock?.locked || objectFormState.loading}
|
|
||||||
loading={objectFormState.editLoading}
|
|
||||||
/>
|
|
||||||
</Space>
|
|
||||||
</Flex>
|
|
||||||
<ScrollBox>
|
|
||||||
<Flex vertical gap={'large'}>
|
|
||||||
<ActionHandler
|
|
||||||
actions={actions}
|
|
||||||
loading={objectFormState.loading}
|
|
||||||
ref={actionHandlerRef}
|
|
||||||
>
|
|
||||||
<InfoCollapse
|
|
||||||
title='Part SKU Information'
|
|
||||||
icon={<InfoCircleIcon />}
|
|
||||||
active={collapseState.info}
|
|
||||||
onToggle={(expanded) => updateCollapseState('info', expanded)}
|
|
||||||
collapseKey='info'
|
|
||||||
>
|
|
||||||
<ObjectForm
|
|
||||||
id={partSkuId}
|
|
||||||
type='partSku'
|
|
||||||
style={{ height: '100%' }}
|
|
||||||
ref={objectFormRef}
|
|
||||||
onStateChange={(state) => {
|
|
||||||
setEditFormState((prev) => ({ ...prev, ...state }))
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{({ loading, isEditing, objectData }) => (
|
|
||||||
<ObjectInfo
|
|
||||||
loading={loading}
|
|
||||||
isEditing={isEditing}
|
|
||||||
type='partSku'
|
|
||||||
objectData={objectData}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</ObjectForm>
|
|
||||||
</InfoCollapse>
|
|
||||||
</ActionHandler>
|
|
||||||
<InfoCollapse
|
|
||||||
title='Notes'
|
|
||||||
icon={<NoteIcon />}
|
|
||||||
active={collapseState.notes}
|
|
||||||
onToggle={(expanded) => updateCollapseState('notes', expanded)}
|
|
||||||
collapseKey='notes'
|
|
||||||
>
|
|
||||||
<Card>
|
|
||||||
<NotesPanel _id={partSkuId} type='partSku' />
|
|
||||||
</Card>
|
|
||||||
</InfoCollapse>
|
|
||||||
<InfoCollapse
|
|
||||||
title='Audit Logs'
|
|
||||||
icon={<AuditLogIcon />}
|
|
||||||
active={collapseState.auditLogs}
|
|
||||||
onToggle={(expanded) =>
|
|
||||||
updateCollapseState('auditLogs', expanded)
|
|
||||||
}
|
|
||||||
collapseKey='auditLogs'
|
|
||||||
>
|
|
||||||
{objectFormState.loading ? (
|
|
||||||
<InfoCollapsePlaceholder />
|
|
||||||
) : (
|
|
||||||
<ObjectTable
|
|
||||||
type='auditLog'
|
|
||||||
masterFilter={{ 'parent._id': partSkuId }}
|
|
||||||
visibleColumns={{ _id: false, 'parent._id': false }}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</InfoCollapse>
|
|
||||||
</Flex>
|
|
||||||
</ScrollBox>
|
|
||||||
</Flex>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default PartSkuInfo
|
|
||||||
@ -11,13 +11,11 @@ import ReloadIcon from '../../Icons/ReloadIcon'
|
|||||||
|
|
||||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
import useColumnVisibility from '../hooks/useColumnVisibility'
|
||||||
|
|
||||||
|
import GridIcon from '../../Icons/GridIcon'
|
||||||
|
import ListIcon from '../../Icons/ListIcon'
|
||||||
import useViewMode from '../hooks/useViewMode'
|
import useViewMode from '../hooks/useViewMode'
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
|
|
||||||
import ColumnViewButton from '../common/ColumnViewButton'
|
import ColumnViewButton from '../common/ColumnViewButton'
|
||||||
import ExportListButton from '../common/ExportListButton'
|
|
||||||
|
|
||||||
const Parts = (filter) => {
|
const Parts = (filter) => {
|
||||||
const [newPartOpen, setNewPartOpen] = useState(false)
|
const [newPartOpen, setNewPartOpen] = useState(false)
|
||||||
@ -25,9 +23,6 @@ const Parts = (filter) => {
|
|||||||
const [viewMode, setViewMode] = useViewMode('part')
|
const [viewMode, setViewMode] = useViewMode('part')
|
||||||
const [columnVisibility, setColumnVisibility] = useColumnVisibility('part')
|
const [columnVisibility, setColumnVisibility] = useColumnVisibility('part')
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('Parts')
|
|
||||||
|
|
||||||
const actionItems = {
|
const actionItems = {
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -53,7 +48,7 @@ const Parts = (filter) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
<Flex vertical={'true'} gap='large'>
|
||||||
<Flex justify={'space-between'}>
|
<Flex justify={'space-between'}>
|
||||||
<Space size='small'>
|
<Space size='small'>
|
||||||
<Dropdown menu={actionItems}>
|
<Dropdown menu={actionItems}>
|
||||||
@ -62,19 +57,16 @@ const Parts = (filter) => {
|
|||||||
<ColumnViewButton
|
<ColumnViewButton
|
||||||
type='part'
|
type='part'
|
||||||
loading={false}
|
loading={false}
|
||||||
visibleState={columnVisibility}
|
collapseState={columnVisibility}
|
||||||
updateVisibleState={setColumnVisibility}
|
updateCollapseState={setColumnVisibility}
|
||||||
/>
|
/>
|
||||||
<ExportListButton objectType='part' />
|
|
||||||
</Space>
|
</Space>
|
||||||
<Space>
|
<Space>
|
||||||
<FilterSidebarButton
|
<Button
|
||||||
active={showFilterSidebar}
|
icon={viewMode === 'cards' ? <ListIcon /> : <GridIcon />}
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
onClick={() =>
|
||||||
/>
|
setViewMode(viewMode === 'cards' ? 'list' : 'cards')
|
||||||
<ObjectTableViewButton
|
}
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -84,7 +76,6 @@ const Parts = (filter) => {
|
|||||||
type='part'
|
type='part'
|
||||||
cards={viewMode === 'cards'}
|
cards={viewMode === 'cards'}
|
||||||
filter={filter}
|
filter={filter}
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Modal
|
<Modal
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { useRef, useState } from 'react'
|
import { useRef, useState } from 'react'
|
||||||
import { useLocation } from 'react-router-dom'
|
import { useLocation } from 'react-router-dom'
|
||||||
import { Space, Flex, Card, Modal } from 'antd'
|
import { Space, Flex, Card } from 'antd'
|
||||||
import useCollapseState from '../../hooks/useCollapseState'
|
import useCollapseState from '../../hooks/useCollapseState'
|
||||||
import NotesPanel from '../../common/NotesPanel'
|
import NotesPanel from '../../common/NotesPanel'
|
||||||
import InfoCollapse from '../../common/InfoCollapse'
|
import InfoCollapse from '../../common/InfoCollapse'
|
||||||
@ -19,19 +19,15 @@ import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
|
|||||||
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
|
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
|
||||||
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
|
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
|
||||||
import ScrollBox from '../../common/ScrollBox.jsx'
|
import ScrollBox from '../../common/ScrollBox.jsx'
|
||||||
import PartSkuIcon from '../../../Icons/PartSkuIcon.jsx'
|
|
||||||
import NewPartSku from '../PartSkus/NewPartSku'
|
|
||||||
|
|
||||||
const PartInfo = () => {
|
const PartInfo = () => {
|
||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
const objectFormRef = useRef(null)
|
const objectFormRef = useRef(null)
|
||||||
const actionHandlerRef = useRef(null)
|
const actionHandlerRef = useRef(null)
|
||||||
const partId = new URLSearchParams(location.search).get('partId')
|
const partId = new URLSearchParams(location.search).get('partId')
|
||||||
const [newPartSkuOpen, setNewPartSkuOpen] = useState(false)
|
|
||||||
const partSkusTableRef = useRef()
|
|
||||||
const [collapseState, updateCollapseState] = useCollapseState('PartInfo', {
|
const [collapseState, updateCollapseState] = useCollapseState('PartInfo', {
|
||||||
info: true,
|
info: true,
|
||||||
partSkus: true,
|
parts: true,
|
||||||
notes: true,
|
notes: true,
|
||||||
auditLogs: true
|
auditLogs: true
|
||||||
})
|
})
|
||||||
@ -49,10 +45,6 @@ const PartInfo = () => {
|
|||||||
objectFormRef?.current?.fetchObject?.()
|
objectFormRef?.current?.fetchObject?.()
|
||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
newPartSku: () => {
|
|
||||||
setNewPartSkuOpen(true)
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
edit: () => {
|
edit: () => {
|
||||||
objectFormRef?.current?.startEditing?.()
|
objectFormRef?.current?.startEditing?.()
|
||||||
return false
|
return false
|
||||||
@ -87,7 +79,6 @@ const PartInfo = () => {
|
|||||||
disabled={objectFormState.loading}
|
disabled={objectFormState.loading}
|
||||||
items={[
|
items={[
|
||||||
{ key: 'info', label: 'Part Information' },
|
{ key: 'info', label: 'Part Information' },
|
||||||
{ key: 'partSkus', label: 'Part SKUs' },
|
|
||||||
{ key: 'notes', label: 'Notes' },
|
{ key: 'notes', label: 'Notes' },
|
||||||
{ key: 'auditLogs', label: 'Audit Logs' }
|
{ key: 'auditLogs', label: 'Audit Logs' }
|
||||||
]}
|
]}
|
||||||
@ -133,74 +124,33 @@ const PartInfo = () => {
|
|||||||
loading={objectFormState.loading}
|
loading={objectFormState.loading}
|
||||||
ref={actionHandlerRef}
|
ref={actionHandlerRef}
|
||||||
>
|
>
|
||||||
<ObjectForm
|
<InfoCollapse
|
||||||
id={partId}
|
title='Part Information'
|
||||||
type='part'
|
icon={<InfoCircleIcon />}
|
||||||
style={{ height: '100%' }}
|
active={collapseState.info}
|
||||||
ref={objectFormRef}
|
onToggle={(expanded) => updateCollapseState('info', expanded)}
|
||||||
onStateChange={(state) => {
|
collapseKey='info'
|
||||||
setEditFormState((prev) => ({ ...prev, ...state }))
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{({ loading, isEditing, objectData }) => (
|
<ObjectForm
|
||||||
<InfoCollapse
|
id={partId}
|
||||||
title='Part Information'
|
type='part'
|
||||||
icon={<InfoCircleIcon />}
|
style={{ height: '100%' }}
|
||||||
active={collapseState.info}
|
ref={objectFormRef}
|
||||||
onToggle={(expanded) =>
|
onStateChange={(state) => {
|
||||||
updateCollapseState('info', expanded)
|
setEditFormState((prev) => ({ ...prev, ...state }))
|
||||||
}
|
}}
|
||||||
collapseKey='info'
|
>
|
||||||
>
|
{({ loading, isEditing, objectData }) => (
|
||||||
<ObjectInfo
|
<ObjectInfo
|
||||||
loading={loading}
|
loading={loading}
|
||||||
isEditing={isEditing}
|
isEditing={isEditing}
|
||||||
type='part'
|
type='part'
|
||||||
objectData={objectData}
|
objectData={objectData}
|
||||||
/>
|
/>
|
||||||
</InfoCollapse>
|
)}
|
||||||
)}
|
</ObjectForm>
|
||||||
</ObjectForm>
|
|
||||||
<InfoCollapse
|
|
||||||
title='Part SKUs'
|
|
||||||
icon={<PartSkuIcon />}
|
|
||||||
active={collapseState.partSkus}
|
|
||||||
onToggle={(expanded) =>
|
|
||||||
updateCollapseState('partSkus', expanded)
|
|
||||||
}
|
|
||||||
collapseKey='partSkus'
|
|
||||||
>
|
|
||||||
{objectFormState.loading ? (
|
|
||||||
<InfoCollapsePlaceholder />
|
|
||||||
) : (
|
|
||||||
<ObjectTable
|
|
||||||
ref={partSkusTableRef}
|
|
||||||
type='partSku'
|
|
||||||
masterFilter={{ part: partId }}
|
|
||||||
visibleColumns={{ part: false }}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</InfoCollapse>
|
</InfoCollapse>
|
||||||
</ActionHandler>
|
</ActionHandler>
|
||||||
<Modal
|
|
||||||
open={newPartSkuOpen}
|
|
||||||
styles={{ content: { paddingBottom: '24px' } }}
|
|
||||||
footer={null}
|
|
||||||
width={700}
|
|
||||||
onCancel={() => setNewPartSkuOpen(false)}
|
|
||||||
destroyOnClose
|
|
||||||
>
|
|
||||||
<NewPartSku
|
|
||||||
onOk={() => {
|
|
||||||
setNewPartSkuOpen(false)
|
|
||||||
partSkusTableRef.current?.reload?.()
|
|
||||||
}}
|
|
||||||
reset={newPartSkuOpen}
|
|
||||||
defaultValues={{
|
|
||||||
part: partId ? { _id: partId } : undefined
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Modal>
|
|
||||||
<InfoCollapse
|
<InfoCollapse
|
||||||
title='Notes'
|
title='Notes'
|
||||||
icon={<NoteIcon />}
|
icon={<NoteIcon />}
|
||||||
|
|||||||
@ -1,111 +0,0 @@
|
|||||||
import { useState, useRef } from 'react'
|
|
||||||
|
|
||||||
import { Button, Flex, Space, Modal, Dropdown } from 'antd'
|
|
||||||
|
|
||||||
import NewProductSku from './ProductSkus/NewProductSku'
|
|
||||||
import PlusIcon from '../../Icons/PlusIcon'
|
|
||||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
|
||||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
|
||||||
import ObjectTable from '../common/ObjectTable'
|
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
|
||||||
import useViewMode from '../hooks/useViewMode'
|
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
import ColumnViewButton from '../common/ColumnViewButton'
|
|
||||||
import ExportListButton from '../common/ExportListButton'
|
|
||||||
|
|
||||||
const ProductSkus = () => {
|
|
||||||
const tableRef = useRef()
|
|
||||||
|
|
||||||
const [newProductSkuOpen, setNewProductSkuOpen] = useState(false)
|
|
||||||
|
|
||||||
const [viewMode, setViewMode] = useViewMode('productSkus')
|
|
||||||
|
|
||||||
const [columnVisibility, setColumnVisibility] =
|
|
||||||
useColumnVisibility('productSku')
|
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('ProductSkus')
|
|
||||||
|
|
||||||
const actionItems = {
|
|
||||||
items: [
|
|
||||||
{
|
|
||||||
label: 'New Product SKU',
|
|
||||||
key: 'newProductSku',
|
|
||||||
icon: <PlusIcon />
|
|
||||||
},
|
|
||||||
{ type: 'divider' },
|
|
||||||
{
|
|
||||||
label: 'Reload List',
|
|
||||||
key: 'reloadList',
|
|
||||||
icon: <ReloadIcon />
|
|
||||||
}
|
|
||||||
],
|
|
||||||
onClick: ({ key }) => {
|
|
||||||
if (key === 'reloadList') {
|
|
||||||
tableRef.current?.reload()
|
|
||||||
} else if (key === 'newProductSku') {
|
|
||||||
setNewProductSkuOpen(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
|
||||||
<Flex justify={'space-between'}>
|
|
||||||
<Space size='small'>
|
|
||||||
<Dropdown menu={actionItems}>
|
|
||||||
<Button>Actions</Button>
|
|
||||||
</Dropdown>
|
|
||||||
<ColumnViewButton
|
|
||||||
type='productSku'
|
|
||||||
loading={false}
|
|
||||||
visibleState={columnVisibility}
|
|
||||||
updateVisibleState={setColumnVisibility}
|
|
||||||
/>
|
|
||||||
<ExportListButton objectType='productSku' />
|
|
||||||
</Space>
|
|
||||||
<Space>
|
|
||||||
<FilterSidebarButton
|
|
||||||
active={showFilterSidebar}
|
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
|
||||||
/>
|
|
||||||
<ObjectTableViewButton
|
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
|
||||||
</Space>
|
|
||||||
</Flex>
|
|
||||||
|
|
||||||
<ObjectTable
|
|
||||||
ref={tableRef}
|
|
||||||
visibleColumns={columnVisibility}
|
|
||||||
type='productSku'
|
|
||||||
cards={viewMode === 'cards'}
|
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
|
||||||
</Flex>
|
|
||||||
<Modal
|
|
||||||
open={newProductSkuOpen}
|
|
||||||
styles={{ content: { paddingBottom: '24px' } }}
|
|
||||||
footer={null}
|
|
||||||
width={700}
|
|
||||||
onCancel={() => {
|
|
||||||
setNewProductSkuOpen(false)
|
|
||||||
}}
|
|
||||||
destroyOnHidden={true}
|
|
||||||
>
|
|
||||||
<NewProductSku
|
|
||||||
onOk={() => {
|
|
||||||
setNewProductSkuOpen(false)
|
|
||||||
tableRef.current?.reload()
|
|
||||||
}}
|
|
||||||
reset={newProductSkuOpen}
|
|
||||||
/>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ProductSkus
|
|
||||||
@ -1,164 +0,0 @@
|
|||||||
import PropTypes from 'prop-types'
|
|
||||||
import ObjectInfo from '../../common/ObjectInfo'
|
|
||||||
import NewObjectForm from '../../common/NewObjectForm'
|
|
||||||
import WizardView from '../../common/WizardView'
|
|
||||||
|
|
||||||
const NewProductSku = ({ onOk, reset, defaultValues }) => {
|
|
||||||
return (
|
|
||||||
<NewObjectForm
|
|
||||||
type='productSku'
|
|
||||||
reset={reset}
|
|
||||||
defaultValues={defaultValues}
|
|
||||||
>
|
|
||||||
{({ handleSubmit, submitLoading, objectData, formValid }) => {
|
|
||||||
const steps = [
|
|
||||||
{
|
|
||||||
title: 'Required',
|
|
||||||
key: 'required',
|
|
||||||
content: (
|
|
||||||
<ObjectInfo
|
|
||||||
type='productSku'
|
|
||||||
column={1}
|
|
||||||
labelWidth={70}
|
|
||||||
bordered={false}
|
|
||||||
isEditing={true}
|
|
||||||
required={true}
|
|
||||||
objectData={objectData}
|
|
||||||
visibleProperties={{
|
|
||||||
description: false,
|
|
||||||
priceMode: false,
|
|
||||||
cost: false,
|
|
||||||
costWithTax: false,
|
|
||||||
costTaxRate: false,
|
|
||||||
price: false,
|
|
||||||
priceWithTax: false,
|
|
||||||
margin: false,
|
|
||||||
amount: false,
|
|
||||||
priceTaxRate: false,
|
|
||||||
vendor: false,
|
|
||||||
parts: false
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Pricing',
|
|
||||||
key: 'pricing',
|
|
||||||
content: (
|
|
||||||
<ObjectInfo
|
|
||||||
type='productSku'
|
|
||||||
column={1}
|
|
||||||
labelWidth={100}
|
|
||||||
visibleProperties={{
|
|
||||||
_id: false,
|
|
||||||
createdAt: false,
|
|
||||||
updatedAt: false,
|
|
||||||
barcode: false,
|
|
||||||
product: false,
|
|
||||||
name: false,
|
|
||||||
description: false,
|
|
||||||
parts: false
|
|
||||||
}}
|
|
||||||
bordered={false}
|
|
||||||
isEditing={true}
|
|
||||||
objectData={objectData}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Parts',
|
|
||||||
key: 'parts',
|
|
||||||
content: (
|
|
||||||
<ObjectInfo
|
|
||||||
type='productSku'
|
|
||||||
column={1}
|
|
||||||
labelWidth={100}
|
|
||||||
visibleProperties={{
|
|
||||||
_id: false,
|
|
||||||
createdAt: false,
|
|
||||||
updatedAt: false,
|
|
||||||
barcode: false,
|
|
||||||
product: false,
|
|
||||||
name: false,
|
|
||||||
description: false,
|
|
||||||
priceMode: false,
|
|
||||||
cost: false,
|
|
||||||
costWithTax: false,
|
|
||||||
costTaxRate: false,
|
|
||||||
price: false,
|
|
||||||
priceWithTax: false,
|
|
||||||
margin: false,
|
|
||||||
amount: false,
|
|
||||||
priceTaxRate: false,
|
|
||||||
vendor: false
|
|
||||||
}}
|
|
||||||
bordered={false}
|
|
||||||
isEditing={true}
|
|
||||||
objectData={objectData}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Optional',
|
|
||||||
key: 'optional',
|
|
||||||
content: (
|
|
||||||
<ObjectInfo
|
|
||||||
type='productSku'
|
|
||||||
column={1}
|
|
||||||
labelWidth={100}
|
|
||||||
visibleProperties={{
|
|
||||||
barcode: true,
|
|
||||||
description: true
|
|
||||||
}}
|
|
||||||
bordered={false}
|
|
||||||
isEditing={true}
|
|
||||||
objectData={objectData}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Summary',
|
|
||||||
key: 'summary',
|
|
||||||
content: (
|
|
||||||
<ObjectInfo
|
|
||||||
type='productSku'
|
|
||||||
column={1}
|
|
||||||
visibleProperties={{
|
|
||||||
createdAt: false,
|
|
||||||
updatedAt: false,
|
|
||||||
_id: false
|
|
||||||
}}
|
|
||||||
labelWidth={100}
|
|
||||||
bordered={false}
|
|
||||||
isEditing={false}
|
|
||||||
objectData={objectData}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
]
|
|
||||||
return (
|
|
||||||
<WizardView
|
|
||||||
steps={steps}
|
|
||||||
loading={submitLoading}
|
|
||||||
formValid={formValid}
|
|
||||||
title='New Product SKU'
|
|
||||||
onSubmit={async () => {
|
|
||||||
const result = await handleSubmit()
|
|
||||||
if (result) {
|
|
||||||
onOk()
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
</NewObjectForm>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
NewProductSku.propTypes = {
|
|
||||||
onOk: PropTypes.func.isRequired,
|
|
||||||
reset: PropTypes.bool,
|
|
||||||
defaultValues: PropTypes.object
|
|
||||||
}
|
|
||||||
|
|
||||||
export default NewProductSku
|
|
||||||
@ -1,222 +0,0 @@
|
|||||||
import { useRef, useState } from 'react'
|
|
||||||
import { useLocation } from 'react-router-dom'
|
|
||||||
import { Space, Flex, Card } from 'antd'
|
|
||||||
import useCollapseState from '../../hooks/useCollapseState'
|
|
||||||
import NotesPanel from '../../common/NotesPanel'
|
|
||||||
import InfoCollapse from '../../common/InfoCollapse'
|
|
||||||
import ObjectInfo from '../../common/ObjectInfo'
|
|
||||||
import ViewButton from '../../common/ViewButton'
|
|
||||||
import ObjectForm from '../../common/ObjectForm'
|
|
||||||
import EditButtons from '../../common/EditButtons'
|
|
||||||
import LockIndicator from '../../common/LockIndicator.jsx'
|
|
||||||
import InfoCircleIcon from '../../../Icons/InfoCircleIcon.jsx'
|
|
||||||
import NoteIcon from '../../../Icons/NoteIcon.jsx'
|
|
||||||
import AuditLogIcon from '../../../Icons/AuditLogIcon.jsx'
|
|
||||||
import ActionHandler from '../../common/ActionHandler.jsx'
|
|
||||||
import ObjectActions from '../../common/ObjectActions.jsx'
|
|
||||||
import ObjectTable from '../../common/ObjectTable.jsx'
|
|
||||||
import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
|
|
||||||
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
|
|
||||||
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
|
|
||||||
import ScrollBox from '../../common/ScrollBox.jsx'
|
|
||||||
import ObjectProperty from '../../common/ObjectProperty.jsx'
|
|
||||||
import { getModelProperty } from '../../../../database/ObjectModels.js'
|
|
||||||
import PartIcon from '../../../Icons/PartIcon.jsx'
|
|
||||||
|
|
||||||
const ProductSkuInfo = () => {
|
|
||||||
const location = useLocation()
|
|
||||||
const objectFormRef = useRef(null)
|
|
||||||
const actionHandlerRef = useRef(null)
|
|
||||||
const productSkuId = new URLSearchParams(location.search).get('productSkuId')
|
|
||||||
const [collapseState, updateCollapseState] = useCollapseState(
|
|
||||||
'ProductSkuInfo',
|
|
||||||
{
|
|
||||||
info: true,
|
|
||||||
parts: true,
|
|
||||||
notes: true,
|
|
||||||
auditLogs: true
|
|
||||||
}
|
|
||||||
)
|
|
||||||
const [objectFormState, setEditFormState] = useState({
|
|
||||||
isEditing: false,
|
|
||||||
editLoading: false,
|
|
||||||
formValid: false,
|
|
||||||
lock: null,
|
|
||||||
loading: false,
|
|
||||||
objectData: {}
|
|
||||||
})
|
|
||||||
|
|
||||||
const actions = {
|
|
||||||
reload: () => {
|
|
||||||
objectFormRef?.current?.fetchObject?.()
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
edit: () => {
|
|
||||||
objectFormRef?.current?.startEditing?.()
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
cancelEdit: () => {
|
|
||||||
objectFormRef?.current?.cancelEditing?.()
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
finishEdit: () => {
|
|
||||||
objectFormRef?.current?.handleUpdate?.()
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
delete: () => {
|
|
||||||
objectFormRef?.current?.handleDelete?.()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Flex
|
|
||||||
gap='large'
|
|
||||||
vertical='true'
|
|
||||||
style={{ maxHeight: '100%', minHeight: 0 }}
|
|
||||||
>
|
|
||||||
<Flex justify={'space-between'}>
|
|
||||||
<Space size='middle'>
|
|
||||||
<Space size='small'>
|
|
||||||
<ObjectActions
|
|
||||||
type='productSku'
|
|
||||||
id={productSkuId}
|
|
||||||
disabled={objectFormState.loading}
|
|
||||||
objectData={objectFormState.objectData}
|
|
||||||
/>
|
|
||||||
<ViewButton
|
|
||||||
disabled={objectFormState.loading}
|
|
||||||
items={[
|
|
||||||
{ key: 'info', label: 'Product SKU Information' },
|
|
||||||
{ key: 'parts', label: 'SKU Parts' },
|
|
||||||
{ key: 'notes', label: 'Notes' },
|
|
||||||
{ key: 'auditLogs', label: 'Audit Logs' }
|
|
||||||
]}
|
|
||||||
visibleState={collapseState}
|
|
||||||
updateVisibleState={updateCollapseState}
|
|
||||||
/>
|
|
||||||
<UserNotifierToggle
|
|
||||||
type='productSku'
|
|
||||||
objectData={objectFormState.objectData}
|
|
||||||
disabled={objectFormState.loading}
|
|
||||||
/>
|
|
||||||
<DocumentPrintButton
|
|
||||||
type='productSku'
|
|
||||||
objectData={objectFormState.objectData}
|
|
||||||
disabled={objectFormState.loading}
|
|
||||||
/>
|
|
||||||
</Space>
|
|
||||||
<LockIndicator lock={objectFormState.lock} />
|
|
||||||
</Space>
|
|
||||||
<Space>
|
|
||||||
<EditButtons
|
|
||||||
isEditing={objectFormState.isEditing}
|
|
||||||
handleUpdate={() => {
|
|
||||||
actionHandlerRef.current.callAction('finishEdit')
|
|
||||||
}}
|
|
||||||
cancelEditing={() => {
|
|
||||||
actionHandlerRef.current.callAction('cancelEdit')
|
|
||||||
}}
|
|
||||||
startEditing={() => {
|
|
||||||
actionHandlerRef.current.callAction('edit')
|
|
||||||
}}
|
|
||||||
editLoading={objectFormState.editLoading}
|
|
||||||
formValid={objectFormState.formValid}
|
|
||||||
disabled={objectFormState.lock?.locked || objectFormState.loading}
|
|
||||||
loading={objectFormState.editLoading}
|
|
||||||
/>
|
|
||||||
</Space>
|
|
||||||
</Flex>
|
|
||||||
<ScrollBox>
|
|
||||||
<Flex vertical gap={'large'}>
|
|
||||||
<ActionHandler
|
|
||||||
actions={actions}
|
|
||||||
loading={objectFormState.loading}
|
|
||||||
ref={actionHandlerRef}
|
|
||||||
>
|
|
||||||
<InfoCollapse
|
|
||||||
title='Product SKU Information'
|
|
||||||
icon={<InfoCircleIcon />}
|
|
||||||
active={collapseState.info}
|
|
||||||
onToggle={(expanded) => updateCollapseState('info', expanded)}
|
|
||||||
collapseKey='info'
|
|
||||||
>
|
|
||||||
<ObjectForm
|
|
||||||
id={productSkuId}
|
|
||||||
type='productSku'
|
|
||||||
style={{ height: '100%' }}
|
|
||||||
ref={objectFormRef}
|
|
||||||
onStateChange={(state) => {
|
|
||||||
setEditFormState((prev) => ({ ...prev, ...state }))
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{({ loading, isEditing, objectData }) => (
|
|
||||||
<>
|
|
||||||
<ObjectInfo
|
|
||||||
loading={loading}
|
|
||||||
isEditing={isEditing}
|
|
||||||
type='productSku'
|
|
||||||
objectData={objectData}
|
|
||||||
visibleProperties={{
|
|
||||||
parts: false
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</ObjectForm>
|
|
||||||
</InfoCollapse>
|
|
||||||
</ActionHandler>
|
|
||||||
<InfoCollapse
|
|
||||||
title='SKU Parts'
|
|
||||||
icon={<PartIcon />}
|
|
||||||
active={collapseState.parts}
|
|
||||||
onToggle={(expanded) => updateCollapseState('parts', expanded)}
|
|
||||||
collapseKey='parts'
|
|
||||||
>
|
|
||||||
<ObjectProperty
|
|
||||||
{...getModelProperty('productSku', 'parts')}
|
|
||||||
isEditing={objectFormState.isEditing}
|
|
||||||
objectData={objectFormState.objectData}
|
|
||||||
loading={objectFormState.loading}
|
|
||||||
size='medium'
|
|
||||||
/>
|
|
||||||
</InfoCollapse>
|
|
||||||
<InfoCollapse
|
|
||||||
title='Notes'
|
|
||||||
icon={<NoteIcon />}
|
|
||||||
active={collapseState.notes}
|
|
||||||
onToggle={(expanded) => updateCollapseState('notes', expanded)}
|
|
||||||
collapseKey='notes'
|
|
||||||
>
|
|
||||||
<Card>
|
|
||||||
<NotesPanel _id={productSkuId} type='productSku' />
|
|
||||||
</Card>
|
|
||||||
</InfoCollapse>
|
|
||||||
<InfoCollapse
|
|
||||||
title='Audit Logs'
|
|
||||||
icon={<AuditLogIcon />}
|
|
||||||
active={collapseState.auditLogs}
|
|
||||||
onToggle={(expanded) =>
|
|
||||||
updateCollapseState('auditLogs', expanded)
|
|
||||||
}
|
|
||||||
collapseKey='auditLogs'
|
|
||||||
>
|
|
||||||
{objectFormState.loading ? (
|
|
||||||
<InfoCollapsePlaceholder />
|
|
||||||
) : (
|
|
||||||
<ObjectTable
|
|
||||||
type='auditLog'
|
|
||||||
masterFilter={{ 'parent._id': productSkuId }}
|
|
||||||
visibleColumns={{ _id: false, 'parent._id': false }}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</InfoCollapse>
|
|
||||||
</Flex>
|
|
||||||
</ScrollBox>
|
|
||||||
</Flex>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ProductSkuInfo
|
|
||||||
@ -25,11 +25,9 @@ import ReloadIcon from '../../Icons/ReloadIcon'
|
|||||||
import XMarkIcon from '../../Icons/XMarkIcon'
|
import XMarkIcon from '../../Icons/XMarkIcon'
|
||||||
import CheckIcon from '../../Icons/CheckIcon'
|
import CheckIcon from '../../Icons/CheckIcon'
|
||||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
import useColumnVisibility from '../hooks/useColumnVisibility'
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
import GridIcon from '../../Icons/GridIcon'
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
import ListIcon from '../../Icons/ListIcon'
|
||||||
import useViewMode from '../hooks/useViewMode'
|
import useViewMode from '../hooks/useViewMode'
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
import ExportListButton from '../common/ExportListButton'
|
|
||||||
|
|
||||||
const Products = () => {
|
const Products = () => {
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
@ -232,13 +230,10 @@ const Products = () => {
|
|||||||
]
|
]
|
||||||
|
|
||||||
const [columnVisibility, updateColumnVisibility] = useColumnVisibility(
|
const [columnVisibility, updateColumnVisibility] = useColumnVisibility(
|
||||||
'product',
|
'Products',
|
||||||
columns
|
columns
|
||||||
)
|
)
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('Products')
|
|
||||||
|
|
||||||
const actionItems = {
|
const actionItems = {
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -324,13 +319,12 @@ const Products = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
<Flex vertical={'true'} gap='large'>
|
||||||
<Flex justify={'space-between'}>
|
<Flex justify={'space-between'}>
|
||||||
<Space size='small'>
|
<Space size='small'>
|
||||||
<Dropdown menu={actionItems}>
|
<Dropdown menu={actionItems}>
|
||||||
<Button>Actions</Button>
|
<Button>Actions</Button>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
<ExportListButton objectType='product' />
|
|
||||||
<Popover
|
<Popover
|
||||||
content={getViewDropdownItems()}
|
content={getViewDropdownItems()}
|
||||||
placement='bottomLeft'
|
placement='bottomLeft'
|
||||||
@ -340,13 +334,11 @@ const Products = () => {
|
|||||||
</Popover>
|
</Popover>
|
||||||
</Space>
|
</Space>
|
||||||
<Space>
|
<Space>
|
||||||
<FilterSidebarButton
|
<Button
|
||||||
active={showFilterSidebar}
|
icon={viewMode === 'cards' ? <ListIcon /> : <GridIcon />}
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
onClick={() =>
|
||||||
/>
|
setViewMode(viewMode === 'cards' ? 'list' : 'cards')
|
||||||
<ObjectTableViewButton
|
}
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -354,7 +346,6 @@ const Products = () => {
|
|||||||
ref={tableRef}
|
ref={tableRef}
|
||||||
type={'product'}
|
type={'product'}
|
||||||
cards={viewMode === 'cards'}
|
cards={viewMode === 'cards'}
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Modal
|
<Modal
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import { useRef, useState } from 'react'
|
import { useRef, useState } from 'react'
|
||||||
import { Modal } from 'antd'
|
|
||||||
import { useLocation } from 'react-router-dom'
|
import { useLocation } from 'react-router-dom'
|
||||||
import { Space, Flex, Card } from 'antd'
|
import { Space, Flex, Card } from 'antd'
|
||||||
import useCollapseState from '../../hooks/useCollapseState'
|
import useCollapseState from '../../hooks/useCollapseState'
|
||||||
@ -20,8 +19,9 @@ import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
|
|||||||
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
|
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
|
||||||
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
|
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
|
||||||
import ScrollBox from '../../common/ScrollBox.jsx'
|
import ScrollBox from '../../common/ScrollBox.jsx'
|
||||||
import ProductSkuIcon from '../../../Icons/ProductSkuIcon.jsx'
|
import ObjectProperty from '../../common/ObjectProperty.jsx'
|
||||||
import NewProductSku from '../ProductSkus/NewProductSku'
|
import { getModelProperty } from '../../../../database/ObjectModels.js'
|
||||||
|
import PartIcon from '../../../Icons/PartIcon.jsx'
|
||||||
|
|
||||||
const ProductInfo = () => {
|
const ProductInfo = () => {
|
||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
@ -30,12 +30,10 @@ const ProductInfo = () => {
|
|||||||
const productId = new URLSearchParams(location.search).get('productId')
|
const productId = new URLSearchParams(location.search).get('productId')
|
||||||
const [collapseState, updateCollapseState] = useCollapseState('ProductInfo', {
|
const [collapseState, updateCollapseState] = useCollapseState('ProductInfo', {
|
||||||
info: true,
|
info: true,
|
||||||
productSkus: true,
|
parts: true,
|
||||||
notes: true,
|
notes: true,
|
||||||
auditLogs: true
|
auditLogs: true
|
||||||
})
|
})
|
||||||
const [newProductSkuOpen, setNewProductSkuOpen] = useState(false)
|
|
||||||
const productSkusTableRef = useRef()
|
|
||||||
const [objectFormState, setEditFormState] = useState({
|
const [objectFormState, setEditFormState] = useState({
|
||||||
isEditing: false,
|
isEditing: false,
|
||||||
editLoading: false,
|
editLoading: false,
|
||||||
@ -50,10 +48,6 @@ const ProductInfo = () => {
|
|||||||
objectFormRef?.current?.fetchObject?.()
|
objectFormRef?.current?.fetchObject?.()
|
||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
newProductSku: () => {
|
|
||||||
setNewProductSkuOpen(true)
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
edit: () => {
|
edit: () => {
|
||||||
objectFormRef?.current?.startEditing?.()
|
objectFormRef?.current?.startEditing?.()
|
||||||
return false
|
return false
|
||||||
@ -88,7 +82,7 @@ const ProductInfo = () => {
|
|||||||
disabled={objectFormState.loading}
|
disabled={objectFormState.loading}
|
||||||
items={[
|
items={[
|
||||||
{ key: 'info', label: 'Product Information' },
|
{ key: 'info', label: 'Product Information' },
|
||||||
{ key: 'productSkus', label: 'Product SKUs' },
|
{ key: 'parts', label: 'Product Parts' },
|
||||||
{ key: 'notes', label: 'Notes' },
|
{ key: 'notes', label: 'Notes' },
|
||||||
{ key: 'auditLogs', label: 'Audit Logs' }
|
{ key: 'auditLogs', label: 'Audit Logs' }
|
||||||
]}
|
]}
|
||||||
@ -159,53 +153,32 @@ const ProductInfo = () => {
|
|||||||
isEditing={isEditing}
|
isEditing={isEditing}
|
||||||
type='product'
|
type='product'
|
||||||
objectData={objectData}
|
objectData={objectData}
|
||||||
|
visibleProperties={{
|
||||||
|
parts: false
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</InfoCollapse>
|
</InfoCollapse>
|
||||||
<InfoCollapse
|
<InfoCollapse
|
||||||
title='Product SKUs'
|
title='Product Parts'
|
||||||
icon={<ProductSkuIcon />}
|
icon={<PartIcon />}
|
||||||
active={collapseState.productSkus}
|
active={collapseState.parts}
|
||||||
onToggle={(expanded) =>
|
onToggle={(expanded) =>
|
||||||
updateCollapseState('productSkus', expanded)
|
updateCollapseState('parts', expanded)
|
||||||
}
|
}
|
||||||
collapseKey='productSkus'
|
collapseKey='parts'
|
||||||
>
|
>
|
||||||
{objectFormState.loading ? (
|
<ObjectProperty
|
||||||
<InfoCollapsePlaceholder />
|
{...getModelProperty('product', 'parts')}
|
||||||
) : (
|
isEditing={isEditing}
|
||||||
<ObjectTable
|
objectData={objectData}
|
||||||
ref={productSkusTableRef}
|
loading={loading}
|
||||||
type='productSku'
|
/>
|
||||||
masterFilter={{ product: productId }}
|
|
||||||
visibleColumns={{ product: false }}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</InfoCollapse>
|
</InfoCollapse>
|
||||||
</Flex>
|
</Flex>
|
||||||
)}
|
)}
|
||||||
</ObjectForm>
|
</ObjectForm>
|
||||||
</ActionHandler>
|
</ActionHandler>
|
||||||
|
|
||||||
<Modal
|
|
||||||
open={newProductSkuOpen}
|
|
||||||
styles={{ content: { paddingBottom: '24px' } }}
|
|
||||||
footer={null}
|
|
||||||
width={700}
|
|
||||||
onCancel={() => setNewProductSkuOpen(false)}
|
|
||||||
destroyOnClose
|
|
||||||
>
|
|
||||||
<NewProductSku
|
|
||||||
onOk={() => {
|
|
||||||
setNewProductSkuOpen(false)
|
|
||||||
productSkusTableRef.current?.reload?.()
|
|
||||||
}}
|
|
||||||
reset={newProductSkuOpen}
|
|
||||||
defaultValues={{
|
|
||||||
product: productId ? { _id: productId } : undefined
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Modal>
|
|
||||||
|
|
||||||
<InfoCollapse
|
<InfoCollapse
|
||||||
title='Notes'
|
title='Notes'
|
||||||
icon={<NoteIcon />}
|
icon={<NoteIcon />}
|
||||||
|
|||||||
@ -5,12 +5,10 @@ import ObjectTable from '../common/ObjectTable'
|
|||||||
import PlusIcon from '../../Icons/PlusIcon'
|
import PlusIcon from '../../Icons/PlusIcon'
|
||||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
import ReloadIcon from '../../Icons/ReloadIcon'
|
||||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
import useColumnVisibility from '../hooks/useColumnVisibility'
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
import GridIcon from '../../Icons/GridIcon'
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
import ListIcon from '../../Icons/ListIcon'
|
||||||
import useViewMode from '../hooks/useViewMode'
|
import useViewMode from '../hooks/useViewMode'
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
import ColumnViewButton from '../common/ColumnViewButton'
|
import ColumnViewButton from '../common/ColumnViewButton'
|
||||||
import ExportListButton from '../common/ExportListButton'
|
|
||||||
|
|
||||||
const TaxRates = () => {
|
const TaxRates = () => {
|
||||||
const [newTaxRateOpen, setNewTaxRateOpen] = useState(false)
|
const [newTaxRateOpen, setNewTaxRateOpen] = useState(false)
|
||||||
@ -20,9 +18,6 @@ const TaxRates = () => {
|
|||||||
|
|
||||||
const [columnVisibility, setColumnVisibility] = useColumnVisibility('taxRate')
|
const [columnVisibility, setColumnVisibility] = useColumnVisibility('taxRate')
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('TaxRates')
|
|
||||||
|
|
||||||
const actionItems = {
|
const actionItems = {
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -48,7 +43,7 @@ const TaxRates = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
<Flex vertical={'true'} gap='large'>
|
||||||
<Flex justify={'space-between'}>
|
<Flex justify={'space-between'}>
|
||||||
<Space size='small'>
|
<Space size='small'>
|
||||||
<Dropdown menu={actionItems}>
|
<Dropdown menu={actionItems}>
|
||||||
@ -57,19 +52,16 @@ const TaxRates = () => {
|
|||||||
<ColumnViewButton
|
<ColumnViewButton
|
||||||
type='taxRate'
|
type='taxRate'
|
||||||
loading={false}
|
loading={false}
|
||||||
visibleState={columnVisibility}
|
collapseState={columnVisibility}
|
||||||
updateVisibleState={setColumnVisibility}
|
updateCollapseState={setColumnVisibility}
|
||||||
/>
|
/>
|
||||||
<ExportListButton objectType='taxRate' />
|
|
||||||
</Space>
|
</Space>
|
||||||
<Space>
|
<Space>
|
||||||
<FilterSidebarButton
|
<Button
|
||||||
active={showFilterSidebar}
|
icon={viewMode === 'cards' ? <ListIcon /> : <GridIcon />}
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
onClick={() =>
|
||||||
/>
|
setViewMode(viewMode === 'cards' ? 'list' : 'cards')
|
||||||
<ObjectTableViewButton
|
}
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -78,7 +70,6 @@ const TaxRates = () => {
|
|||||||
visibleColumns={columnVisibility}
|
visibleColumns={columnVisibility}
|
||||||
type='taxRate'
|
type='taxRate'
|
||||||
cards={viewMode === 'cards'}
|
cards={viewMode === 'cards'}
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Modal
|
<Modal
|
||||||
|
|||||||
@ -5,12 +5,10 @@ import ObjectTable from '../common/ObjectTable'
|
|||||||
import PlusIcon from '../../Icons/PlusIcon'
|
import PlusIcon from '../../Icons/PlusIcon'
|
||||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
import ReloadIcon from '../../Icons/ReloadIcon'
|
||||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
import useColumnVisibility from '../hooks/useColumnVisibility'
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
import GridIcon from '../../Icons/GridIcon'
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
import ListIcon from '../../Icons/ListIcon'
|
||||||
import useViewMode from '../hooks/useViewMode'
|
import useViewMode from '../hooks/useViewMode'
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
import ColumnViewButton from '../common/ColumnViewButton'
|
import ColumnViewButton from '../common/ColumnViewButton'
|
||||||
import ExportListButton from '../common/ExportListButton'
|
|
||||||
|
|
||||||
const TaxRecords = () => {
|
const TaxRecords = () => {
|
||||||
const [newTaxRecordOpen, setNewTaxRecordOpen] = useState(false)
|
const [newTaxRecordOpen, setNewTaxRecordOpen] = useState(false)
|
||||||
@ -21,9 +19,6 @@ const TaxRecords = () => {
|
|||||||
const [columnVisibility, setColumnVisibility] =
|
const [columnVisibility, setColumnVisibility] =
|
||||||
useColumnVisibility('taxRecord')
|
useColumnVisibility('taxRecord')
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('TaxRecords')
|
|
||||||
|
|
||||||
const actionItems = {
|
const actionItems = {
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -49,7 +44,7 @@ const TaxRecords = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
<Flex vertical={'true'} gap='large'>
|
||||||
<Flex justify={'space-between'}>
|
<Flex justify={'space-between'}>
|
||||||
<Space size='small'>
|
<Space size='small'>
|
||||||
<Dropdown menu={actionItems}>
|
<Dropdown menu={actionItems}>
|
||||||
@ -61,16 +56,13 @@ const TaxRecords = () => {
|
|||||||
collapseState={columnVisibility}
|
collapseState={columnVisibility}
|
||||||
updateCollapseState={setColumnVisibility}
|
updateCollapseState={setColumnVisibility}
|
||||||
/>
|
/>
|
||||||
<ExportListButton objectType='taxRecord' />
|
|
||||||
</Space>
|
</Space>
|
||||||
<Space>
|
<Space>
|
||||||
<FilterSidebarButton
|
<Button
|
||||||
active={showFilterSidebar}
|
icon={viewMode === 'cards' ? <ListIcon /> : <GridIcon />}
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
onClick={() =>
|
||||||
/>
|
setViewMode(viewMode === 'cards' ? 'list' : 'cards')
|
||||||
<ObjectTableViewButton
|
}
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -79,7 +71,6 @@ const TaxRecords = () => {
|
|||||||
visibleColumns={columnVisibility}
|
visibleColumns={columnVisibility}
|
||||||
type='taxRecord'
|
type='taxRecord'
|
||||||
cards={viewMode === 'cards'}
|
cards={viewMode === 'cards'}
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Modal
|
<Modal
|
||||||
|
|||||||
@ -3,12 +3,10 @@ import { Button, Flex, Space, Dropdown } from 'antd'
|
|||||||
import ObjectTable from '../common/ObjectTable'
|
import ObjectTable from '../common/ObjectTable'
|
||||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
import ReloadIcon from '../../Icons/ReloadIcon'
|
||||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
import useColumnVisibility from '../hooks/useColumnVisibility'
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
import GridIcon from '../../Icons/GridIcon'
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
import ListIcon from '../../Icons/ListIcon'
|
||||||
import useViewMode from '../hooks/useViewMode'
|
import useViewMode from '../hooks/useViewMode'
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
import ColumnViewButton from '../common/ColumnViewButton'
|
import ColumnViewButton from '../common/ColumnViewButton'
|
||||||
import ExportListButton from '../common/ExportListButton'
|
|
||||||
|
|
||||||
const Users = () => {
|
const Users = () => {
|
||||||
const tableRef = useRef()
|
const tableRef = useRef()
|
||||||
@ -17,9 +15,6 @@ const Users = () => {
|
|||||||
|
|
||||||
const [columnVisibility, setColumnVisibility] = useColumnVisibility('user')
|
const [columnVisibility, setColumnVisibility] = useColumnVisibility('user')
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('Users')
|
|
||||||
|
|
||||||
const actionItems = {
|
const actionItems = {
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -36,7 +31,7 @@ const Users = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
<Flex vertical={'true'} gap='large'>
|
||||||
<Flex justify={'space-between'}>
|
<Flex justify={'space-between'}>
|
||||||
<Space size='small'>
|
<Space size='small'>
|
||||||
<Dropdown menu={actionItems}>
|
<Dropdown menu={actionItems}>
|
||||||
@ -48,16 +43,11 @@ const Users = () => {
|
|||||||
visibleState={columnVisibility}
|
visibleState={columnVisibility}
|
||||||
updateVisibleState={setColumnVisibility}
|
updateVisibleState={setColumnVisibility}
|
||||||
/>
|
/>
|
||||||
<ExportListButton objectType='user' />
|
|
||||||
</Space>
|
</Space>
|
||||||
<Space>
|
<Space>
|
||||||
<FilterSidebarButton
|
<Button
|
||||||
active={showFilterSidebar}
|
icon={viewMode === 'cards' ? <ListIcon /> : <GridIcon />}
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
onClick={() => setViewMode(viewMode === 'cards' ? 'list' : 'cards')}
|
||||||
/>
|
|
||||||
<ObjectTableViewButton
|
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -66,7 +56,6 @@ const Users = () => {
|
|||||||
type={'user'}
|
type={'user'}
|
||||||
visibleColumns={columnVisibility}
|
visibleColumns={columnVisibility}
|
||||||
cards={viewMode === 'cards'}
|
cards={viewMode === 'cards'}
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,73 +0,0 @@
|
|||||||
import PropTypes from 'prop-types'
|
|
||||||
import { useContext, useState } from 'react'
|
|
||||||
import { Result, Typography, Flex, Button } from 'antd'
|
|
||||||
import { ApiServerContext } from '../../context/ApiServerContext'
|
|
||||||
import CopyButton from '../../common/CopyButton'
|
|
||||||
import LockIcon from '../../../Icons/LockIcon'
|
|
||||||
import ReloadIcon from '../../../Icons/ReloadIcon'
|
|
||||||
|
|
||||||
const { Text } = Typography
|
|
||||||
|
|
||||||
const SetAppPassword = ({ id }) => {
|
|
||||||
const { sendObjectFunction } = useContext(ApiServerContext)
|
|
||||||
const [appPassword, setAppPassword] = useState(null)
|
|
||||||
const [loading, setLoading] = useState(false)
|
|
||||||
const [passwordGenerated, setPasswordGenerated] = useState(false)
|
|
||||||
|
|
||||||
const handleSet = async () => {
|
|
||||||
setLoading(true)
|
|
||||||
setAppPassword(null)
|
|
||||||
try {
|
|
||||||
const result = await sendObjectFunction(id, 'user', 'setAppPassword', {})
|
|
||||||
if (result?.appPassword) {
|
|
||||||
setAppPassword(result.appPassword)
|
|
||||||
setPasswordGenerated(true)
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
setLoading(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Flex vertical align='center'>
|
|
||||||
<Result
|
|
||||||
title={
|
|
||||||
passwordGenerated ? 'App Password Generated' : 'Roll New Password'
|
|
||||||
}
|
|
||||||
disabled={passwordGenerated}
|
|
||||||
subTitle={
|
|
||||||
appPassword ? (
|
|
||||||
<Text>Copy this password now. It will not be shown again.</Text>
|
|
||||||
) : (
|
|
||||||
<Text>Generate a new app password for API access.</Text>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
icon={<LockIcon />}
|
|
||||||
>
|
|
||||||
<Flex justify='center' style={{ minWidth: '395px' }}>
|
|
||||||
<Flex justify='center'>
|
|
||||||
<Flex gap='small' align='center' justify='center'>
|
|
||||||
<CopyButton size='default' text={appPassword} />
|
|
||||||
|
|
||||||
<Text code style={{ fontSize: '18px' }}>
|
|
||||||
{appPassword || '••••••••••••••••••••••••••••••••'}
|
|
||||||
</Text>
|
|
||||||
<Button
|
|
||||||
type='texts'
|
|
||||||
loading={loading}
|
|
||||||
onClick={handleSet}
|
|
||||||
icon={<ReloadIcon />}
|
|
||||||
/>
|
|
||||||
</Flex>
|
|
||||||
</Flex>
|
|
||||||
</Flex>
|
|
||||||
</Result>
|
|
||||||
</Flex>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
SetAppPassword.propTypes = {
|
|
||||||
id: PropTypes.string.isRequired
|
|
||||||
}
|
|
||||||
|
|
||||||
export default SetAppPassword
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import { useRef, useState } from 'react'
|
import { useRef, useState } from 'react'
|
||||||
import { useLocation } from 'react-router-dom'
|
import { useLocation } from 'react-router-dom'
|
||||||
import { Space, Flex, Card, Modal } from 'antd'
|
import { Space, Flex, Card } from 'antd'
|
||||||
import { LoadingOutlined } from '@ant-design/icons'
|
import { LoadingOutlined } from '@ant-design/icons'
|
||||||
import useCollapseState from '../../hooks/useCollapseState'
|
import useCollapseState from '../../hooks/useCollapseState'
|
||||||
import NotesPanel from '../../common/NotesPanel'
|
import NotesPanel from '../../common/NotesPanel'
|
||||||
@ -10,7 +10,6 @@ import ViewButton from '../../common/ViewButton'
|
|||||||
import InfoCircleIcon from '../../../Icons/InfoCircleIcon.jsx'
|
import InfoCircleIcon from '../../../Icons/InfoCircleIcon.jsx'
|
||||||
import NoteIcon from '../../../Icons/NoteIcon.jsx'
|
import NoteIcon from '../../../Icons/NoteIcon.jsx'
|
||||||
import AuditLogIcon from '../../../Icons/AuditLogIcon.jsx'
|
import AuditLogIcon from '../../../Icons/AuditLogIcon.jsx'
|
||||||
import AppPasswordIcon from '../../../Icons/AppPasswordIcon.jsx'
|
|
||||||
import ObjectForm from '../../common/ObjectForm'
|
import ObjectForm from '../../common/ObjectForm'
|
||||||
import EditButtons from '../../common/EditButtons'
|
import EditButtons from '../../common/EditButtons'
|
||||||
import LockIndicator from '../../common/LockIndicator.jsx'
|
import LockIndicator from '../../common/LockIndicator.jsx'
|
||||||
@ -21,18 +20,14 @@ import InfoCollapsePlaceholder from '../../common/InfoCollapsePlaceholder.jsx'
|
|||||||
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
|
import DocumentPrintButton from '../../common/DocumentPrintButton.jsx'
|
||||||
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
|
import UserNotifierToggle from '../../common/UserNotifierToggle.jsx'
|
||||||
import ScrollBox from '../../common/ScrollBox.jsx'
|
import ScrollBox from '../../common/ScrollBox.jsx'
|
||||||
import NewAppPassword from '../AppPasswords/NewAppPassword.jsx'
|
|
||||||
|
|
||||||
const UserInfo = () => {
|
const UserInfo = () => {
|
||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
const objectFormRef = useRef(null)
|
const objectFormRef = useRef(null)
|
||||||
const appPasswordsTableRef = useRef(null)
|
|
||||||
const actionHandlerRef = useRef(null)
|
const actionHandlerRef = useRef(null)
|
||||||
const userId = new URLSearchParams(location.search).get('userId')
|
const userId = new URLSearchParams(location.search).get('userId')
|
||||||
const [newAppPasswordOpen, setNewAppPasswordOpen] = useState(false)
|
|
||||||
const [collapseState, updateCollapseState] = useCollapseState('UserInfo', {
|
const [collapseState, updateCollapseState] = useCollapseState('UserInfo', {
|
||||||
info: true,
|
info: true,
|
||||||
appPasswords: true,
|
|
||||||
notes: true,
|
notes: true,
|
||||||
auditLogs: true
|
auditLogs: true
|
||||||
})
|
})
|
||||||
@ -47,13 +42,9 @@ const UserInfo = () => {
|
|||||||
|
|
||||||
const actions = {
|
const actions = {
|
||||||
reload: () => {
|
reload: () => {
|
||||||
objectFormRef?.current?.handleFetchObject?.()
|
objectFormRef?.current?.fetchObject?.()
|
||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
newAppPassword: () => {
|
|
||||||
setNewAppPasswordOpen(true)
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
edit: () => {
|
edit: () => {
|
||||||
objectFormRef?.current?.startEditing?.()
|
objectFormRef?.current?.startEditing?.()
|
||||||
return false
|
return false
|
||||||
@ -88,7 +79,6 @@ const UserInfo = () => {
|
|||||||
disabled={objectFormState.loading}
|
disabled={objectFormState.loading}
|
||||||
items={[
|
items={[
|
||||||
{ key: 'info', label: 'User Information' },
|
{ key: 'info', label: 'User Information' },
|
||||||
{ key: 'appPasswords', label: 'App Passwords' },
|
|
||||||
{ key: 'notes', label: 'Notes' },
|
{ key: 'notes', label: 'Notes' },
|
||||||
{ key: 'auditLogs', label: 'Audit Logs' }
|
{ key: 'auditLogs', label: 'Audit Logs' }
|
||||||
]}
|
]}
|
||||||
@ -162,26 +152,6 @@ const UserInfo = () => {
|
|||||||
</ObjectForm>
|
</ObjectForm>
|
||||||
</InfoCollapse>
|
</InfoCollapse>
|
||||||
</ActionHandler>
|
</ActionHandler>
|
||||||
<InfoCollapse
|
|
||||||
title='App Passwords'
|
|
||||||
icon={<AppPasswordIcon />}
|
|
||||||
active={collapseState.appPasswords}
|
|
||||||
onToggle={(expanded) =>
|
|
||||||
updateCollapseState('appPasswords', expanded)
|
|
||||||
}
|
|
||||||
collapseKey='appPasswords'
|
|
||||||
>
|
|
||||||
{!userId ? (
|
|
||||||
<InfoCollapsePlaceholder />
|
|
||||||
) : (
|
|
||||||
<ObjectTable
|
|
||||||
type='appPassword'
|
|
||||||
masterFilter={{ user: userId }}
|
|
||||||
visibleColumns={{ user: false }}
|
|
||||||
ref={appPasswordsTableRef}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</InfoCollapse>
|
|
||||||
<InfoCollapse
|
<InfoCollapse
|
||||||
title='Notes'
|
title='Notes'
|
||||||
icon={<NoteIcon />}
|
icon={<NoteIcon />}
|
||||||
@ -215,26 +185,6 @@ const UserInfo = () => {
|
|||||||
</Flex>
|
</Flex>
|
||||||
</ScrollBox>
|
</ScrollBox>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
<Modal
|
|
||||||
open={newAppPasswordOpen}
|
|
||||||
destroyOnClose
|
|
||||||
width={700}
|
|
||||||
onCancel={() => {
|
|
||||||
actionHandlerRef.current?.clearAction?.()
|
|
||||||
setNewAppPasswordOpen(false)
|
|
||||||
}}
|
|
||||||
footer={null}
|
|
||||||
>
|
|
||||||
<NewAppPassword
|
|
||||||
onOk={() => {
|
|
||||||
setNewAppPasswordOpen(false)
|
|
||||||
appPasswordsTableRef.current?.reload?.()
|
|
||||||
}}
|
|
||||||
reset={newAppPasswordOpen}
|
|
||||||
defaultValues={{ user: { ...objectFormState.objectData } }}
|
|
||||||
/>
|
|
||||||
</Modal>
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,12 +5,10 @@ import ObjectTable from '../common/ObjectTable'
|
|||||||
import PlusIcon from '../../Icons/PlusIcon'
|
import PlusIcon from '../../Icons/PlusIcon'
|
||||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
import ReloadIcon from '../../Icons/ReloadIcon'
|
||||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
import useColumnVisibility from '../hooks/useColumnVisibility'
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
import GridIcon from '../../Icons/GridIcon'
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
import ListIcon from '../../Icons/ListIcon'
|
||||||
import useViewMode from '../hooks/useViewMode'
|
import useViewMode from '../hooks/useViewMode'
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
import ColumnViewButton from '../common/ColumnViewButton'
|
import ColumnViewButton from '../common/ColumnViewButton'
|
||||||
import ExportListButton from '../common/ExportListButton'
|
|
||||||
|
|
||||||
const Vendors = () => {
|
const Vendors = () => {
|
||||||
const [newVendorOpen, setNewVendorOpen] = useState(false)
|
const [newVendorOpen, setNewVendorOpen] = useState(false)
|
||||||
@ -20,9 +18,6 @@ const Vendors = () => {
|
|||||||
|
|
||||||
const [columnVisibility, setColumnVisibility] = useColumnVisibility('vendor')
|
const [columnVisibility, setColumnVisibility] = useColumnVisibility('vendor')
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('Vendors')
|
|
||||||
|
|
||||||
const actionItems = {
|
const actionItems = {
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -48,7 +43,7 @@ const Vendors = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
<Flex vertical={'true'} gap='large'>
|
||||||
<Flex justify={'space-between'}>
|
<Flex justify={'space-between'}>
|
||||||
<Space size='small'>
|
<Space size='small'>
|
||||||
<Dropdown menu={actionItems}>
|
<Dropdown menu={actionItems}>
|
||||||
@ -57,19 +52,16 @@ const Vendors = () => {
|
|||||||
<ColumnViewButton
|
<ColumnViewButton
|
||||||
type='vendor'
|
type='vendor'
|
||||||
loading={false}
|
loading={false}
|
||||||
visibleState={columnVisibility}
|
collapseState={columnVisibility}
|
||||||
updateVisibleState={setColumnVisibility}
|
updateCollapseState={setColumnVisibility}
|
||||||
/>
|
/>
|
||||||
<ExportListButton objectType='vendor' />
|
|
||||||
</Space>
|
</Space>
|
||||||
<Space>
|
<Space>
|
||||||
<FilterSidebarButton
|
<Button
|
||||||
active={showFilterSidebar}
|
icon={viewMode === 'cards' ? <ListIcon /> : <GridIcon />}
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
onClick={() =>
|
||||||
/>
|
setViewMode(viewMode === 'cards' ? 'list' : 'cards')
|
||||||
<ObjectTableViewButton
|
}
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -78,7 +70,6 @@ const Vendors = () => {
|
|||||||
visibleColumns={columnVisibility}
|
visibleColumns={columnVisibility}
|
||||||
type='vendor'
|
type='vendor'
|
||||||
cards={viewMode === 'cards'}
|
cards={viewMode === 'cards'}
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Modal
|
<Modal
|
||||||
|
|||||||
@ -7,13 +7,11 @@ import useColumnVisibility from '../hooks/useColumnVisibility'
|
|||||||
import PlusIcon from '../../Icons/PlusIcon'
|
import PlusIcon from '../../Icons/PlusIcon'
|
||||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
import ReloadIcon from '../../Icons/ReloadIcon'
|
||||||
import ObjectTable from '../common/ObjectTable'
|
import ObjectTable from '../common/ObjectTable'
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
import ListIcon from '../../Icons/ListIcon'
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
import GridIcon from '../../Icons/GridIcon'
|
||||||
import useViewMode from '../hooks/useViewMode'
|
import useViewMode from '../hooks/useViewMode'
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
|
|
||||||
import ColumnViewButton from '../common/ColumnViewButton'
|
import ColumnViewButton from '../common/ColumnViewButton'
|
||||||
import ExportListButton from '../common/ExportListButton'
|
|
||||||
|
|
||||||
const GCodeFiles = () => {
|
const GCodeFiles = () => {
|
||||||
const [newGCodeFileOpen, setNewGCodeFileOpen] = useState(false)
|
const [newGCodeFileOpen, setNewGCodeFileOpen] = useState(false)
|
||||||
@ -23,9 +21,6 @@ const GCodeFiles = () => {
|
|||||||
const [columnVisibility, setColumnVisibility] =
|
const [columnVisibility, setColumnVisibility] =
|
||||||
useColumnVisibility('gcodeFile')
|
useColumnVisibility('gcodeFile')
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('GCodeFiles')
|
|
||||||
|
|
||||||
const actionItems = {
|
const actionItems = {
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -51,7 +46,7 @@ const GCodeFiles = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
<Flex vertical={'true'} gap='large'>
|
||||||
<Flex justify={'space-between'}>
|
<Flex justify={'space-between'}>
|
||||||
<Space>
|
<Space>
|
||||||
<Dropdown menu={actionItems}>
|
<Dropdown menu={actionItems}>
|
||||||
@ -63,16 +58,13 @@ const GCodeFiles = () => {
|
|||||||
visibleState={columnVisibility}
|
visibleState={columnVisibility}
|
||||||
updateVisibleState={setColumnVisibility}
|
updateVisibleState={setColumnVisibility}
|
||||||
/>
|
/>
|
||||||
<ExportListButton objectType='gcodeFile' />
|
|
||||||
</Space>
|
</Space>
|
||||||
<Space>
|
<Space>
|
||||||
<FilterSidebarButton
|
<Button
|
||||||
active={showFilterSidebar}
|
icon={viewMode === 'cards' ? <ListIcon /> : <GridIcon />}
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
onClick={() =>
|
||||||
/>
|
setViewMode(viewMode === 'cards' ? 'list' : 'cards')
|
||||||
<ObjectTableViewButton
|
}
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -81,7 +73,6 @@ const GCodeFiles = () => {
|
|||||||
type='gcodeFile'
|
type='gcodeFile'
|
||||||
cards={viewMode === 'cards'}
|
cards={viewMode === 'cards'}
|
||||||
visibleColumns={columnVisibility}
|
visibleColumns={columnVisibility}
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Modal
|
<Modal
|
||||||
|
|||||||
@ -7,12 +7,10 @@ import useColumnVisibility from '../hooks/useColumnVisibility.jsx'
|
|||||||
import PlusIcon from '../../Icons/PlusIcon.jsx'
|
import PlusIcon from '../../Icons/PlusIcon.jsx'
|
||||||
import ReloadIcon from '../../Icons/ReloadIcon.jsx'
|
import ReloadIcon from '../../Icons/ReloadIcon.jsx'
|
||||||
import ObjectTable from '../common/ObjectTable.jsx'
|
import ObjectTable from '../common/ObjectTable.jsx'
|
||||||
|
import ListIcon from '../../Icons/ListIcon.jsx'
|
||||||
|
import GridIcon from '../../Icons/GridIcon.jsx'
|
||||||
import useViewMode from '../hooks/useViewMode.jsx'
|
import useViewMode from '../hooks/useViewMode.jsx'
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
|
||||||
import ColumnViewButton from '../common/ColumnViewButton.jsx'
|
import ColumnViewButton from '../common/ColumnViewButton.jsx'
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility.jsx'
|
|
||||||
import ExportListButton from '../common/ExportListButton.jsx'
|
|
||||||
|
|
||||||
const Jobs = () => {
|
const Jobs = () => {
|
||||||
const [newJobOpen, setNewJobOpen] = useState(false)
|
const [newJobOpen, setNewJobOpen] = useState(false)
|
||||||
@ -21,9 +19,6 @@ const Jobs = () => {
|
|||||||
|
|
||||||
const [columnVisibility, setColumnVisibility] = useColumnVisibility('job')
|
const [columnVisibility, setColumnVisibility] = useColumnVisibility('job')
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('Jobs')
|
|
||||||
|
|
||||||
const actionItems = {
|
const actionItems = {
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -53,7 +48,7 @@ const Jobs = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
<Flex vertical={'true'} gap='large' style={{ height: '100%' }}>
|
||||||
<Flex justify={'space-between'}>
|
<Flex justify={'space-between'}>
|
||||||
<Space size='small'>
|
<Space size='small'>
|
||||||
<Dropdown menu={actionItems}>
|
<Dropdown menu={actionItems}>
|
||||||
@ -65,17 +60,14 @@ const Jobs = () => {
|
|||||||
visibleState={columnVisibility}
|
visibleState={columnVisibility}
|
||||||
updateVisibleState={setColumnVisibility}
|
updateVisibleState={setColumnVisibility}
|
||||||
/>
|
/>
|
||||||
<ExportListButton objectType='job' />
|
|
||||||
</Space>
|
</Space>
|
||||||
|
|
||||||
<Space>
|
<Space>
|
||||||
<FilterSidebarButton
|
<Button
|
||||||
active={showFilterSidebar}
|
icon={viewMode === 'cards' ? <ListIcon /> : <GridIcon />}
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
onClick={() =>
|
||||||
/>
|
setViewMode(viewMode === 'cards' ? 'list' : 'cards')
|
||||||
<ObjectTableViewButton
|
}
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -85,7 +77,6 @@ const Jobs = () => {
|
|||||||
type={'job'}
|
type={'job'}
|
||||||
visibleColumns={columnVisibility}
|
visibleColumns={columnVisibility}
|
||||||
cards={viewMode === 'cards'}
|
cards={viewMode === 'cards'}
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Modal
|
<Modal
|
||||||
|
|||||||
@ -7,13 +7,11 @@ import PlusIcon from '../../Icons/PlusIcon'
|
|||||||
import ReloadIcon from '../../Icons/ReloadIcon'
|
import ReloadIcon from '../../Icons/ReloadIcon'
|
||||||
import ObjectTable from '../common/ObjectTable'
|
import ObjectTable from '../common/ObjectTable'
|
||||||
import ColumnViewButton from '../common/ColumnViewButton'
|
import ColumnViewButton from '../common/ColumnViewButton'
|
||||||
import ExportListButton from '../common/ExportListButton'
|
|
||||||
|
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
import GridIcon from '../../Icons/GridIcon'
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
import ListIcon from '../../Icons/ListIcon'
|
||||||
import useViewMode from '../hooks/useViewMode'
|
import useViewMode from '../hooks/useViewMode'
|
||||||
import useColumnVisibility from '../hooks/useColumnVisibility'
|
import useColumnVisibility from '../hooks/useColumnVisibility'
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility'
|
|
||||||
|
|
||||||
const Printers = () => {
|
const Printers = () => {
|
||||||
const [newPrinterOpen, setNewPrinterOpen] = useState(false)
|
const [newPrinterOpen, setNewPrinterOpen] = useState(false)
|
||||||
@ -25,9 +23,6 @@ const Printers = () => {
|
|||||||
// Column visibility state, persisted in sessionStorage via custom hook
|
// Column visibility state, persisted in sessionStorage via custom hook
|
||||||
const [columnVisibility, setColumnVisibility] = useColumnVisibility('printer')
|
const [columnVisibility, setColumnVisibility] = useColumnVisibility('printer')
|
||||||
|
|
||||||
// Filter sidebar visibility, persisted in sessionStorage via custom hook
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] = useFilterSidebarVisibility('Printers')
|
|
||||||
|
|
||||||
const actionItems = {
|
const actionItems = {
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -53,7 +48,7 @@ const Printers = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
<Flex vertical={'true'} gap='large'>
|
||||||
<Flex justify={'space-between'}>
|
<Flex justify={'space-between'}>
|
||||||
<Space>
|
<Space>
|
||||||
<Dropdown menu={actionItems}>
|
<Dropdown menu={actionItems}>
|
||||||
@ -65,16 +60,13 @@ const Printers = () => {
|
|||||||
visibleState={columnVisibility}
|
visibleState={columnVisibility}
|
||||||
updateVisibleState={setColumnVisibility}
|
updateVisibleState={setColumnVisibility}
|
||||||
/>
|
/>
|
||||||
<ExportListButton objectType='printer' />
|
|
||||||
</Space>
|
</Space>
|
||||||
<Space>
|
<Space>
|
||||||
<FilterSidebarButton
|
<Button
|
||||||
active={showFilterSidebar}
|
icon={viewMode === 'cards' ? <ListIcon /> : <GridIcon />}
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
onClick={() =>
|
||||||
/>
|
setViewMode(viewMode === 'cards' ? 'list' : 'cards')
|
||||||
<ObjectTableViewButton
|
}
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -82,7 +74,6 @@ const Printers = () => {
|
|||||||
<ObjectTable
|
<ObjectTable
|
||||||
ref={tableRef}
|
ref={tableRef}
|
||||||
type='printer'
|
type='printer'
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
cards={viewMode === 'cards'}
|
cards={viewMode === 'cards'}
|
||||||
visibleColumns={columnVisibility}
|
visibleColumns={columnVisibility}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -1,12 +1,17 @@
|
|||||||
|
import { useContext } from 'react'
|
||||||
import { Flex } from 'antd'
|
import { Flex } from 'antd'
|
||||||
import useCollapseState from '../hooks/useCollapseState.jsx'
|
import useCollapseState from '../hooks/useCollapseState.jsx'
|
||||||
import StatsDisplay from '../common/StatsDisplay'
|
import StatsDisplay from '../common/StatsDisplay'
|
||||||
import HistoryDisplay from '../common/HistoryDisplay'
|
import HistoryDisplay from '../common/HistoryDisplay'
|
||||||
import InfoCollapse from '../common/InfoCollapse'
|
import InfoCollapse from '../common/InfoCollapse'
|
||||||
import ScrollBox from '../common/ScrollBox'
|
import ScrollBox from '../common/ScrollBox'
|
||||||
|
|
||||||
|
import { ApiServerContext } from '../context/ApiServerContext'
|
||||||
import ObjectTable from '../common/ObjectTable'
|
import ObjectTable from '../common/ObjectTable'
|
||||||
|
|
||||||
const ProductionOverview = () => {
|
const ProductionOverview = () => {
|
||||||
|
const { connected } = useContext(ApiServerContext)
|
||||||
|
|
||||||
const [collapseState, updateCollapseState] = useCollapseState(
|
const [collapseState, updateCollapseState] = useCollapseState(
|
||||||
'ProductionOverview',
|
'ProductionOverview',
|
||||||
{
|
{
|
||||||
@ -19,6 +24,10 @@ const ProductionOverview = () => {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (!connected) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex
|
<Flex
|
||||||
gap='large'
|
gap='large'
|
||||||
|
|||||||
@ -5,12 +5,10 @@ import { Button, Flex, Space, Dropdown } from 'antd'
|
|||||||
import useColumnVisibility from '../hooks/useColumnVisibility.jsx'
|
import useColumnVisibility from '../hooks/useColumnVisibility.jsx'
|
||||||
import ReloadIcon from '../../Icons/ReloadIcon.jsx'
|
import ReloadIcon from '../../Icons/ReloadIcon.jsx'
|
||||||
import ObjectTable from '../common/ObjectTable.jsx'
|
import ObjectTable from '../common/ObjectTable.jsx'
|
||||||
|
import ListIcon from '../../Icons/ListIcon.jsx'
|
||||||
|
import GridIcon from '../../Icons/GridIcon.jsx'
|
||||||
import useViewMode from '../hooks/useViewMode.jsx'
|
import useViewMode from '../hooks/useViewMode.jsx'
|
||||||
import ObjectTableViewButton from '../common/ObjectTableViewButton'
|
|
||||||
import FilterSidebarButton from '../common/FilterSidebarButton'
|
|
||||||
import ColumnViewButton from '../common/ColumnViewButton.jsx'
|
import ColumnViewButton from '../common/ColumnViewButton.jsx'
|
||||||
import useFilterSidebarVisibility from '../hooks/useFilterSidebarVisibility.jsx'
|
|
||||||
import ExportListButton from '../common/ExportListButton.jsx'
|
|
||||||
|
|
||||||
const SubJobs = () => {
|
const SubJobs = () => {
|
||||||
const tableRef = useRef()
|
const tableRef = useRef()
|
||||||
@ -18,9 +16,6 @@ const SubJobs = () => {
|
|||||||
|
|
||||||
const [columnVisibility, setColumnVisibility] = useColumnVisibility('subJob')
|
const [columnVisibility, setColumnVisibility] = useColumnVisibility('subJob')
|
||||||
|
|
||||||
const [showFilterSidebar, setShowFilterSidebar] =
|
|
||||||
useFilterSidebarVisibility('SubJobs')
|
|
||||||
|
|
||||||
const actionItems = {
|
const actionItems = {
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -38,7 +33,7 @@ const SubJobs = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex vertical={'true'} gap='large' className='h-100'>
|
<Flex vertical={'true'} gap='large' style={{ height: '100%' }}>
|
||||||
<Flex justify={'space-between'}>
|
<Flex justify={'space-between'}>
|
||||||
<Space size='small'>
|
<Space size='small'>
|
||||||
<Dropdown menu={actionItems}>
|
<Dropdown menu={actionItems}>
|
||||||
@ -50,17 +45,14 @@ const SubJobs = () => {
|
|||||||
visibleState={columnVisibility}
|
visibleState={columnVisibility}
|
||||||
updateVisibleState={setColumnVisibility}
|
updateVisibleState={setColumnVisibility}
|
||||||
/>
|
/>
|
||||||
<ExportListButton objectType='subJob' />
|
|
||||||
</Space>
|
</Space>
|
||||||
|
|
||||||
<Space>
|
<Space>
|
||||||
<FilterSidebarButton
|
<Button
|
||||||
active={showFilterSidebar}
|
icon={viewMode === 'cards' ? <ListIcon /> : <GridIcon />}
|
||||||
onClick={() => setShowFilterSidebar(!showFilterSidebar)}
|
onClick={() =>
|
||||||
/>
|
setViewMode(viewMode === 'cards' ? 'list' : 'cards')
|
||||||
<ObjectTableViewButton
|
}
|
||||||
viewMode={viewMode}
|
|
||||||
setViewMode={setViewMode}
|
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -70,7 +62,6 @@ const SubJobs = () => {
|
|||||||
type={'subJob'}
|
type={'subJob'}
|
||||||
visibleColumns={columnVisibility}
|
visibleColumns={columnVisibility}
|
||||||
cards={viewMode === 'cards'}
|
cards={viewMode === 'cards'}
|
||||||
showFilterSidebar={showFilterSidebar}
|
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
</>
|
</>
|
||||||
|
|||||||