Initial commit

This commit is contained in:
John Wang
2023-05-15 08:51:32 +08:00
commit db896255d6
744 changed files with 56028 additions and 0 deletions

View File

@@ -0,0 +1,16 @@
<svg width="464" height="180" viewBox="0 0 464 180" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="464" height="180" rx="12" fill="#F9FAFB"/>
<rect y="6" width="464" height="8" rx="3" fill="#EAECF0"/>
<rect y="26" width="464" height="8" rx="3" fill="#EAECF0"/>
<rect y="46" width="464" height="8" rx="3" fill="#EAECF0"/>
<rect y="66" width="464" height="8" rx="3" fill="#EAECF0"/>
<rect y="86" width="464" height="8" rx="3" fill="#EAECF0"/>
<rect y="106" width="256" height="8" rx="3" fill="#EAECF0"/>
<path d="M0 60H464V168C464 174.627 458.627 180 452 180H12C5.3726 180 0 174.627 0 168V60Z" fill="url(#paint0_linear_2131_10881)"/>
<defs>
<linearGradient id="paint0_linear_2131_10881" x1="232" y1="60" x2="232" y2="180" gradientUnits="userSpaceOnUse">
<stop stop-color="#FCFCFD" stop-opacity="0"/>
<stop offset="0.741486" stop-color="#FCFCFD"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 892 B

View File

@@ -0,0 +1,3 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.40616 0.834307C6.14751 0.719294 5.85222 0.719294 5.59356 0.834307C5.3938 0.923133 5.26403 1.07959 5.17373 1.20708C5.08495 1.33242 4.9899 1.49664 4.88536 1.67723L0.751783 8.81705C0.646828 8.9983 0.551451 9.16302 0.486781 9.3028C0.421056 9.44487 0.349754 9.63584 0.372478 9.85381C0.401884 10.1359 0.549654 10.3922 0.779012 10.5589C0.956259 10.6878 1.15726 10.7218 1.31314 10.7361C1.46651 10.7501 1.65684 10.7501 1.86628 10.7501H10.1334C10.3429 10.7501 10.5332 10.7501 10.6866 10.7361C10.8425 10.7218 11.0435 10.6878 11.2207 10.5589C11.4501 10.3922 11.5978 10.1359 11.6272 9.85381C11.65 9.63584 11.5787 9.44487 11.5129 9.3028C11.4483 9.16303 11.3529 8.99833 11.248 8.81709L7.11436 1.67722C7.00983 1.49663 6.91477 1.33242 6.82599 1.20708C6.73569 1.07959 6.60593 0.923133 6.40616 0.834307ZM6.49988 4.50012C6.49988 4.22398 6.27602 4.00012 5.99988 4.00012C5.72374 4.00012 5.49988 4.22398 5.49988 4.50012V6.50012C5.49988 6.77626 5.72374 7.00012 5.99988 7.00012C6.27602 7.00012 6.49988 6.77626 6.49988 6.50012V4.50012ZM5.99988 8.00012C5.72374 8.00012 5.49988 8.22398 5.49988 8.50012C5.49988 8.77626 5.72374 9.00012 5.99988 9.00012H6.00488C6.28102 9.00012 6.50488 8.77626 6.50488 8.50012C6.50488 8.22398 6.28102 8.00012 6.00488 8.00012H5.99988Z" fill="#F79009"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.2413 2H7.7587C6.95374 1.99999 6.28937 1.99998 5.74818 2.04419C5.18608 2.09012 4.66937 2.18868 4.18404 2.43598C3.43139 2.81947 2.81947 3.43139 2.43598 4.18404C2.18868 4.66937 2.09012 5.18608 2.04419 5.74818C1.99998 6.28937 1.99999 6.95372 2 7.75869V13.5343C1.99999 14.2041 1.99999 14.7569 2.03087 15.2095C2.06289 15.6788 2.13142 16.1129 2.30448 16.5307C2.71046 17.5108 3.48916 18.2895 4.46927 18.6955C4.88708 18.8686 5.32118 18.9371 5.79046 18.9691C6.24307 19 6.79594 19 7.46573 19H7.5C8.03656 19 8.14307 19.0063 8.22975 19.0268C8.38085 19.0624 8.52156 19.1328 8.64075 19.2322C8.70913 19.2893 8.77806 19.3708 9.1 19.8L10.5769 21.7692C10.6703 21.8938 10.7758 22.0346 10.8774 22.1476C10.9894 22.2721 11.1756 22.4555 11.4563 22.5647C11.806 22.7007 12.194 22.7007 12.5437 22.5647C12.8244 22.4555 13.0106 22.2721 13.1226 22.1476C13.2242 22.0346 13.3297 21.8938 13.4231 21.7692L14.9 19.8C15.2219 19.3708 15.2909 19.2893 15.3593 19.2322C15.4784 19.1328 15.6192 19.0624 15.7702 19.0268C15.8569 19.0063 15.9634 19 16.5 19H16.5343C17.2041 19 17.7569 19 18.2095 18.9691C18.6788 18.9371 19.1129 18.8686 19.5307 18.6955C20.5108 18.2895 21.2895 17.5108 21.6955 16.5307C21.8686 16.1129 21.9371 15.6788 21.9691 15.2095C22 14.7569 22 14.2041 22 13.5343V7.75868C22 6.95372 22 6.28937 21.9558 5.74818C21.9099 5.18608 21.8113 4.66937 21.564 4.18404C21.1805 3.43139 20.5686 2.81947 19.816 2.43598C19.3306 2.18868 18.8139 2.09012 18.2518 2.04419C17.7106 1.99998 17.0463 1.99999 16.2413 2ZM12 6C11.4477 6 11 6.44772 11 7C11 7.55229 11.4477 8 12 8H12.01C12.5623 8 13.01 7.55229 13.01 7C13.01 6.44772 12.5623 6 12.01 6H12ZM13 10.5C13 9.94772 12.5523 9.5 12 9.5C11.4477 9.5 11 9.94772 11 10.5V14C11 14.5523 11.4477 15 12 15C12.5523 15 13 14.5523 13 14V10.5Z" fill="#155EEF"/>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.3332 8H2.6665M2.6665 8L6.6665 12M2.6665 8L6.6665 4" stroke="#155EEF" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 253 B

View File

@@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.12" d="M1.33337 4.13333C1.33337 3.3866 1.33337 3.01323 1.4787 2.72801C1.60653 2.47713 1.8105 2.27316 2.06139 2.14532C2.3466 2 2.71997 2 3.46671 2H3.73337C5.22685 2 5.97358 2 6.54401 2.29065C7.04578 2.54631 7.45373 2.95426 7.70939 3.45603C8.00004 4.02646 8.00004 4.77319 8.00004 6.26667V14L7.93334 13.8999C7.47024 13.2053 7.2387 12.858 6.93277 12.6065C6.66195 12.3839 6.34988 12.2169 6.01444 12.1151C5.63554 12 5.21811 12 4.38326 12H3.46671C2.71997 12 2.3466 12 2.06139 11.8547C1.8105 11.7268 1.60653 11.5229 1.4787 11.272C1.33337 10.9868 1.33337 10.6134 1.33337 9.86667V4.13333Z" fill="#155EEF"/>
<path d="M8.00004 14L7.93334 13.8999C7.47024 13.2053 7.2387 12.858 6.93278 12.6065C6.66195 12.3839 6.34988 12.2169 6.01444 12.1151C5.63554 12 5.21811 12 4.38326 12H3.46671C2.71997 12 2.3466 12 2.06139 11.8547C1.8105 11.7268 1.60653 11.5229 1.4787 11.272C1.33337 10.9868 1.33337 10.6134 1.33337 9.86667V4.13333C1.33337 3.3866 1.33337 3.01323 1.4787 2.72801C1.60653 2.47713 1.8105 2.27316 2.06139 2.14532C2.3466 2 2.71997 2 3.46671 2H3.73337C5.22685 2 5.97358 2 6.54402 2.29065C7.04578 2.54631 7.45373 2.95426 7.70939 3.45603C8.00004 4.02646 8.00004 4.77319 8.00004 6.26667M8.00004 14V6.26667M8.00004 14L8.06674 13.8999C8.52984 13.2053 8.76139 12.858 9.06731 12.6065C9.33814 12.3839 9.6502 12.2169 9.98564 12.1151C10.3645 12 10.782 12 11.6168 12H12.5334C13.2801 12 13.6535 12 13.9387 11.8547C14.1896 11.7268 14.3936 11.5229 14.5214 11.272C14.6667 10.9868 14.6667 10.6134 14.6667 9.86667V4.13333C14.6667 3.3866 14.6667 3.01323 14.5214 2.72801C14.3936 2.47713 14.1896 2.27316 13.9387 2.14532C13.6535 2 13.2801 2 12.5334 2H12.2667C10.7732 2 10.0265 2 9.45607 2.29065C8.9543 2.54631 8.54635 2.95426 8.29069 3.45603C8.00004 4.02646 8.00004 4.77319 8.00004 6.26667" stroke="#155EEF" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1,3 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10 3L4.5 8.5L2 6" stroke="#667085" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 216 B

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 4L4 12M4 4L12 12" stroke="#667085" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 219 B

View File

@@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.66667 1.34356C8.66667 1.32602 8.66667 1.31725 8.66591 1.30135C8.65018 0.972168 8.3607 0.682824 8.03151 0.667251C8.01562 0.666499 8.0104 0.666501 8.00001 0.666504H5.8391C5.30248 0.666497 4.85957 0.666491 4.49878 0.695968C4.12405 0.726585 3.77958 0.792295 3.45603 0.957155C2.95426 1.21282 2.54631 1.62077 2.29065 2.12253C2.12579 2.44609 2.06008 2.79056 2.02946 3.16529C1.99999 3.52608 1.99999 3.96899 2 4.50562V11.494C1.99999 12.0307 1.99999 12.4736 2.02946 12.8344C2.06008 13.2091 2.12579 13.5536 2.29065 13.8771C2.54631 14.3789 2.95426 14.7869 3.45603 15.0425C3.77958 15.2074 4.12405 15.2731 4.49878 15.3037C4.85958 15.3332 5.30248 15.3332 5.83912 15.3332H10.1609C10.6975 15.3332 11.1404 15.3332 11.5012 15.3037C11.8759 15.2731 12.2204 15.2074 12.544 15.0425C13.0457 14.7869 13.4537 14.3789 13.7093 13.8771C13.8742 13.5536 13.9399 13.2091 13.9705 12.8344C14 12.4736 14 12.0307 14 11.4941V6.66646C14 6.65611 14 6.65093 13.9993 6.63505C13.9837 6.30583 13.6943 6.01631 13.3651 6.0006C13.3492 5.99985 13.3405 5.99985 13.323 5.99985L10.3787 5.99985C10.2105 5.99987 10.0466 5.99989 9.90785 5.98855C9.75545 5.9761 9.57563 5.94672 9.39468 5.85452C9.1438 5.72669 8.93983 5.52272 8.81199 5.27183C8.7198 5.09088 8.69042 4.91106 8.67797 4.75867C8.66663 4.61989 8.66665 4.45603 8.66667 4.28778L8.66667 1.34356ZM5.33333 8.6665C4.96514 8.6665 4.66667 8.96498 4.66667 9.33317C4.66667 9.70136 4.96514 9.99984 5.33333 9.99984H10.6667C11.0349 9.99984 11.3333 9.70136 11.3333 9.33317C11.3333 8.96498 11.0349 8.6665 10.6667 8.6665H5.33333ZM5.33333 11.3332C4.96514 11.3332 4.66667 11.6316 4.66667 11.9998C4.66667 12.368 4.96514 12.6665 5.33333 12.6665H9.33333C9.70152 12.6665 10 12.368 10 11.9998C10 11.6316 9.70152 11.3332 9.33333 11.3332H5.33333Z" fill="#444CE7"/>
<path d="M12.6053 4.6665C12.8011 4.6665 12.8989 4.6665 12.9791 4.61735C13.0923 4.54794 13.16 4.3844 13.129 4.25526C13.107 4.16382 13.0432 4.10006 12.9155 3.97253L10.694 1.75098C10.5664 1.62333 10.5027 1.5595 10.4112 1.53752C10.2821 1.50648 10.1186 1.57417 10.0492 1.6874C10 1.76757 10 1.86545 10 2.0612L10 4.13315C10 4.31982 10 4.41316 10.0363 4.48446C10.0683 4.54718 10.1193 4.59818 10.182 4.63014C10.2533 4.66647 10.3466 4.66647 10.5333 4.66647L12.6053 4.6665Z" fill="#444CE7"/>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.66683 4.66667L7.92314 3.17928C7.7091 2.7512 7.60207 2.53715 7.44241 2.38078C7.30122 2.24249 7.13105 2.13732 6.94421 2.07287C6.73294 2 6.49363 2 6.01502 2H3.46683C2.72009 2 2.34672 2 2.06151 2.14532C1.81063 2.27316 1.60665 2.47713 1.47882 2.72801C1.3335 3.01323 1.3335 3.3866 1.3335 4.13333V4.66667M1.3335 4.66667H11.4668C12.5869 4.66667 13.147 4.66667 13.5748 4.88465C13.9511 5.0764 14.2571 5.38236 14.4488 5.75869C14.6668 6.18651 14.6668 6.74656 14.6668 7.86667V10.8C14.6668 11.9201 14.6668 12.4802 14.4488 12.908C14.2571 13.2843 13.9511 13.5903 13.5748 13.782C13.147 14 12.5869 14 11.4668 14H4.5335C3.41339 14 2.85334 14 2.42552 13.782C2.04919 13.5903 1.74323 13.2843 1.55148 12.908C1.3335 12.4802 1.3335 11.9201 1.3335 10.8V4.66667ZM8.00016 11.3333V7.33333M6.00016 9.33333H10.0002" stroke="#155EEF" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 985 B

View File

@@ -0,0 +1,23 @@
<svg width="32" height="34" viewBox="0 0 32 34" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d_3055_14424)">
<path d="M4 7.73349C4 5.49329 4 4.37318 4.43597 3.51753C4.81947 2.76489 5.43139 2.15296 6.18404 1.76947C7.03969 1.3335 8.15979 1.3335 10.4 1.3335H18.6667L28 10.6668V24.2668C28 26.507 28 27.6271 27.564 28.4828C27.1805 29.2354 26.5686 29.8474 25.816 30.2309C24.9603 30.6668 23.8402 30.6668 21.6 30.6668H10.4C8.15979 30.6668 7.03969 30.6668 6.18404 30.2309C5.43139 29.8474 4.81947 29.2354 4.43597 28.4828C4 27.6271 4 26.507 4 24.2668V7.73349Z" fill="#EC5B27"/>
</g>
<g opacity="0.96">
<path d="M10.2704 24.0002V18.3042H8.87042V20.4962H7.38242V18.3042H5.98242V24.0002H7.38242V21.7442H8.87042V24.0002H10.2704Z" fill="white"/>
<path d="M15.2839 19.5522V18.3042H11.0839V19.5522H12.4839V24.0002H13.8839V19.5522H15.2839Z" fill="white"/>
<path d="M21.4116 24.0002V18.3042H20.0356L18.7556 20.8162L17.4756 18.3042H16.0996V24.0002H17.4996V21.2722L18.3076 22.6802H19.2036L20.0116 21.2722V24.0002H21.4116Z" fill="white"/>
<path d="M26.3525 24.0002V22.7522H23.9605V18.3042H22.5605V24.0002H26.3525Z" fill="white"/>
</g>
<path opacity="0.5" d="M18.6665 1.3335L27.9998 10.6668H21.3332C19.8604 10.6668 18.6665 9.47292 18.6665 8.00016V1.3335Z" fill="white"/>
<defs>
<filter id="filter0_d_3055_14424" x="2" y="0.333496" width="28" height="33.3335" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="1"/>
<feGaussianBlur stdDeviation="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.0627451 0 0 0 0 0.0941176 0 0 0 0 0.156863 0 0 0 0.05 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_3055_14424"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_3055_14424" result="shape"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1,23 @@
<svg width="32" height="34" viewBox="0 0 32 34" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d_3055_14428)">
<path d="M4 7.73349C4 5.49329 4 4.37318 4.43597 3.51753C4.81947 2.76489 5.43139 2.15296 6.18404 1.76947C7.03969 1.3335 8.15979 1.3335 10.4 1.3335H18.6667L28 10.6668V24.2668C28 26.507 28 27.6271 27.564 28.4828C27.1805 29.2354 26.5686 29.8474 25.816 30.2309C24.9603 30.6668 23.8402 30.6668 21.6 30.6668H10.4C8.15979 30.6668 7.03969 30.6668 6.18404 30.2309C5.43139 29.8474 4.81947 29.2354 4.43597 28.4828C4 27.6271 4 26.507 4 24.2668V7.73349Z" fill="#2D2D2E"/>
</g>
<g opacity="0.96">
<path d="M9.83907 22.0479V18.3039H8.43907V22.0159C8.43907 22.5599 8.12707 22.7999 7.69507 22.7999C7.38307 22.7999 7.23907 22.6879 7.06307 22.5119L6.14307 23.4239C6.60707 23.8879 7.03107 24.0479 7.69507 24.0479C8.76707 24.0479 9.83907 23.3999 9.83907 22.0479Z" fill="white"/>
<path d="M14.7321 22.2559C14.7321 21.7279 14.6121 21.3039 14.3081 21.0079C14.0681 20.7679 13.7001 20.6079 13.1881 20.5359L12.5001 20.4399C12.3001 20.4159 12.1801 20.3439 12.1081 20.2719C12.0201 20.1839 11.9961 20.0799 11.9961 20.0079C11.9961 19.7599 12.1961 19.4799 12.6841 19.4799C12.9321 19.4799 13.4041 19.4559 13.7641 19.8159L14.6441 18.9359C14.1561 18.4479 13.5401 18.2559 12.7241 18.2559C11.4281 18.2559 10.6441 19.0159 10.6441 20.0559C10.6441 20.5439 10.7721 20.9279 11.0361 21.1999C11.2921 21.4639 11.6761 21.6319 12.1801 21.7039L12.8681 21.7999C13.0521 21.8239 13.1721 21.8799 13.2441 21.9519C13.3241 22.0399 13.3561 22.1519 13.3561 22.2879C13.3561 22.6159 13.0921 22.7999 12.5401 22.7999C12.0841 22.7999 11.5641 22.6959 11.2681 22.3999L10.3721 23.2959C10.9481 23.8879 11.6601 24.0479 12.5321 24.0479C13.7321 24.0479 14.7321 23.4159 14.7321 22.2559Z" fill="white"/>
<path d="M19.8023 21.1519C19.8023 20.2959 19.8263 19.4959 19.2263 18.8959C18.8103 18.4799 18.3303 18.2559 17.6343 18.2559C16.9383 18.2559 16.4583 18.4799 16.0423 18.8959C15.4423 19.4959 15.4663 20.2959 15.4663 21.1519C15.4663 22.0079 15.4423 22.8079 16.0423 23.4079C16.4583 23.8239 16.9383 24.0479 17.6343 24.0479C18.3303 24.0479 18.8103 23.8239 19.2263 23.4079C19.8263 22.8079 19.8023 22.0079 19.8023 21.1519ZM18.4023 21.1519C18.4023 22.1919 18.3223 22.3759 18.1943 22.5439C18.0903 22.6799 17.8903 22.7999 17.6343 22.7999C17.3783 22.7999 17.1783 22.6799 17.0743 22.5439C16.9463 22.3759 16.8663 22.1919 16.8663 21.1519C16.8663 20.1119 16.9463 19.9199 17.0743 19.7519C17.1783 19.6159 17.3783 19.5039 17.6343 19.5039C17.8903 19.5039 18.0903 19.6159 18.1943 19.7519C18.3223 19.9199 18.4023 20.1119 18.4023 21.1519Z" fill="white"/>
<path d="M25.2154 23.9999V18.3039H23.8154V21.1679L21.9914 18.3039H20.7674V23.9999H22.1674V21.1359L23.9914 23.9999H25.2154Z" fill="white"/>
</g>
<path opacity="0.5" d="M18.6665 1.3335L27.9998 10.6668H21.3332C19.8604 10.6668 18.6665 9.47292 18.6665 8.00016V1.3335Z" fill="white"/>
<defs>
<filter id="filter0_d_3055_14428" x="2" y="0.333496" width="28" height="33.3335" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="1"/>
<feGaussianBlur stdDeviation="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.0627451 0 0 0 0 0.0941176 0 0 0 0 0.156863 0 0 0 0.05 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_3055_14428"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_3055_14428" result="shape"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -0,0 +1,18 @@
<svg width="32" height="34" viewBox="0 0 32 34" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d_3777_37339)">
<path d="M4 7.73349C4 5.49329 4 4.37318 4.43597 3.51753C4.81947 2.76489 5.43139 2.15296 6.18404 1.76947C7.03969 1.3335 8.15979 1.3335 10.4 1.3335H18.6667L28 10.6668V24.2668C28 26.507 28 27.6271 27.564 28.4828C27.1805 29.2354 26.5686 29.8474 25.816 30.2309C24.9603 30.6668 23.8402 30.6668 21.6 30.6668H10.4C8.15979 30.6668 7.03969 30.6668 6.18404 30.2309C5.43139 29.8474 4.81947 29.2354 4.43597 28.4828C4 27.6271 4 26.507 4 24.2668V7.73349Z" fill="#309BEC"/>
</g>
<path fill-rule="evenodd" clip-rule="evenodd" d="M21.9904 25.3335H10.0096C9.45202 25.3335 9 24.9138 9 24.396V18.271C9 17.7532 9.45202 17.3335 10.0096 17.3335H21.9904C22.548 17.3335 23 17.7532 23 18.271V24.396C23 24.9138 22.548 25.3335 21.9904 25.3335ZM12.3654 23.4585V21.021L13.7115 22.5835L15.0577 21.021V23.4585H16.4038V19.2085H15.0577L13.7115 20.771L12.3654 19.2085H11.0192V23.4585H12.3654ZM20.0385 21.3335H21.3846L19.3654 23.521L17.3462 21.3335H18.6923V19.2085H20.0385V21.3335Z" fill="white"/>
<path opacity="0.5" d="M18.6665 1.3335L27.9998 10.6668H21.3332C19.8604 10.6668 18.6665 9.47292 18.6665 8.00016V1.3335Z" fill="white"/>
<defs>
<filter id="filter0_d_3777_37339" x="2" y="0.333496" width="28" height="33.3335" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="1"/>
<feGaussianBlur stdDeviation="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.0627451 0 0 0 0 0.0941176 0 0 0 0 0.156863 0 0 0 0.05 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_3777_37339"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_3777_37339" result="shape"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1,12 @@
<svg width="21" height="20" viewBox="0 0 21 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_2942_529)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.90599 18.2611L1.75639 15.5832C1.2392 14.9389 0.958496 14.1466 0.958496 13.3312V3.63437C0.958496 2.4129 1.93574 1.39936 3.19644 1.31328L13.1661 0.632614C13.8904 0.583164 14.6103 0.775682 15.2052 1.17794L18.708 3.5462C19.335 3.97012 19.7085 4.66312 19.7085 5.40266V16.427C19.7085 17.6223 18.7476 18.6121 17.5133 18.688L6.44808 19.3692C5.46308 19.4298 4.51099 19.0148 3.90599 18.2611Z" fill="white"/>
<path d="M7.36355 8.48663V8.35968C7.36355 8.03787 7.62129 7.77098 7.95347 7.7488L10.3731 7.58726L13.7191 12.5146V8.19003L12.8579 8.07522V8.01492C12.8579 7.68933 13.1215 7.42068 13.4579 7.40344L15.6595 7.29066V7.60749C15.6595 7.75622 15.5489 7.88343 15.3973 7.90907L14.8675 7.99868V15.0022L14.2026 15.2309C13.6471 15.4219 13.0287 15.2174 12.7107 14.7376L9.46228 9.83568V14.5143L10.4622 14.7056L10.4482 14.7984C10.4046 15.0889 10.1538 15.3086 9.85036 15.3221L7.36355 15.4328C7.33068 15.1204 7.56481 14.8409 7.88781 14.807L8.21492 14.7726V8.53447L7.36355 8.48663Z" fill="black"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.2553 1.85418L3.28567 2.53485C2.68849 2.57562 2.22559 3.05572 2.22559 3.63431V13.3311C2.22559 13.8748 2.41272 14.4029 2.75752 14.8325L4.90712 17.5104C5.25467 17.9433 5.80161 18.1817 6.36747 18.1469L17.4326 17.4658C17.9998 17.4309 18.4413 16.9761 18.4413 16.4269V5.4026C18.4413 5.06281 18.2697 4.74441 17.9816 4.54963L14.4788 2.18137C14.1218 1.94002 13.6899 1.82451 13.2553 1.85418ZM3.78004 3.78556C3.64138 3.6829 3.70737 3.46903 3.88156 3.45654L13.3224 2.77938C13.6232 2.75781 13.9221 2.84064 14.1653 3.01299L16.0595 4.35502C16.1315 4.40597 16.0977 4.51596 16.0087 4.5208L6.01092 5.06454C5.70835 5.081 5.4097 4.99211 5.16913 4.814L3.78004 3.78556ZM5.54198 6.76913C5.54198 6.44433 5.80438 6.17604 6.13991 6.15777L16.7104 5.5821C17.0374 5.56429 17.3127 5.81577 17.3127 6.13232V15.6782C17.3127 16.0024 17.0512 16.2705 16.7164 16.2895L6.2128 16.8871C5.84887 16.9079 5.54198 16.6282 5.54198 16.2759V6.76913Z" fill="black"/>
</g>
<defs>
<clipPath id="clip0_2942_529">
<rect width="20" height="20" fill="white" transform="translate(0.333496)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -0,0 +1,22 @@
<svg width="32" height="34" viewBox="0 0 32 34" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d_3055_14420)">
<path d="M4 7.73349C4 5.49329 4 4.37318 4.43597 3.51753C4.81947 2.76489 5.43139 2.15296 6.18404 1.76947C7.03969 1.3335 8.15979 1.3335 10.4 1.3335H18.6667L28 10.6668V24.2668C28 26.507 28 27.6271 27.564 28.4828C27.1805 29.2354 26.5686 29.8474 25.816 30.2309C24.9603 30.6668 23.8402 30.6668 21.6 30.6668H10.4C8.15979 30.6668 7.03969 30.6668 6.18404 30.2309C5.43139 29.8474 4.81947 29.2354 4.43597 28.4828C4 27.6271 4 26.507 4 24.2668V7.73349Z" fill="#DD3633"/>
</g>
<g opacity="0.96">
<path d="M13.2801 20.1362C13.2801 19.2002 12.6001 18.3042 11.3361 18.3042H9.08008V24.0002H10.4801V21.9682H11.3361C12.6001 21.9682 13.2801 21.0722 13.2801 20.1362ZM11.8801 20.1362C11.8801 20.4322 11.6561 20.7122 11.2721 20.7122H10.4801V19.5602H11.2721C11.6561 19.5602 11.8801 19.8402 11.8801 20.1362Z" fill="white"/>
<path d="M18.3357 21.1522C18.3357 20.2562 18.4077 19.5282 17.7437 18.8642C17.3517 18.4722 16.7997 18.3042 16.2077 18.3042H14.0957V24.0002H16.2077C16.7997 24.0002 17.3517 23.8322 17.7437 23.4402C18.4077 22.7762 18.3357 22.0482 18.3357 21.1522ZM16.9357 21.1522C16.9357 22.1202 16.8957 22.2722 16.7837 22.4322C16.6557 22.6242 16.4637 22.7522 16.1117 22.7522H15.4957V19.5522H16.1117C16.4637 19.5522 16.6557 19.6802 16.7837 19.8722C16.8957 20.0322 16.9357 20.1922 16.9357 21.1522Z" fill="white"/>
<path d="M23.1786 19.5522V18.3042H19.3066V24.0002H20.7066V21.8002H22.8186V20.5522H20.7066V19.5522H23.1786Z" fill="white"/>
</g>
<path opacity="0.5" d="M18.6665 1.3335L27.9998 10.6668H21.3332C19.8604 10.6668 18.6665 9.47292 18.6665 8.00016V1.3335Z" fill="white"/>
<defs>
<filter id="filter0_d_3055_14420" x="2" y="0.333496" width="28" height="33.3335" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="1"/>
<feGaussianBlur stdDeviation="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.0627451 0 0 0 0 0.0941176 0 0 0 0 0.156863 0 0 0 0.05 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_3055_14420"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_3055_14420" result="shape"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7.66675 6.00004C8.95541 6.00004 10.0001 4.95537 10.0001 3.66671C10.0001 2.37804 8.95541 1.33337 7.66675 1.33337C6.37808 1.33337 5.33341 2.37804 5.33341 3.66671C5.33341 4.95537 6.37808 6.00004 7.66675 6.00004Z" fill="#444CE7"/>
<path d="M4.65042 5.75205C4.49131 5.52233 4.41175 5.40747 4.32605 5.36953C4.24913 5.33547 4.16814 5.3313 4.08813 5.35729C3.99899 5.38624 3.92889 5.46803 3.78869 5.6316C3.22609 6.28801 2.84238 7.10277 2.71398 8.00016H2.66675C2.29856 8.00016 2.00008 7.70168 2.00008 7.33349C2.00008 7.08757 2.13289 6.87188 2.3339 6.75561C2.65261 6.57125 2.76151 6.16343 2.57715 5.84472C2.39279 5.52601 1.98497 5.4171 1.66626 5.60147C1.0702 5.94627 0.666748 6.59237 0.666748 7.33349C0.666748 8.43806 1.56218 9.33349 2.66675 9.33349H2.71402C2.85798 10.339 3.32264 11.2416 4.00004 11.9329L4.00004 13.4823C4.00001 13.5617 3.99997 13.6565 4.0068 13.7401C4.01471 13.8369 4.035 13.9756 4.10903 14.1209C4.20491 14.309 4.35789 14.462 4.54605 14.5579C4.69135 14.6319 4.83001 14.6522 4.92682 14.6601C5.01034 14.6669 5.10517 14.6669 5.18456 14.6669H6.48214C6.56153 14.6669 6.6564 14.6669 6.73993 14.6601C6.83674 14.6522 6.9754 14.6319 7.1207 14.5579C7.30886 14.462 7.46184 14.309 7.55771 14.1209C7.63175 13.9756 7.65204 13.8369 7.65995 13.7401C7.66678 13.6565 7.66674 13.5617 7.66671 13.4823L7.66671 13.3335H8.33338L8.33338 13.482C8.33335 13.5615 8.33331 13.6563 8.34014 13.7398C8.34805 13.8366 8.36834 13.9753 8.44238 14.1206C8.53825 14.3088 8.69123 14.4618 8.87939 14.5576C9.02469 14.6317 9.16335 14.652 9.26016 14.6599C9.34368 14.6667 9.43849 14.6667 9.51788 14.6666H10.8155C10.8949 14.6667 10.9898 14.6667 11.0733 14.6599C11.1701 14.652 11.3088 14.6317 11.4541 14.5576C11.6422 14.4618 11.7952 14.3088 11.8911 14.1206C11.9651 13.9753 11.9854 13.8366 11.9933 13.7398C12.0002 13.6563 12.0001 13.5615 12.0001 13.482L12.0001 12.884C12.7376 12.5338 13.3679 11.9963 13.8302 11.3333L14.1488 11.3333C14.2283 11.3333 14.3231 11.3334 14.4066 11.3265C14.5035 11.3186 14.6421 11.2983 14.7874 11.2243C14.9756 11.1284 15.1286 10.9754 15.2244 10.7873C15.2985 10.642 15.3188 10.5033 15.3267 10.4065C15.3335 10.323 15.3335 10.2282 15.3334 10.1488V7.84245C15.3335 7.76683 15.3335 7.67651 15.3273 7.59685C15.3201 7.50472 15.3017 7.37257 15.2344 7.23269C15.1361 7.02862 14.9714 6.86396 14.7674 6.76567C14.6275 6.6983 14.4953 6.67993 14.4032 6.67276C14.3437 6.66813 14.2783 6.66697 14.2175 6.66669C13.9938 6.19554 13.6937 5.76825 13.3334 5.40063L13.3334 4.68824C13.3335 4.58502 13.3335 4.46819 13.3245 4.36769C13.3147 4.25673 13.2888 4.08518 13.1835 3.91515C13.0521 3.70315 12.8463 3.54789 12.6064 3.47982C12.4139 3.42523 12.2419 3.44753 12.1325 3.4685C12.0334 3.48749 11.921 3.51963 11.8218 3.54801L11.7179 3.57769C11.5813 3.61674 11.513 3.63626 11.4649 3.67145C11.4185 3.70542 11.3901 3.73891 11.3642 3.79026C11.3374 3.84344 11.3281 3.92456 11.3096 4.08678C11.1012 5.91399 9.54973 7.33337 7.66675 7.33337C6.41642 7.33337 5.31225 6.70755 4.65042 5.75205Z" fill="#444CE7"/>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -0,0 +1,8 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1.33325 12.6666C1.33325 12.2984 1.63173 12 1.99992 12H4.66659C5.03478 12 5.33325 12.2984 5.33325 12.6666C5.33325 13.0348 5.03478 13.3333 4.66659 13.3333H1.99992C1.63173 13.3333 1.33325 13.0348 1.33325 12.6666Z" fill="#155EEF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.5528 12C10.2782 11.2232 9.5374 10.6666 8.66659 10.6666C7.56202 10.6666 6.66659 11.5621 6.66659 12.6666C6.66659 13.7712 7.56202 14.6666 8.66659 14.6666C9.5374 14.6666 10.2782 14.1101 10.5528 13.3333L13.9999 13.3333C14.3681 13.3333 14.6666 13.0348 14.6666 12.6666C14.6666 12.2984 14.3681 12 13.9999 12L10.5528 12Z" fill="#155EEF"/>
<path d="M9.99992 7.33329C9.63173 7.33329 9.33325 7.63177 9.33325 7.99996C9.33325 8.36815 9.63173 8.66663 9.99992 8.66663H13.9999C14.3681 8.66663 14.6666 8.36815 14.6666 7.99996C14.6666 7.63177 14.3681 7.33329 13.9999 7.33329H9.99992Z" fill="#155EEF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.33325 7.99996C1.33325 7.63177 1.63173 7.33329 1.99992 7.33329H4.11372C4.38828 6.5565 5.12911 5.99996 5.99992 5.99996C7.10449 5.99996 7.99992 6.89539 7.99992 7.99996C7.99992 9.10453 7.10449 9.99996 5.99992 9.99996C5.12911 9.99996 4.38828 9.44342 4.11372 8.66663H1.99992C1.63173 8.66663 1.33325 8.36815 1.33325 7.99996Z" fill="#155EEF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.99992 1.33329C10.8707 1.33329 11.6116 1.88983 11.8861 2.66663H13.9999C14.3681 2.66663 14.6666 2.9651 14.6666 3.33329C14.6666 3.70148 14.3681 3.99996 13.9999 3.99996H11.8861C11.6116 4.77675 10.8707 5.33329 9.99992 5.33329C8.89535 5.33329 7.99992 4.43786 7.99992 3.33329C7.99992 2.22872 8.89535 1.33329 9.99992 1.33329Z" fill="#155EEF"/>
<path d="M1.33325 3.33329C1.33325 2.9651 1.63173 2.66663 1.99992 2.66663H5.99992C6.36811 2.66663 6.66659 2.9651 6.66659 3.33329C6.66659 3.70148 6.36811 3.99996 5.99992 3.99996H1.99992C1.63173 3.99996 1.33325 3.70148 1.33325 3.33329Z" fill="#155EEF"/>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,11 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.00008 0.666626C8.36827 0.666626 8.66675 0.965103 8.66675 1.33329V2.66663C8.66675 3.03482 8.36827 3.33329 8.00008 3.33329C7.63189 3.33329 7.33341 3.03482 7.33341 2.66663V1.33329C7.33341 0.965103 7.63189 0.666626 8.00008 0.666626Z" fill="#FB6514"/>
<path d="M3.75729 2.81452C3.49694 2.55418 3.07483 2.55418 2.81448 2.81452C2.55413 3.07487 2.55413 3.49698 2.81448 3.75733L3.75729 4.70014C4.01764 4.96049 4.43975 4.96049 4.7001 4.70014C4.96045 4.43979 4.96045 4.01768 4.7001 3.75733L3.75729 2.81452Z" fill="#FB6514"/>
<path d="M0.666748 7.99996C0.666748 7.63177 0.965225 7.33329 1.33341 7.33329H2.66675C3.03494 7.33329 3.33341 7.63177 3.33341 7.99996C3.33341 8.36815 3.03494 8.66663 2.66675 8.66663H1.33341C0.965225 8.66663 0.666748 8.36815 0.666748 7.99996Z" fill="#FB6514"/>
<path d="M13.3334 7.33329C12.9652 7.33329 12.6667 7.63177 12.6667 7.99996C12.6667 8.36815 12.9652 8.66663 13.3334 8.66663H14.6667C15.0349 8.66663 15.3334 8.36815 15.3334 7.99996C15.3334 7.63177 15.0349 7.33329 14.6667 7.33329H13.3334Z" fill="#FB6514"/>
<path d="M12.2426 11.2997C11.9823 11.0394 11.5602 11.0394 11.2998 11.2997C11.0395 11.5601 11.0395 11.9822 11.2998 12.2425L12.2426 13.1853C12.503 13.4457 12.9251 13.4457 13.1855 13.1853C13.4458 12.925 13.4458 12.5029 13.1855 12.2425L12.2426 11.2997Z" fill="#FB6514"/>
<path d="M13.1855 3.75733C13.4458 3.49698 13.4458 3.07487 13.1855 2.81452C12.9251 2.55418 12.503 2.55418 12.2426 2.81452L11.2998 3.75733C11.0395 4.01768 11.0395 4.43979 11.2998 4.70014C11.5602 4.96049 11.9823 4.96049 12.2426 4.70014L13.1855 3.75733Z" fill="#FB6514"/>
<path d="M8.00008 12.6666C8.36827 12.6666 8.66675 12.9651 8.66675 13.3333V14.6666C8.66675 15.0348 8.36827 15.3333 8.00008 15.3333C7.63189 15.3333 7.33341 15.0348 7.33341 14.6666V13.3333C7.33341 12.9651 7.63189 12.6666 8.00008 12.6666Z" fill="#FB6514"/>
<path d="M4.7001 12.2425C4.96045 11.9822 4.96045 11.5601 4.7001 11.2997C4.43975 11.0394 4.01764 11.0394 3.75729 11.2997L2.81448 12.2425C2.55413 12.5029 2.55413 12.925 2.81448 13.1853C3.07483 13.4457 3.49694 13.4457 3.75729 13.1853L4.7001 12.2425Z" fill="#FB6514"/>
<path d="M8.59791 4.37154C8.48559 4.14401 8.25385 3.99996 8.0001 3.99996C7.74635 3.99996 7.51461 4.14401 7.4023 4.37154L6.52726 6.14427L4.57035 6.4303C4.31931 6.46699 4.11085 6.643 4.0326 6.88434C3.95435 7.12567 4.01987 7.39051 4.20161 7.56753L5.61709 8.9462L5.28303 10.8939C5.24013 11.1441 5.34296 11.3968 5.54828 11.546C5.7536 11.6951 6.02579 11.7148 6.2504 11.5967L8.0001 10.6765L9.7498 11.5967C9.97441 11.7148 10.2466 11.6951 10.4519 11.546C10.6572 11.3968 10.7601 11.1441 10.7172 10.8939L10.3831 8.9462L11.7986 7.56753C11.9803 7.39051 12.0458 7.12567 11.9676 6.88434C11.8893 6.643 11.6809 6.46699 11.4299 6.4303L9.47294 6.14427L8.59791 4.37154Z" fill="#FB6514"/>
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6 2H10M2 4H14M12.6667 4L12.1991 11.0129C12.129 12.065 12.0939 12.5911 11.8667 12.99C11.6666 13.3412 11.3648 13.6235 11.0011 13.7998C10.588 14 10.0607 14 9.00623 14H6.99377C5.93927 14 5.41202 14 4.99889 13.7998C4.63517 13.6235 4.33339 13.3412 4.13332 12.99C3.90607 12.5911 3.871 12.065 3.80086 11.0129L3.33333 4M6.66667 7V10.3333M9.33333 7V10.3333" stroke="#667085" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 546 B

View File

@@ -0,0 +1,23 @@
<svg width="32" height="34" viewBox="0 0 32 34" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d_3055_14432)">
<path d="M4 7.73349C4 5.49329 4 4.37318 4.43597 3.51753C4.81947 2.76489 5.43139 2.15296 6.18404 1.76947C7.03969 1.3335 8.15979 1.3335 10.4 1.3335H18.6667L28 10.6668V24.2668C28 26.507 28 27.6271 27.564 28.4828C27.1805 29.2354 26.5686 29.8474 25.816 30.2309C24.9603 30.6668 23.8402 30.6668 21.6 30.6668H10.4C8.15979 30.6668 7.03969 30.6668 6.18404 30.2309C5.43139 29.8474 4.81947 29.2354 4.43597 28.4828C4 27.6271 4 26.507 4 24.2668V7.73349Z" fill="#E3E5E8"/>
<path d="M4.25 7.73349C4.25 6.60926 4.25019 5.78113 4.30367 5.12666C4.3569 4.47511 4.46169 4.01774 4.65873 3.63103C5.01825 2.92542 5.59193 2.35175 6.29754 1.99222C6.68424 1.79518 7.14162 1.6904 7.79317 1.63716C8.44763 1.58369 9.27577 1.5835 10.4 1.5835H18.5631L27.75 10.7704V24.2668C27.75 25.3911 27.7498 26.2192 27.6963 26.8737C27.6431 27.5252 27.5383 27.9826 27.3413 28.3693C26.9817 29.0749 26.4081 29.6486 25.7025 30.0081C25.3158 30.2051 24.8584 30.3099 24.2068 30.3632C23.5524 30.4166 22.7242 30.4168 21.6 30.4168H10.4C9.27577 30.4168 8.44763 30.4166 7.79317 30.3632C7.14162 30.3099 6.68424 30.2051 6.29754 30.0081C5.59193 29.6486 5.01825 29.0749 4.65873 28.3693C4.46169 27.9826 4.3569 27.5252 4.30367 26.8737C4.25019 26.2192 4.25 25.3911 4.25 24.2668V7.73349Z" stroke="black" stroke-opacity="0.03" stroke-width="0.5"/>
</g>
<g opacity="0.96">
<path d="M13.2254 19.5522V18.3042H9.02539V19.5522H10.4254V24.0002H11.8254V19.5522H13.2254Z" fill="#667085"/>
<path d="M18.5371 24.0002L16.7611 21.0802L18.4251 18.3042H16.8331L16.0011 19.9122L15.1691 18.3042H13.5771L15.2411 21.0802L13.4651 24.0002H15.0651L16.0011 22.2482L16.9371 24.0002H18.5371Z" fill="#667085"/>
<path d="M22.9754 19.5522V18.3042H18.7754V19.5522H20.1754V24.0002H21.5754V19.5522H22.9754Z" fill="#667085"/>
</g>
<path opacity="0.5" d="M18.6665 1.3335L27.9998 10.6668H21.3332C19.8604 10.6668 18.6665 9.47292 18.6665 8.00016V1.3335Z" fill="white"/>
<defs>
<filter id="filter0_d_3055_14432" x="2" y="0.333496" width="28" height="33.3335" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="1"/>
<feGaussianBlur stdDeviation="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.0627451 0 0 0 0 0.0941176 0 0 0 0 0.156863 0 0 0 0.05 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_3055_14432"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_3055_14432" result="shape"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -0,0 +1,23 @@
<svg width="32" height="34" viewBox="0 0 32 34" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d_3055_14436)">
<path d="M4 7.73349C4 5.49329 4 4.37318 4.43597 3.51753C4.81947 2.76489 5.43139 2.15296 6.18404 1.76947C7.03969 1.3335 8.15979 1.3335 10.4 1.3335H18.6667L28 10.6668V24.2668C28 26.507 28 27.6271 27.564 28.4828C27.1805 29.2354 26.5686 29.8474 25.816 30.2309C24.9603 30.6668 23.8402 30.6668 21.6 30.6668H10.4C8.15979 30.6668 7.03969 30.6668 6.18404 30.2309C5.43139 29.8474 4.81947 29.2354 4.43597 28.4828C4 27.6271 4 26.507 4 24.2668V7.73349Z" fill="#E3E5E8"/>
<path d="M4.25 7.73349C4.25 6.60926 4.25019 5.78113 4.30367 5.12666C4.3569 4.47511 4.46169 4.01774 4.65873 3.63103C5.01825 2.92542 5.59193 2.35175 6.29754 1.99222C6.68424 1.79518 7.14162 1.6904 7.79317 1.63716C8.44763 1.58369 9.27577 1.5835 10.4 1.5835H18.5631L27.75 10.7704V24.2668C27.75 25.3911 27.7498 26.2192 27.6963 26.8737C27.6431 27.5252 27.5383 27.9826 27.3413 28.3693C26.9817 29.0749 26.4081 29.6486 25.7025 30.0081C25.3158 30.2051 24.8584 30.3099 24.2068 30.3632C23.5524 30.4166 22.7242 30.4168 21.6 30.4168H10.4C9.27577 30.4168 8.44763 30.4166 7.79317 30.3632C7.14162 30.3099 6.68424 30.2051 6.29754 30.0081C5.59193 29.6486 5.01825 29.0749 4.65873 28.3693C4.46169 27.9826 4.3569 27.5252 4.30367 26.8737C4.25019 26.2192 4.25 25.3911 4.25 24.2668V7.73349Z" stroke="black" stroke-opacity="0.03" stroke-width="0.5"/>
</g>
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.9998 23.1992C15.8014 23.1992 15.6039 23.1968 15.4077 23.1924V24.0549C15.4077 24.3819 15.6728 24.647 15.9998 24.647C16.3268 24.647 16.592 24.3819 16.592 24.0549V23.1924C16.3957 23.1968 16.1983 23.1992 15.9998 23.1992Z" fill="#98A2B3"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.0984 22.8838L11.757 23.8593C11.649 24.168 11.8117 24.5058 12.1203 24.6138C12.185 24.6364 12.251 24.6472 12.3159 24.6472C12.5605 24.6472 12.7894 24.4944 12.8747 24.2505L13.2936 23.0534C12.8807 23.0073 12.481 22.9506 12.0984 22.8838Z" fill="#98A2B3"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M20.2431 23.8593L19.9018 22.8838C19.5192 22.9506 19.1195 23.0073 18.7065 23.0534L19.1254 24.2505C19.2108 24.4944 19.4396 24.6472 19.6843 24.6472C19.7491 24.6472 19.8151 24.6364 19.8798 24.6138C20.1885 24.5058 20.3511 24.168 20.2431 23.8593Z" fill="#98A2B3"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M20.1624 17.2634C20.2697 17.6416 20.3254 18.0369 20.3254 18.4409C20.3254 18.9087 20.05 19.3327 19.6226 19.5228C19.5564 19.5522 17.9801 20.2436 16.0359 20.2436C14.0917 20.2436 12.5153 19.5522 12.4492 19.5228C12.0218 19.3327 11.7464 18.9086 11.7464 18.4409C11.7464 18.0312 11.8037 17.6305 11.914 17.2476C10.3343 17.5645 8.5 18.2009 8.5 19.4464C8.5 20.2859 9.32512 20.9477 10.9525 21.4134C11.4194 21.547 11.9381 21.66 12.4949 21.7506C12.8783 21.813 13.28 21.8648 13.6953 21.9056C14.2455 21.9597 14.8197 21.9942 15.4079 22.0082C15.6039 22.0128 15.8013 22.0153 16 22.0153C16.1987 22.0153 16.3962 22.0128 16.5921 22.0082C17.1803 21.9943 17.7545 21.9596 18.3047 21.9056C18.72 21.8648 19.1217 21.8131 19.5051 21.7506C20.062 21.66 20.5807 21.547 21.0476 21.4134C22.6749 20.9477 23.5 20.2859 23.5 19.4464C23.5 18.2187 21.7108 17.5833 20.1624 17.2634Z" fill="#98A2B3"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M18.8441 17.1144C18.7585 16.9335 18.6559 16.7622 18.5384 16.6025C18.4174 16.4382 18.2809 16.286 18.1307 16.1486C17.5784 15.6437 16.8433 15.3354 16.036 15.3354C15.2318 15.3354 14.499 15.6411 13.9476 16.1426C13.7974 16.2791 13.6609 16.4303 13.5399 16.5937C13.4217 16.753 13.3185 16.924 13.2322 17.1048C13.039 17.5095 12.9307 17.9624 12.9307 18.4407C12.9307 18.4407 14.321 19.0592 16.036 19.0592C17.751 19.0592 19.1412 18.4407 19.1412 18.4407C19.1412 17.9662 19.0344 17.5167 18.8441 17.1144Z" fill="#98A2B3"/>
<path opacity="0.5" d="M18.6665 1.3335L27.9998 10.6668H21.3332C19.8604 10.6668 18.6665 9.47292 18.6665 8.00016V1.3335Z" fill="white"/>
<defs>
<filter id="filter0_d_3055_14436" x="2" y="0.333496" width="28" height="33.3335" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="1"/>
<feGaussianBlur stdDeviation="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.0627451 0 0 0 0 0.0941176 0 0 0 0 0.156863 0 0 0 0.05 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_3055_14436"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_3055_14436" result="shape"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.4" d="M4 16.2422C2.79401 15.435 2 14.0602 2 12.5C2 10.1564 3.79151 8.23129 6.07974 8.01937C6.54781 5.17213 9.02024 3 12 3C14.9798 3 17.4522 5.17213 17.9203 8.01937C20.2085 8.23129 22 10.1564 22 12.5C22 14.0602 21.206 15.435 20 16.2422" stroke="#344054" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M8 16L12 12M12 12L16 16M12 12L12 21" stroke="#344054" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 572 B

View File

@@ -0,0 +1,4 @@
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.06124 2.21694C7.57213 2.07545 8.11041 1.99984 8.66634 1.99984C9.97432 1.99984 11.1845 2.41837 12.1704 3.12881C11.6459 3.4755 11.2546 3.85196 10.9834 4.25446C10.569 4.86947 10.4628 5.50546 10.5486 6.08575C10.632 6.64928 10.8907 7.13053 11.1627 7.48656C11.4265 7.83177 11.7501 8.12048 12.0351 8.26293C12.7526 8.62164 13.5806 8.80129 14.1996 8.89387C14.7596 8.97762 15.9468 9.2579 15.9907 8.36596C15.9967 8.24461 15.9997 8.12255 15.9997 7.99984C15.9997 3.94975 12.7164 0.666504 8.66634 0.666504C4.61625 0.666504 1.33301 3.94975 1.33301 7.99984C1.33301 12.0499 4.61625 15.3332 8.66634 15.3332C8.78906 15.3332 8.91112 15.3301 9.03246 15.3242C9.40021 15.3061 9.68364 14.9933 9.66553 14.6255C9.64743 14.2578 9.33463 13.9743 8.96689 13.9925C8.86737 13.9974 8.76717 13.9998 8.66634 13.9998C6.32676 13.9998 4.29993 12.6608 3.31046 10.7073L3.95617 10.3345L6.33797 10.7803C6.95507 10.8958 7.52471 10.4207 7.52192 9.79289L7.51258 7.69081L8.72983 5.60684C8.92705 5.2692 8.90938 4.84758 8.68459 4.52762L7.06124 2.21694Z" fill="#1570EF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.96344 8.43724C9.71815 8.3442 9.4411 8.40367 9.2556 8.58917C9.07009 8.77467 9.01063 9.05172 9.10367 9.29701L11.2149 14.8629C11.3123 15.1198 11.5575 15.2906 11.8323 15.2931C12.1071 15.2955 12.3552 15.1291 12.4572 14.8739L13.3377 12.6713L15.5403 11.7908C15.7955 11.6888 15.9619 11.4407 15.9595 11.1659C15.9571 10.891 15.7862 10.6459 15.5293 10.5484L9.96344 8.43724Z" fill="#1570EF"/>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1,6 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.66675 11.6666C1.66675 11.2985 1.96522 11 2.33341 11H6.00008C6.36827 11 6.66675 11.2985 6.66675 11.6666C6.66675 12.0348 6.36827 12.3333 6.00008 12.3333H2.33341C1.96522 12.3333 1.66675 12.0348 1.66675 11.6666Z" fill="#7839EE"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.666748 7.99997C0.666748 7.63178 0.965225 7.33331 1.33341 7.33331H4.33341C4.7016 7.33331 5.00008 7.63178 5.00008 7.99997C5.00008 8.36816 4.7016 8.66664 4.33341 8.66664H1.33341C0.965225 8.66664 0.666748 8.36816 0.666748 7.99997Z" fill="#7839EE"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.00008 4.33331C2.00008 3.96512 2.29856 3.66664 2.66675 3.66664H6.00008C6.36827 3.66664 6.66675 3.96512 6.66675 4.33331C6.66675 4.7015 6.36827 4.99997 6.00008 4.99997H2.66675C2.29856 4.99997 2.00008 4.7015 2.00008 4.33331Z" fill="#7839EE"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.5785 1.37998C11.8632 1.49253 12.0347 1.78458 11.9942 2.08808L11.4282 6.33331H13.9637C13.9714 6.33331 13.979 6.33331 13.9867 6.3333C14.1339 6.33327 14.2864 6.33324 14.4124 6.34476C14.5363 6.35609 14.7618 6.38612 14.9633 6.54167C15.1984 6.72308 15.3407 6.99955 15.3517 7.29625C15.3611 7.55067 15.2545 7.7516 15.1917 7.85904C15.1278 7.96825 15.0391 8.09234 14.9536 8.21207C14.9491 8.21833 14.9446 8.22457 14.9402 8.23079L10.5426 14.3875C10.3646 14.6366 10.0398 14.7325 9.75503 14.62C9.47027 14.5074 9.29879 14.2154 9.33926 13.9119L9.90529 9.66664H7.36978C7.36213 9.66664 7.35447 9.66664 7.34679 9.66664C7.19962 9.66668 7.0471 9.66671 6.92111 9.65519C6.79717 9.64386 6.5717 9.61383 6.37015 9.45828C6.13511 9.27687 5.99283 9.0004 5.98183 8.7037C5.9724 8.44928 6.07901 8.24835 6.14183 8.14091C6.20569 8.0317 6.29437 7.9076 6.37993 7.78787C6.3844 7.78162 6.38886 7.77538 6.3933 7.76915L10.7909 1.61248C10.9689 1.36332 11.2937 1.26743 11.5785 1.37998Z" fill="#7839EE"/>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1,38 @@
.modal {
position: relative;
}
.modalHeader {
@apply flex items-center place-content-between h-8;
}
.modalHeader .title {
@apply grow;
font-weight: 600;
font-size: 20px;
line-height: 32px;
color: #101828;
}
.modalHeader .close {
@apply shrink-0 h-4 w-4 bg-center bg-no-repeat cursor-pointer;
background-image: url(../assets/close.svg);
background-size: 16px;
}
.modal .tip {
@apply mt-1 mb-8;
font-weight: 400;
font-size: 13px;
line-height: 18px;
color: #667085;
}
.form {
@apply mb-8;
}
.form .label {
@apply mb-2;
font-weight: 500;
font-size: 14px;
line-height: 20px;
color: #101828;
}

View File

@@ -0,0 +1,73 @@
'use client'
import React, { useState } from 'react'
import { useRouter } from 'next/navigation'
import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import Modal from '@/app/components/base/modal'
import Input from '@/app/components/base/input'
import Button from '@/app/components/base/button'
import { ToastContext } from '@/app/components/base/toast'
import { createEmptyDataset } from '@/service/datasets'
import cn from 'classnames'
import s from './index.module.css'
type IProps = {
show: boolean,
onHide: () => void,
}
const EmptyDatasetCreationModal = ({
show = false,
onHide,
}: IProps) => {
const [inputValue, setInputValue] = useState('')
const { t } = useTranslation()
const { notify } = useContext(ToastContext)
const router = useRouter()
const submit = async () => {
if (!inputValue) {
notify({ type: 'error', message: t('datasetCreation.stepOne.modal.nameNotEmpty') })
return
}
if (inputValue.length > 40) {
notify({ type: 'error', message: t('datasetCreation.stepOne.modal.nameLengthInvaild') })
return
}
try {
const dataset = await createEmptyDataset({ name: inputValue })
onHide()
router.push(`/datasets/${dataset.id}/documents`)
}
catch (err) {
notify({ type: 'error', message: t('datasetCreation.stepOne.modal.failed') })
return
}
}
return (
<Modal
isShow={show}
onClose={onHide}
className={cn(s.modal, '!max-w-[520px]', 'px-8')}
>
<div className={s.modalHeader}>
<div className={s.title}>{t('datasetCreation.stepOne.modal.title')}</div>
<span className={s.close} onClick={onHide}/>
</div>
<div className={s.tip}>{t('datasetCreation.stepOne.modal.tip')}</div>
<div className={s.form}>
<div className={s.label}>{t('datasetCreation.stepOne.modal.input')}</div>
<Input className='!h-8' value={inputValue} placeholder={t('datasetCreation.stepOne.modal.placeholder') || ''} onChange={setInputValue} />
</div>
<div className='flex flex-row-reverse'>
<Button className='w-24 ml-2' type='primary' onClick={submit}>{t('datasetCreation.stepOne.modal.confirmButton')}</Button>
<Button className='w-24' onClick={onHide}>{t('datasetCreation.stepOne.modal.cancelButton')}</Button>
</div>
</Modal>
)
}
export default EmptyDatasetCreationModal

View File

@@ -0,0 +1,46 @@
.filePreview {
@apply flex flex-col border-l border-gray-200 shrink-0;
width: 528px;
background-color: #fcfcfd;
}
.previewHeader {
@apply border-b border-gray-200 shrink-0;
margin: 42px 32px 0;
padding-bottom: 16px;
}
.previewHeader .title {
color: #101828;
font-weight: 600;
font-size: 18px;
line-height: 28px;
}
.previewHeader .fileName {
font-weight: 400;
font-size: 12px;
line-height: 18px;
color: #1D2939;
}
.previewHeader .filetype {
color: #667085;
}
.previewContent {
@apply overflow-y-auto grow;
padding: 20px 32px;
font-weight: 400;
font-size: 16px;
line-height: 24px;
color: #344054;
}
.previewContent .loading {
width: 100%;
height: 180px;
background: #f9fafb center no-repeat url(../assets/Loading.svg);
background-size: contain;
}

View File

@@ -0,0 +1,62 @@
'use client'
import React, { useState, useEffect } from 'react'
import { useTranslation } from 'react-i18next'
import type { File } from '@/models/datasets'
import { fetchFilePreview } from '@/service/common'
import cn from 'classnames'
import s from './index.module.css'
type IProps = {
file?: File,
}
const FilePreview = ({
file,
}: IProps) => {
const { t } = useTranslation()
const [previewContent, setPreviewContent] = useState('')
const [loading, setLoading] = useState(true)
const getPreviewContent = async (fileID: string) => {
try {
const res = await fetchFilePreview({ fileID })
setPreviewContent(res.content)
setLoading(false)
}
catch {}
}
const getFileName = (currentFile?: File) => {
if (!currentFile) {
return ''
}
const arr = currentFile.name.split('.')
return arr.slice(0, -1).join()
}
useEffect(() => {
if (file) {
getPreviewContent(file.id)
}
}, [file])
return (
<div className={cn(s.filePreview)}>
<div className={cn(s.previewHeader)}>
<div className={cn(s.title)}>{t('datasetCreation.stepOne.filePreview')}</div>
<div className={cn(s.fileName)}>
<span>{getFileName(file)}</span><span className={cn(s.filetype)}>.{file?.extension}</span>
</div>
</div>
<div className={cn(s.previewContent)}>
{loading && <div className={cn(s.loading)}/>}
{!loading && (
<div className={cn(s.fileContent)}>{previewContent}</div>
)}
</div>
</div>
)
}
export default FilePreview

View File

@@ -0,0 +1,171 @@
.fileUploader {
@apply mb-9;
}
.fileUploader .title {
@apply mb-2;
font-weight: 500;
font-size: 16px;
line-height: 24px;
color: #344054;
}
.fileUploader .tip {
@apply mt-2;
font-weight: 400;
font-size: 12px;
line-height: 26px;
color: #667085;
}
.uploader {
@apply relative box-border flex justify-center items-center;
max-width: 640px;
height: 80px;
background: #F9FAFB;
border: 1px dashed #EAECF0;
border-radius: 12px;
font-weight: 400;
font-size: 14px;
line-height: 20px;
color: #667085;
}
.uploader.dragging {
background: #F5F8FF;
border: 1px dashed #B2CCFF;
}
.uploader .draggingCover {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.uploader::before {
content: '';
display: block;
margin-right: 8px;
width: 24px;
height: 24px;
background: center no-repeat url(../assets/upload-cloud-01.svg);
background-size: contain;
}
.uploader .browse{
@apply pl-1 cursor-pointer;
color: #155eef;
}
.file {
@apply box-border relative flex items-center;
padding: 21px 24px 21px 64px;
max-width: 640px;
height: 80px;
background: #F9FAFB;
border: 1px solid #F2F4F7;
border-radius: 12px;
overflow: hidden;
}
.progressbar {
position: absolute;
top: 0;
left: 0;
height: 100%;
background-color: #F2F4F7;
}
.file:hover {
background: #F5F8FF;
border: 1px solid #D1E0FF;
}
.file:hover .actionWrapper .buttonWrapper {
display: flex;
align-items: center;
}
.file:hover .actionWrapper .divider {
display: block;
}
.file.uploading,
.file.uploading:hover {
background: #FCFCFD;
border: 1px solid #EAECF0;
}
.file.uploading:hover .actionWrapper .percent {
padding: 8px;
}
.file.uploading:hover .actionWrapper .buttonWrapper {
display: flex;
align-items: center;
}
.fileIcon {
@apply w-8 h-8 bg-center bg-no-repeat;
position: absolute;
top: 24px;
left: 24px;
background-image: url(../assets/unknow.svg);
background-size: 32px;
}
.fileIcon.pdf {
background-image: url(../assets/pdf.svg);
}
.fileIcon.html,
.fileIcon.htm {
background-image: url(../assets/html.svg);
}
.fileIcon.md,
.fileIcon.markdown {
background-image: url(../assets/md.svg);
}
.fileIcon.txt {
background-image: url(../assets/txt.svg);
}
.fileIcon.json {
background-image: url(../assets/json.svg);
}
.fileInfo {
@apply grow;
z-index: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.filename {
font-weight: 500;
font-size: 14px;
line-height: 20px;
}
.name {
color: #1D2939;
line-height: 20px;
}
.extension {
color: #667085;
line-height: 20px;
}
.fileExtraInfo {
color: #667085;
font-size: 12px;
line-height: 18px;
}
.actionWrapper {
@apply flex items-center shrink-0;
z-index: 1;
}
.actionWrapper .percent {
font-size: 16px;
line-height: 24px;
color: #344054;
}
.actionWrapper .divider {
display: none;
margin: 0 8px;
width: 1px;
height: 16px;
background: #FEE4E2;
}
.actionWrapper .remove {
width: 32px;
height: 32px;
background: center no-repeat url(../assets/trash.svg);
background-size: 16px;
cursor: pointer;
}
.actionWrapper .buttonWrapper {
@apply flex items-center;
display: none;
}

View File

@@ -0,0 +1,265 @@
'use client'
import React, { useState, useRef, useEffect, useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import type { File as FileEntity } from '@/models/datasets'
import { useContext } from 'use-context-selector'
import { ToastContext } from '@/app/components/base/toast'
import Button from '@/app/components/base/button'
import { upload } from '@/service/base'
import cn from 'classnames'
import s from './index.module.css'
type IFileUploaderProps = {
file?: FileEntity;
onFileUpdate: (file?: FileEntity) => void;
}
const ACCEPTS = [
'.pdf',
'.html',
'.htm',
'.md',
'.markdown',
'.txt',
]
const MAX_SIZE = 15 * 1024 *1024
const FileUploader = ({ file, onFileUpdate }: IFileUploaderProps) => {
const { t } = useTranslation()
const { notify } = useContext(ToastContext)
const [dragging, setDragging] = useState(false)
const dropRef = useRef<HTMLDivElement>(null)
const dragRef = useRef<HTMLDivElement>(null)
const fileUploader = useRef<HTMLInputElement>(null)
const uploadPromise = useRef<any>(null)
const [currentFile, setCurrentFile] = useState<File>()
const [uploading, setUploading] = useState(false)
const [percent, setPercent] = useState(0)
const handleDragEnter = (e: DragEvent) => {
e.preventDefault()
e.stopPropagation()
e.target !== dragRef.current && setDragging(true)
}
const handleDragOver = (e: DragEvent) => {
e.preventDefault()
e.stopPropagation()
}
const handleDragLeave = (e: DragEvent) => {
e.preventDefault()
e.stopPropagation()
e.target === dragRef.current && setDragging(false)
}
const handleDrop = (e: DragEvent) => {
e.preventDefault()
e.stopPropagation()
setDragging(false)
if (!e.dataTransfer) {
return
}
const files = [...e.dataTransfer.files]
if (files.length > 1) {
notify({ type: 'error', message: t('datasetCreation.stepOne.uploader.validation.count') })
return;
}
onFileUpdate()
fileUpload(files[0])
}
const selectHandle = () => {
if (fileUploader.current) {
fileUploader.current.click();
}
}
const removeFile = () => {
if (fileUploader.current) {
fileUploader.current.value = ''
}
setCurrentFile(undefined)
onFileUpdate()
}
const fileChangeHandle = (e: React.ChangeEvent<HTMLInputElement>) => {
const currentFile = e.target.files?.[0]
onFileUpdate()
fileUpload(currentFile)
}
const fileUpload = async (file?: File) => {
if (!file) {
return
}
if (!isValid(file)) {
return
}
setCurrentFile(file)
setUploading(true)
const formData = new FormData()
formData.append('file', file)
// store for abort
const currentXHR = new XMLHttpRequest()
uploadPromise.current = currentXHR
try {
const result = await upload({
xhr: currentXHR,
data: formData,
onprogress: onProgress,
}) as FileEntity;
onFileUpdate(result)
setUploading(false)
}
catch (xhr: any) {
setUploading(false)
// abort handle
if (xhr.readyState === 0 && xhr.status === 0) {
if (fileUploader.current) {
fileUploader.current.value = ''
}
setCurrentFile(undefined)
return
}
notify({ type: 'error', message: t('datasetCreation.stepOne.uploader.failed') })
return
}
}
const onProgress = useCallback((e: ProgressEvent) => {
if (e.lengthComputable) {
const percent = Math.floor(e.loaded / e.total * 100)
setPercent(percent)
}
}, [setPercent])
const abort = () => {
const currentXHR = uploadPromise.current
currentXHR.abort();
}
// utils
const getFileType = (currentFile: File) => {
if (!currentFile) {
return ''
}
const arr = currentFile.name.split('.')
return arr[arr.length-1]
}
const getFileName = (name: string) => {
const arr = name.split('.')
return arr.slice(0, -1).join()
}
const getFileSize = (size: number) => {
if (size / 1024 < 10) {
return `${(size / 1024).toFixed(2)}KB`
}
return `${(size / 1024 / 1024).toFixed(2)}MB`
}
const isValid = (file: File) => {
const { size } = file
const ext = `.${getFileType(file)}`
const isValidType = ACCEPTS.includes(ext)
if (!isValidType) {
notify({ type: 'error', message: t('datasetCreation.stepOne.uploader.validation.typeError') })
}
const isValidSize = size <= MAX_SIZE;
if (!isValidSize) {
notify({ type: 'error', message: t('datasetCreation.stepOne.uploader.validation.size') })
}
return isValidType && isValidSize;
}
useEffect(() => {
dropRef.current?.addEventListener('dragenter', handleDragEnter);
dropRef.current?.addEventListener('dragover', handleDragOver);
dropRef.current?.addEventListener('dragleave', handleDragLeave);
dropRef.current?.addEventListener('drop', handleDrop);
return () => {
dropRef.current?.removeEventListener('dragenter', handleDragEnter);
dropRef.current?.removeEventListener('dragover', handleDragOver);
dropRef.current?.removeEventListener('dragleave', handleDragLeave);
dropRef.current?.removeEventListener('drop', handleDrop);
}
}, [])
return (
<div className={s.fileUploader}>
<input
ref={fileUploader}
style={{ display: 'none' }}
type="file"
id="fileUploader"
accept={ACCEPTS.join(',')}
onChange={fileChangeHandle}
/>
<div className={s.title}>{t('datasetCreation.stepOne.uploader.title')}</div>
{!currentFile && !file && (
<div ref={dropRef} className={cn(s.uploader, dragging && s.dragging)}>
<span>{t('datasetCreation.stepOne.uploader.button')}</span>
<label className={s.browse} onClick={selectHandle}>{t('datasetCreation.stepOne.uploader.browse')}</label>
{dragging && <div ref={dragRef} className={s.draggingCover}/>}
</div>
)}
{currentFile && (
<div className={cn(s.file, uploading && s.uploading)}>
{uploading && (
<div className={s.progressbar} style={{ width: `${percent}%`}}/>
)}
<div className={cn(s.fileIcon, s[getFileType(currentFile)])}/>
<div className={s.fileInfo}>
<div className={s.filename}>
<span className={s.name}>{getFileName(currentFile.name)}</span>
<span className={s.extension}>{`.${getFileType(currentFile)}`}</span>
</div>
<div className={s.fileExtraInfo}>
<span className={s.size}>{getFileSize(currentFile.size)}</span>
<span className={s.error}></span>
</div>
</div>
<div className={s.actionWrapper}>
{uploading && (
<>
<div className={s.percent}>{`${percent}%`}</div>
<div className={s.divider}/>
<div className={s.buttonWrapper}>
<Button className={cn(s.button, 'ml-2 !h-8 bg-white')} onClick={abort}>{t('datasetCreation.stepOne.uploader.cancel')}</Button>
</div>
</>
)}
{!uploading && (
<>
<div className={s.buttonWrapper}>
<Button className={cn(s.button, 'ml-2 !h-8 bg-white')} onClick={selectHandle}>{t('datasetCreation.stepOne.uploader.change')}</Button>
<div className={s.divider}/>
<div className={s.remove} onClick={removeFile}/>
</div>
</>
)}
</div>
</div>
)}
{!currentFile && file && (
<div className={cn(s.file)}>
<div className={cn(s.fileIcon, s[file.extension])}/>
<div className={s.fileInfo}>
<div className={s.filename}>
<span className={s.name}>{getFileName(file.name)}</span>
<span className={s.extension}>{`.${file.extension}`}</span>
</div>
<div className={s.fileExtraInfo}>
<span className={s.size}>{getFileSize(file.size)}</span>
<span className={s.error}></span>
</div>
</div>
<div className={s.actionWrapper}>
<div className={s.buttonWrapper}>
<Button className={cn(s.button, 'ml-2 !h-8 bg-white')} onClick={selectHandle}>{t('datasetCreation.stepOne.uploader.change')}</Button>
<div className={s.divider}/>
<div className={s.remove} onClick={removeFile}/>
</div>
</div>
</div>
)}
<div className={s.tip}>{t('datasetCreation.stepOne.uploader.tip')}</div>
</div>
)
}
export default FileUploader;

View File

@@ -0,0 +1,113 @@
'use client'
import React, { useState, useCallback, useEffect } from 'react'
import { useTranslation } from 'react-i18next'
import { useBoolean } from 'ahooks'
import type { DataSet, File, createDocumentResponse } from '@/models/datasets'
import { fetchTenantInfo } from '@/service/common'
import { fetchDataDetail } from '@/service/datasets'
import StepsNavBar from './steps-nav-bar'
import StepOne from './step-one'
import StepTwo from './step-two'
import StepThree from './step-three'
import AccountSetting from '@/app/components/header/account-setting'
import AppUnavailable from '../../base/app-unavailable'
type DatasetUpdateFormProps = {
datasetId?: string;
}
const DatasetUpdateForm = ({ datasetId }: DatasetUpdateFormProps) => {
const { t } = useTranslation()
const [hasSetAPIKEY, setHasSetAPIKEY] = useState(true)
const [isShowSetAPIKey, { setTrue: showSetAPIKey, setFalse: hideSetAPIkey }] = useBoolean()
const [step, setStep] = useState(1)
const [indexingTypeCache, setIndexTypeCache] = useState('')
const [file, setFile] = useState<File | undefined>()
const [result, setResult] = useState<createDocumentResponse | undefined>()
const [hasError, setHasError] = useState(false)
const updateFile = (file?: File) => {
setFile(file)
}
const updateIndexingTypeCache = (type: string) => {
setIndexTypeCache(type)
}
const updateResultCache = (res?: createDocumentResponse) => {
setResult(res)
}
const nextStep = useCallback(() => {
setStep(step + 1)
}, [step, setStep])
const changeStep = useCallback((delta: number) => {
setStep(step + delta)
}, [step, setStep])
const checkAPIKey = async () => {
const data = await fetchTenantInfo({ url: '/info' })
const hasSetKey = data.providers.some(({ is_valid }) => is_valid)
setHasSetAPIKEY(hasSetKey)
}
useEffect(() => {
checkAPIKey()
}, [])
const [detail, setDetail] = useState<DataSet | null>(null)
useEffect(() => {
(async () => {
if (datasetId) {
try {
const detail = await fetchDataDetail(datasetId)
setDetail(detail)
} catch (e) {
setHasError(true)
}
}
})()
}, [datasetId])
if (hasError) {
return <AppUnavailable code={500} unknownReason={t('datasetCreation.error.unavailable') as string} />
}
return (
<div className='flex' style={{ height: 'calc(100vh - 56px)' }}>
<div className="flex flex-col w-56 overflow-y-auto bg-white border-r border-gray-200 shrink-0">
<StepsNavBar step={step} datasetId={datasetId} />
</div>
<div className="grow bg-white">
{step === 1 && <StepOne
datasetId={datasetId}
file={file}
updateFile={updateFile}
onStepChange={nextStep}
/>}
{(step === 2 && (!datasetId || (datasetId && !!detail))) && <StepTwo
hasSetAPIKEY={hasSetAPIKEY}
onSetting={showSetAPIKey}
indexingType={detail?.indexing_technique || ''}
datasetId={datasetId}
file={file}
onStepChange={changeStep}
updateIndexingTypeCache={updateIndexingTypeCache}
updateResultCache={updateResultCache}
/>}
{step === 3 && <StepThree
datasetId={datasetId}
datasetName={detail?.name}
indexingType={detail?.indexing_technique || indexingTypeCache}
creationCache={result}
/>}
</div>
{isShowSetAPIKey && <AccountSetting activeTab="provider" onCancel={async () => {
await checkAPIKey()
hideSetAPIkey()
}} />}
</div>
)
}
export default DatasetUpdateForm

View File

@@ -0,0 +1,109 @@
.stepHeader {
position: sticky;
top: 0;
left: 0;
padding: 42px 64px 12px;
font-weight: 600;
font-size: 18px;
line-height: 28px;
color: #101828;
}
.form {
padding: 12px 64px;
}
.dataSourceTypeList {
@apply flex items-center mb-8;
}
.dataSourceItem {
@apply box-border relative shrink-0 flex items-center mr-3 p-3 h-14 bg-white rounded-xl cursor-pointer;
border: 0.5px solid #EAECF0;
box-shadow: 0px 1px 2px rgba(16, 24, 40, 0.05);
font-weight: 500;
font-size: 14px;
line-height: 20px;
color: #101828;
}
.dataSourceItem:hover {
background-color: #f5f8ff;
border: 0.5px solid #B2CCFF;
box-shadow: 0px 12px 16px -4px rgba(16, 24, 40, 0.08), 0px 4px 6px -2px rgba(16, 24, 40, 0.03);
}
.dataSourceItem.active {
background-color: #f5f8ff;
border: 1.5px solid #528BFF;
box-shadow: 0px 1px 3px rgba(16, 24, 40, 0.1), 0px 1px 2px rgba(16, 24, 40, 0.06);
}
.dataSourceItem.disabled {
background-color: #f9fafb;
border: 0.5px solid #EAECF0;
box-shadow: 0px 1px 2px rgba(16, 24, 40, 0.05);
cursor: default;
}
.dataSourceItem.disabled:hover {
background-color: #f9fafb;
border: 0.5px solid #EAECF0;
box-shadow: 0px 1px 2px rgba(16, 24, 40, 0.05);
}
.comingTag {
@apply flex justify-center items-center bg-white;
position: absolute;
right: 8px;
top: -10px;
padding: 1px 6px;
height: 20px;
border: 1px solid #E0EAFF;
border-radius: 6px;
font-weight: 500;
font-size: 12px;
line-height: 18px;
color: #444CE7;
}
.datasetIcon {
@apply flex mr-2 w-8 h-8 rounded-lg bg-center bg-no-repeat;
background-color: #F5FAFF;
background-image: url(../assets/file.svg);
background-size: 16px;
border: 0.5px solid #D1E9FF;
}
.dataSourceItem:active .datasetIcon,
.dataSourceItem:hover .datasetIcon {
background-color: #F5F8FF;
border: 0.5px solid #E0EAFF;
}
.datasetIcon.notion {
background-image: url(../assets/notion.svg);
background-size: 20px;
}
.datasetIcon.web {
background-image: url(../assets/web.svg);
}
.submitButton {
width: 120px;
}
.dividerLine {
margin: 32px 0;
max-width: 640px;
height: 1px;
background-color: #eaecf0;
}
.OtherCreationOption {
@apply flex items-center cursor-pointer;
font-weight: 500;
font-size: 13px;
line-height: 18px;
color: #155EEF;
}
.OtherCreationOption::before {
content: '';
display: block;
margin-right: 4px;
width: 16px;
height: 16px;
background: center no-repeat url(../assets/folder-plus.svg);
background-size: contain;
}

View File

@@ -0,0 +1,80 @@
'use client'
import React, { useState } from 'react'
import { useTranslation } from 'react-i18next'
import type { File } from '@/models/datasets'
import FilePreview from '../file-preview'
import FileUploader from '../file-uploader'
import EmptyDatasetCreationModal from '../empty-dataset-creation-modal'
import Button from '@/app/components/base/button'
import cn from 'classnames'
import s from './index.module.css'
type IStepOneProps = {
datasetId?: string,
file?: File,
updateFile: (file?: File) => void,
onStepChange: () => void,
}
const StepOne = ({
datasetId,
onStepChange,
file,
updateFile,
}: IStepOneProps) => {
const [dataSourceType, setDataSourceType] = useState('FILE')
const [showModal, setShowModal] = useState(false)
const { t } = useTranslation()
const modalShowHandle = () => setShowModal(true)
const modalCloseHandle = () => setShowModal(false)
return (
<div className='flex w-full h-full'>
<div className='grow overflow-y-auto relative'>
<div className={s.stepHeader}>{t('datasetCreation.steps.one')}</div>
<div className={s.form}>
<div className={s.dataSourceTypeList}>
<div
className={cn(s.dataSourceItem, dataSourceType === 'FILE' && s.active)}
onClick={() => setDataSourceType('FILE')}
>
<span className={cn(s.datasetIcon)}/>
{t('datasetCreation.stepOne.dataSourceType.file')}
</div>
<div
className={cn(s.dataSourceItem, s.disabled, dataSourceType === 'notion' && s.active)}
// onClick={() => setDataSourceType('notion')}
>
<span className={s.comingTag}>Coming soon</span>
<span className={cn(s.datasetIcon, s.notion)}/>
{t('datasetCreation.stepOne.dataSourceType.notion')}
</div>
<div
className={cn(s.dataSourceItem, s.disabled, dataSourceType === 'web' && s.active)}
// onClick={() => setDataSourceType('web')}
>
<span className={s.comingTag}>Coming soon</span>
<span className={cn(s.datasetIcon, s.web)}/>
{t('datasetCreation.stepOne.dataSourceType.web')}
</div>
</div>
<FileUploader onFileUpdate={updateFile} file={file} />
<Button disabled={!file} className={s.submitButton} type='primary' onClick={onStepChange}>{t('datasetCreation.stepOne.button')}</Button>
{!datasetId && (
<>
<div className={s.dividerLine}/>
<div onClick={modalShowHandle} className={s.OtherCreationOption}>{t('datasetCreation.stepOne.emptyDatasetCreation')}</div>
</>
)}
</div>
<EmptyDatasetCreationModal show={showModal} onHide={modalCloseHandle}/>
</div>
{file && <FilePreview file={file} />}
</div>
)
}
export default StepOne

View File

@@ -0,0 +1,75 @@
.creationInfo {
padding-top: 42px;
}
.creationInfo .title {
@apply mb-2;
font-weight: 500;
font-size: 20px;
line-height: 30px;
color: #101828;
}
.creationInfo .content {
margin-bottom: 44px;
font-weight: 400;
font-size: 14px;
line-height: 20px;
color: #667085;
}
.creationInfo .label {
@apply mb-2;
font-weight: 500;
font-size: 14px;
line-height: 20px;
color: #101828;
}
.datasetName {
padding: 8px 12px;
background: #F9FAFB;
border-radius: 8px;
font-weight: 400;
font-size: 14px;
line-height: 20px;
color: #101828;
word-break: break-all;
}
.dividerLine {
margin: 24px 0;
height: 1px;
background-color: #eaecf0;
}
.sideTip {
@apply flex flex-col items-center shrink-0 ;
padding-top: 108px;
width: 524px;
border-left: 0.5px solid #F2F4F7;
}
.tipCard {
@apply flex flex-col items-start p-6;
width: 320px;
background-color: #F9FAFB;
box-shadow: 0px 1px 2px rgba(16, 24, 40, 0.05);
border-radius: 12px;
}
.tipCard .icon {
width: 32px;
height: 32px;
border: 1px solid #EAECF0;
border-radius: 6px;
background: center no-repeat url(../assets/book-open-01.svg);
background-size: 16px;
}
.tipCard .title {
margin: 12px 0;
font-weight: 500;
font-size: 16px;
line-height: 24px;
color: #344054;
}
.tipCard .content {
font-weight: 400;
font-size: 14px;
line-height: 20px;
color: #344054;
}

View File

@@ -0,0 +1,61 @@
'use client'
import React from 'react'
import { useTranslation } from 'react-i18next'
import type { createDocumentResponse } from '@/models/datasets'
import EmbeddingDetail from '../../documents/detail/embedding'
import cn from 'classnames'
import s from './index.module.css'
type StepThreeProps = {
datasetId?: string,
datasetName?: string,
indexingType?: string,
creationCache?: createDocumentResponse
}
const StepThree = ({ datasetId, datasetName, indexingType, creationCache }: StepThreeProps) => {
const { t } = useTranslation()
return (
<div className='flex w-full h-full'>
<div className={'h-full w-full overflow-y-scroll px-16'}>
<div className='max-w-[636px]'>
{!datasetId && (
<>
<div className={s.creationInfo}>
<div className={s.title}>{t('datasetCreation.stepThree.creationTitle')}</div>
<div className={s.content}>{t('datasetCreation.stepThree.creationContent')}</div>
<div className={s.label}>{t('datasetCreation.stepThree.label')}</div>
<div className={s.datasetName}>{datasetName || creationCache?.dataset?.name}</div>
</div>
<div className={s.dividerLine}/>
</>
)}
{datasetId && (
<div className={s.creationInfo}>
<div className={s.title}>{t('datasetCreation.stepThree.additionTitle')}</div>
<div className={s.content}>{`${t('datasetCreation.stepThree.additionP1')} ${datasetName || creationCache?.dataset?.name} ${t('datasetCreation.stepThree.additionP2')}`}</div>
</div>
)}
<EmbeddingDetail
datasetId={datasetId || creationCache?.dataset?.id}
documentId={creationCache?.document.id}
indexingType={indexingType || creationCache?.dataset?.indexing_technique}
stopPosition='bottom'
detail={creationCache?.document}
/>
</div>
</div>
<div className={cn(s.sideTip)}>
<div className={s.tipCard}>
<span className={s.icon}/>
<div className={s.title}>{t('datasetCreation.stepThree.sideTipTitle')}</div>
<div className={s.content}>{t('datasetCreation.stepThree.sideTipContent')}</div>
</div>
</div>
</div>
)
}
export default StepThree;

View File

@@ -0,0 +1,382 @@
.pageHeader {
@apply px-16;
position: sticky;
top: 0;
left: 0;
padding-top: 42px;
padding-bottom: 12px;
background-color: #fff;
font-weight: 600;
font-size: 18px;
line-height: 28px;
color: #101828;
z-index: 10;
}
.fixed {
background: rgba(255, 255, 255, 0.9);
border-bottom: 0.5px solid #EAECF0;
backdrop-filter: blur(4px);
}
.form {
@apply px-16 pb-8;
}
.form .label {
@apply pt-6 pb-2;
font-weight: 500;
font-size: 16px;
line-height: 24px;
color: #344054;
}
.segmentationItem {
min-height: 68px;
}
.indexItem {
min-height: 146px;
}
.indexItem .disableMask {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(255, 255, 255, 0.5);
border-radius: 12px;
z-index: 2;
}
.indexItem .warningTip {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
padding: 8px 20px 8px 40px;
background: #FFFAEB;
border-top: 0.5px solid #FEF0C7;
border-radius: 12px;
font-size: 12px;
line-height: 18px;
color: #344054;
z-index: 3;
}
.indexItem .warningTip::before {
content: '';
position: absolute;
top: 11px;
left: 20px;
width: 12px;
height: 12px;
background: center no-repeat url(../assets/alert-triangle.svg);
background-size: 12px;
}
.indexItem .warningTip .click {
color: #155EEF;
cursor: pointer;
}
.indexItem.disabled:hover {
background-color: #fcfcfd;
border-color: #f2f4f7;
box-shadow: none;
cursor: default;
}
.indexItem.disabled:hover .radio {
@apply w-4 h-4 border-[2px] border-gray-200 rounded-full;
}
.radioItem {
@apply relative mb-2 rounded-xl border border-gray-100 cursor-pointer;
background-color: #fcfcfd;
}
.radioItem.segmentationItem.custom {
height: auto;
}
.radioItem.segmentationItem.custom .typeHeader {
/* height: 65px; */
}
.radioItem.indexItem .typeHeader {
@apply py-4 pr-5;
}
.radioItem.indexItem.active .typeHeader {
padding: 15.5px 19.5px 15.5px 63.5px;
}
.radioItem.indexItem .radio {
top: 16px;
right: 20px;
}
.radioItem.indexItem.active .radio {
top: 16px;
right: 19.5px;
}
.radioItem.indexItem .typeHeader .title {
@apply pb-1;
}
.radioItem.indexItem .typeHeader .tip {
@apply pb-3;
}
.radioItem .typeIcon {
position: absolute;
top: 18px;
left: 20px;
width: 32px;
height: 32px;
background: #EEF4FF center no-repeat;
border-radius: 8px;
}
.typeIcon.auto {
background-color: #F5F3FF;
background-image: url(../assets/zap-fast.svg);
}
.typeIcon.customize {
background-image: url(../assets/sliders-02.svg);
}
.typeIcon.qualified {
background-color: #FFF6ED;
background-image: url(../assets/star-07.svg);
}
.typeIcon.economical {
background-image: url(../assets/piggy-bank-01.svg);
}
.radioItem .radio {
@apply w-4 h-4 border-[2px] border-gray-200 rounded-full;
position: absolute;
top: 26px;
right: 20px;
}
.radioItem:hover {
background-color: #ffffff;
border-color: #B2CCFF;
box-shadow: 0px 12px 16px -4px rgba(16, 24, 40, 0.08), 0px 4px 6px -2px rgba(16, 24, 40, 0.03);
}
.radioItem:hover .radio {
border-color: #155eef;
}
.radioItem.active {
border-width: 1.5px;
border-color: #528BFF;
box-shadow: 0px 1px 3px rgba(16, 24, 40, 0.1), 0px 1px 2px rgba(16, 24, 40, 0.06);
}
.radioItem.active .radio {
top: 25.5px;
right: 19.5px;
border-width: 5px;
border-color: #155EEF;
}
.radioItem.active:hover {
border-width: 1.5px;
border-color: #528BFF;
box-shadow: 0px 1px 3px rgba(16, 24, 40, 0.1), 0px 1px 2px rgba(16, 24, 40, 0.06);
}
.radioItem.active .typeIcon {
top: 17.5px;
left: 19.5px;
}
.radioItem.active .typeHeader {
padding: 11.5px 63.5px;
}
.typeHeader {
@apply flex flex-col px-16 py-3 justify-center;
}
.typeHeader .title {
display: flex;
align-items: center;
padding-bottom: 2px;
font-weight: 500;
font-size: 16px;
line-height: 24px;
color: #101828;
}
.typeHeader .tip {
font-weight: 400;
font-size: 13px;
line-height: 18px;
color: #667085;
}
.recommendTag {
display: inline-flex;
justify-content: center;
align-items: center;
padding: 0 6px;
margin-left: 4px;
border: 1px solid #E0EAFF;
border-radius: 6px;
font-weight: 500;
font-size: 12px;
line-height: 20px;
color: #444CE7;
}
.typeFormBody {
@apply px-16;
border-top: 1px solid #F2F4F7;
}
.formRow {
@apply flex justify-between mt-6;
}
.formRow .label {
@apply mb-2 p-0;
font-weight: 500;
font-size: 14px;
line-height: 20px;
color: #101828;
}
.ruleItem {
@apply flex items-center h-7;
}
.formFooter {
padding: 16px 0 28px;
}
.formFooter .button {
font-size: 13px;
line-height: 18px;
}
.input {
@apply inline-flex h-9 w-full py-1 px-2 rounded-lg text-xs leading-normal;
@apply bg-gray-100 caret-primary-600 hover:bg-gray-100 focus:ring-1 focus:ring-inset focus:ring-gray-200 focus-visible:outline-none focus:bg-white placeholder:text-gray-400;
}
.file {
@apply flex justify-between items-center mt-8 px-6 py-4 rounded-xl bg-gray-50;
}
.file .divider {
@apply shrink-0 mx-4 w-px bg-gray-200;
height: 42px;
}
.fileIcon {
@apply inline-flex mr-1 w-6 h-6 bg-center bg-no-repeat;
background-image: url(../assets/pdf.svg);
background-size: 24px;
}
.fileIcon.pdf {
background-image: url(../assets/pdf.svg);
}
.fileIcon.html,
.fileIcon.htm {
background-image: url(../assets/html.svg);
}
.fileIcon.md,
.fileIcon.markdown {
background-image: url(../assets/md.svg);
}
.fileIcon.txt {
background-image: url(../assets/txt.svg);
}
.fileIcon.json {
background-image: url(../assets/json.svg);
}
.fileContent {
flex: 1 1 50%;
}
.divider {
@apply mx-3 w-px h-4 bg-gray-200;
}
.calculating {
color: #98A2B3;
font-size: 12px;
line-height: 18px;
}
.sideTip {
@apply flex flex-col items-center shrink-0;
padding-top: 108px;
width: 524px;
border-left: 0.5px solid #F2F4F7;
}
.tipCard {
@apply flex flex-col items-start p-6;
width: 320px;
background-color: #F9FAFB;
box-shadow: 0px 1px 2px rgba(16, 24, 40, 0.05);
border-radius: 12px;
}
.tipCard .icon {
width: 32px;
height: 32px;
border: 1px solid #EAECF0;
border-radius: 6px;
background: center no-repeat url(../assets/book-open-01.svg);
background-size: 16px;
}
.tipCard .title {
margin: 12px 0;
font-weight: 500;
font-size: 16px;
line-height: 24px;
color: #344054;
}
.tipCard .content {
font-weight: 400;
font-size: 14px;
line-height: 20px;
color: #344054;
}
.previewWrap {
flex-shrink: 0;
width: 524px;
}
.previewHeader {
position: sticky;
top: 0;
left: 0;
padding-top: 42px;
background-color: #fff;
font-weight: 600;
font-size: 18px;
line-height: 28px;
color: #101828;
z-index: 10;
}

View File

@@ -0,0 +1,491 @@
'use client'
import React, { useState, useRef, useEffect, useLayoutEffect } from 'react'
import { useTranslation } from 'react-i18next'
import { useBoolean } from 'ahooks'
import type { File, PreProcessingRule, Rules, FileIndexingEstimateResponse as IndexingEstimateResponse } from '@/models/datasets'
import {
fetchDefaultProcessRule,
createFirstDocument,
createDocument,
fetchFileIndexingEstimate as didFetchFileIndexingEstimate,
} from '@/service/datasets'
import type { CreateDocumentReq, createDocumentResponse } from '@/models/datasets'
import Button from '@/app/components/base/button'
import PreviewItem from './preview-item'
import Loading from '@/app/components/base/loading'
import { XMarkIcon } from '@heroicons/react/20/solid'
import cn from 'classnames'
import s from './index.module.css'
import Link from 'next/link'
import Toast from '@/app/components/base/toast'
import { formatNumber } from '@/utils/format'
type StepTwoProps = {
hasSetAPIKEY: boolean,
onSetting: () => void,
datasetId?: string,
indexingType?: string,
file?: File,
onStepChange: (delta: number) => void,
updateIndexingTypeCache: (type: string) => void,
updateResultCache: (res: createDocumentResponse) => void
}
enum SegmentType {
AUTO = 'automatic',
CUSTOM = 'custom',
}
enum IndexingType {
QUALIFIED = 'high_quality',
ECONOMICAL = 'economy',
}
const StepTwo = ({
hasSetAPIKEY,
onSetting,
datasetId,
indexingType,
file,
onStepChange,
updateIndexingTypeCache,
updateResultCache,
}: StepTwoProps) => {
const { t } = useTranslation()
const scrollRef = useRef<HTMLDivElement>(null)
const [scrolled, setScrolled] = useState(false)
const previewScrollRef = useRef<HTMLDivElement>(null)
const [previewScrolled, setPreviewScrolled] = useState(false)
const [segmentationType, setSegmentationType] = useState<SegmentType>(SegmentType.AUTO)
const [segmentIdentifier, setSegmentIdentifier] = useState('\\n')
const [max, setMax] = useState(1000)
const [rules, setRules] = useState<PreProcessingRule[]>([])
const [defaultConfig, setDefaultConfig] = useState<Rules>()
const hasSetIndexType = !!indexingType
const [indexType, setIndexType] = useState<IndexingType>(
indexingType ||
hasSetAPIKEY ? IndexingType.QUALIFIED : IndexingType.ECONOMICAL
)
const [showPreview, { setTrue: setShowPreview, setFalse: hidePreview }] = useBoolean()
const [customFileIndexingEstimate, setCustomFileIndexingEstimate] = useState<IndexingEstimateResponse | null>(null)
const [automaticFileIndexingEstimate, setAutomaticFileIndexingEstimate] = useState<IndexingEstimateResponse | null>(null)
const fileIndexingEstimate = (() => {
return segmentationType === SegmentType.AUTO ? automaticFileIndexingEstimate : customFileIndexingEstimate
})()
const scrollHandle = (e: any) => {
if (e.target.scrollTop > 0) {
setScrolled(true)
} else {
setScrolled(false)
}
}
const previewScrollHandle = (e: any) => {
if (e.target.scrollTop > 0) {
setPreviewScrolled(true)
} else {
setPreviewScrolled(false)
}
}
const getFileName = (name: string) => {
const arr = name.split('.')
return arr.slice(0, -1).join('.')
}
const getRuleName = (key: string) => {
if (key === 'remove_extra_spaces') {
return t('datasetCreation.stepTwo.removeExtraSpaces')
}
if (key === 'remove_urls_emails') {
return t('datasetCreation.stepTwo.removeUrlEmails')
}
if (key === 'remove_stopwords') {
return t('datasetCreation.stepTwo.removeStopwords')
}
}
const ruleChangeHandle = (id: string) => {
const newRules = rules.map(rule => {
if (rule.id === id) {
return {
id: rule.id,
enabled: !rule.enabled,
}
}
return rule
})
setRules(newRules)
}
const resetRules = () => {
if (defaultConfig) {
setSegmentIdentifier(defaultConfig.segmentation.separator === '\n' ? '\\n' : defaultConfig.segmentation.separator || '\\n')
setMax(defaultConfig.segmentation.max_tokens)
setRules(defaultConfig.pre_processing_rules)
}
}
const confirmChangeCustomConfig = async () => {
setCustomFileIndexingEstimate(null)
setShowPreview()
await fetchFileIndexingEstimate()
}
const getIndexing_technique = () => indexingType ? indexingType : indexType
const getProcessRule = () => {
const processRule: any = {
rules: {}, // api will check this. It will be removed after api refactored.
mode: segmentationType,
}
if (segmentationType === SegmentType.CUSTOM) {
const ruleObj = {
pre_processing_rules: rules,
segmentation: {
separator: segmentIdentifier === '\\n' ? '\n' : segmentIdentifier,
max_tokens: max,
},
}
processRule.rules = ruleObj
}
return processRule
}
const getFileIndexingEstimateParams = () => {
const params = {
file_id: file?.id,
dataset_id: datasetId,
indexing_technique: getIndexing_technique(),
process_rule: getProcessRule(),
}
return params
}
const fetchFileIndexingEstimate = async () => {
const res = await didFetchFileIndexingEstimate(getFileIndexingEstimateParams())
if (segmentationType === SegmentType.CUSTOM) {
setCustomFileIndexingEstimate(res)
}
else {
setAutomaticFileIndexingEstimate(res)
}
}
const getCreationParams = () => {
const params = {
data_source: {
type: 'upload_file',
info: file?.id,
name: file?.name,
},
indexing_technique: getIndexing_technique(),
process_rule: getProcessRule(),
} as CreateDocumentReq
return params
}
const getRules = async () => {
try {
const res = await fetchDefaultProcessRule({ url: '/datasets/process-rule' })
const separator = res.rules.segmentation.separator
setSegmentIdentifier(separator === '\n' ? '\\n' : separator || '\\n')
setMax(res.rules.segmentation.max_tokens)
setRules(res.rules.pre_processing_rules)
setDefaultConfig(res.rules)
}
catch (err) {
console.log(err)
}
}
const createHandle = async () => {
try {
let res;
const params = getCreationParams()
if (!datasetId) {
res = await createFirstDocument({
body: params
})
updateIndexingTypeCache(indexType)
updateResultCache(res)
} else {
res = await createDocument({
datasetId,
body: params
})
updateIndexingTypeCache(indexType)
updateResultCache({
document: res,
})
}
onStepChange(+1)
}
catch (err) {
Toast.notify({
type: 'error',
message: err + '',
})
}
}
useEffect(() => {
// fetch rules
getRules()
}, [])
useEffect(() => {
scrollRef.current?.addEventListener('scroll', scrollHandle);
return () => {
scrollRef.current?.removeEventListener('scroll', scrollHandle);
}
}, [])
useLayoutEffect(() => {
if (showPreview) {
previewScrollRef.current?.addEventListener('scroll', previewScrollHandle);
return () => {
previewScrollRef.current?.removeEventListener('scroll', previewScrollHandle);
}
}
}, [showPreview])
useEffect(() => {
// get indexing type by props
if (indexingType) {
setIndexType(indexingType as IndexingType)
} else {
setIndexType(hasSetAPIKEY ? IndexingType.QUALIFIED : IndexingType.ECONOMICAL)
}
}, [hasSetAPIKEY, indexingType, datasetId])
useEffect(() => {
if (segmentationType === SegmentType.AUTO) {
setAutomaticFileIndexingEstimate(null)
setShowPreview()
fetchFileIndexingEstimate()
} else {
hidePreview()
setCustomFileIndexingEstimate(null)
}
}, [segmentationType, indexType])
return (
<div className='flex w-full h-full'>
<div ref={scrollRef} className='relative h-full w-full overflow-y-scroll'>
<div className={cn(s.pageHeader, scrolled && s.fixed)}>{t('datasetCreation.steps.two')}</div>
<div className={cn(s.form)}>
<div className={s.label}>{t('datasetCreation.stepTwo.segmentation')}</div>
<div className='max-w-[640px]'>
<div
className={cn(
s.radioItem,
s.segmentationItem,
segmentationType === SegmentType.AUTO && s.active
)}
onClick={() => setSegmentationType(SegmentType.AUTO)}
>
<span className={cn(s.typeIcon, s.auto)} />
<span className={cn(s.radio)} />
<div className={s.typeHeader}>
<div className={s.title}>{t('datasetCreation.stepTwo.auto')}</div>
<div className={s.tip}>{t('datasetCreation.stepTwo.autoDescription')}</div>
</div>
</div>
<div
className={cn(
s.radioItem,
s.segmentationItem,
segmentationType === SegmentType.CUSTOM && s.active,
segmentationType === SegmentType.CUSTOM && s.custom,
)}
onClick={() => setSegmentationType(SegmentType.CUSTOM)}
>
<span className={cn(s.typeIcon, s.customize)} />
<span className={cn(s.radio)} />
<div className={s.typeHeader}>
<div className={s.title}>{t('datasetCreation.stepTwo.custom')}</div>
<div className={s.tip}>{t('datasetCreation.stepTwo.customDescription')}</div>
</div>
{segmentationType === SegmentType.CUSTOM && (
<div className={s.typeFormBody}>
<div className={s.formRow}>
<div className='w-full'>
<div className={s.label}>{t('datasetCreation.stepTwo.separator')}</div>
<input
type="text"
className={s.input}
placeholder={t('datasetCreation.stepTwo.separatorPlaceholder') || ''} value={segmentIdentifier}
onChange={(e) => setSegmentIdentifier(e.target.value)}
/>
</div>
</div>
<div className={s.formRow}>
<div className='w-full'>
<div className={s.label}>{t('datasetCreation.stepTwo.maxLength')}</div>
<input
type="number"
className={s.input}
placeholder={t('datasetCreation.stepTwo.separatorPlaceholder') || ''} value={max}
onChange={(e) => setMax(Number(e.target.value))}
/>
</div>
</div>
<div className={s.formRow}>
<div className='w-full'>
<div className={s.label}>{t('datasetCreation.stepTwo.rules')}</div>
{rules.map(rule => (
<div key={rule.id} className={s.ruleItem}>
<input id={rule.id} type="checkbox" defaultChecked={rule.enabled} onChange={() => ruleChangeHandle(rule.id)} className="w-4 h-4 rounded border-gray-300 text-blue-700 focus:ring-blue-700" />
<label htmlFor={rule.id} className="ml-2 text-sm font-normal cursor-pointer text-gray-800">{getRuleName(rule.id)}</label>
</div>
))}
</div>
</div>
<div className={s.formFooter}>
<Button type="primary" className={cn(s.button, '!h-8 text-primary-600')} onClick={confirmChangeCustomConfig}>{t('datasetCreation.stepTwo.preview')}</Button>
<Button className={cn(s.button, 'ml-2 !h-8')} onClick={resetRules}>{t('datasetCreation.stepTwo.reset')}</Button>
</div>
</div>
)}
</div>
</div>
<div className={s.label}>{t('datasetCreation.stepTwo.indexMode')}</div>
<div className='max-w-[640px]'>
<div className='flex items-center gap-3'>
{(!hasSetIndexType || (hasSetIndexType && indexingType === IndexingType.QUALIFIED)) && (
<div
className={cn(
s.radioItem,
s.indexItem,
!hasSetAPIKEY && s.disabled,
!hasSetIndexType && indexType === IndexingType.QUALIFIED && s.active,
hasSetIndexType && s.disabled,
hasSetIndexType && '!w-full',
)}
onClick={() => {
if (hasSetAPIKEY) {
setIndexType(IndexingType.QUALIFIED)
}
}}
>
<span className={cn(s.typeIcon, s.qualified)} />
{!hasSetIndexType && <span className={cn(s.radio)} />}
<div className={s.typeHeader}>
<div className={s.title}>
{t('datasetCreation.stepTwo.qualified')}
{!hasSetIndexType && <span className={s.recommendTag}>{t('datasetCreation.stepTwo.recommend')}</span>}
</div>
<div className={s.tip}>{t('datasetCreation.stepTwo.qualifiedTip')}</div>
<div className='pb-0.5 text-xs font-medium text-gray-500'>{t('datasetCreation.stepTwo.emstimateCost')}</div>
{
!!fileIndexingEstimate ? (
<div className='text-xs font-medium text-gray-800'>{formatNumber(fileIndexingEstimate.tokens)} tokens(<span className='text-yellow-500'>${formatNumber(fileIndexingEstimate.total_price)}</span>)</div>
) : (
<div className={s.calculating}>{t('datasetCreation.stepTwo.calculating')}</div>
)
}
</div>
{!hasSetAPIKEY && (
<div className={s.warningTip}>
<span>{t('datasetCreation.stepTwo.warning')}&nbsp;</span>
<span className={s.click} onClick={onSetting}>{t('datasetCreation.stepTwo.click')}</span>
</div>
)}
</div>
)}
{(!hasSetIndexType || (hasSetIndexType && indexingType === IndexingType.ECONOMICAL)) && (
<div
className={cn(
s.radioItem,
s.indexItem,
!hasSetIndexType && indexType === IndexingType.ECONOMICAL && s.active,
hasSetIndexType && s.disabled,
hasSetIndexType && '!w-full',
)}
onClick={() => !hasSetIndexType && setIndexType(IndexingType.ECONOMICAL)}
>
<span className={cn(s.typeIcon, s.economical)} />
{!hasSetIndexType && <span className={cn(s.radio)} />}
<div className={s.typeHeader}>
<div className={s.title}>{t('datasetCreation.stepTwo.economical')}</div>
<div className={s.tip}>{t('datasetCreation.stepTwo.economicalTip')}</div>
<div className='pb-0.5 text-xs font-medium text-gray-500'>{t('datasetCreation.stepTwo.emstimateCost')}</div>
<div className='text-xs font-medium text-gray-800'>0 tokens</div>
</div>
</div>
)}
</div>
{hasSetIndexType && (
<div className='mt-2 text-xs text-gray-500 font-medium'>
{t('datasetCreation.stepTwo.indexSettedTip')}
<Link className='text-[#155EEF]' href={`/datasets/${datasetId}/settings`}>{t('datasetCreation.stepTwo.datasetSettingLink')}</Link>
</div>
)}
<div className={s.file}>
<div className={s.fileContent}>
<div className='mb-2 text-xs font-medium text-gray-500'>{t('datasetCreation.stepTwo.fileName')}</div>
<div className='flex items-center text-sm leading-6 font-medium text-gray-800'>
<span className={cn(s.fileIcon, file && s[file.extension])} />
{getFileName(file?.name || '')}
</div>
</div>
<div className={s.divider} />
<div className={s.fileContent}>
<div className='mb-2 text-xs font-medium text-gray-500'>{t('datasetCreation.stepTwo.emstimateSegment')}</div>
<div className='flex items-center text-sm leading-6 font-medium text-gray-800'>
{
!!fileIndexingEstimate ? (
<div className='text-xs font-medium text-gray-800'>{formatNumber(fileIndexingEstimate.total_segments)} </div>
) : (
<div className={s.calculating}>{t('datasetCreation.stepTwo.calculating')}</div>
)
}
</div>
</div>
</div>
<div className='flex items-center mt-8 py-2'>
<Button onClick={() => onStepChange(-1)}>{t('datasetCreation.stepTwo.lastStep')}</Button>
<div className={s.divider} />
<Button type='primary' onClick={createHandle}>{t('datasetCreation.stepTwo.nextStep')}</Button>
</div>
</div>
</div>
</div>
{(showPreview) ? (
<div ref={previewScrollRef} className={cn(s.previewWrap, 'relativeh-full overflow-y-scroll border-l border-[#F2F4F7]')}>
<div className={cn(s.previewHeader, previewScrolled && `${s.fixed} pb-3`, ' flex items-center justify-between px-8')}>
<span>{t('datasetCreation.stepTwo.previewTitle')}</span>
<div className='flex items-center justify-center w-6 h-6 cursor-pointer' onClick={hidePreview}>
<XMarkIcon className='h-4 w-4'></XMarkIcon>
</div>
</div>
<div className='my-4 px-8 space-y-4'>
{fileIndexingEstimate?.preview ? (
<>
{fileIndexingEstimate?.preview.map((item, index) => (
<PreviewItem key={item} content={item} index={index + 1} />
))}
</>
) : <div className='flex items-center justify-center h-[200px]'><Loading type='area'></Loading></div>
}
</div>
</div>
) :
(<div className={cn(s.sideTip)}>
<div className={s.tipCard}>
<span className={s.icon} />
<div className={s.title}>{t('datasetCreation.stepTwo.sideTipTitle')}</div>
<div className={s.content}>
<p className='mb-3'>{t('datasetCreation.stepTwo.sideTipP1')}</p>
<p className='mb-3'>{t('datasetCreation.stepTwo.sideTipP2')}</p>
<p className='mb-3'>{t('datasetCreation.stepTwo.sideTipP3')}</p>
<p>{t('datasetCreation.stepTwo.sideTipP4')}</p>
</div>
</div>
</div>)}
</div>
)
}
export default StepTwo

View File

@@ -0,0 +1,49 @@
'use client'
import React, { FC } from 'react'
import { useTranslation } from 'react-i18next'
export interface IPreviewItemProps {
index: number
content: string
}
const sharpIcon = (
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4.74999 1.5L3.24999 10.5M8.74998 1.5L7.24998 10.5M10.25 4H1.75M9.75 8H1.25" stroke="#98A2B3" strokeLinecap="round" strokeLinejoin="round" />
</svg>
)
const textIcon = (
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4 3.5H8M6 3.5V8.5M3.9 10.5H8.1C8.94008 10.5 9.36012 10.5 9.68099 10.3365C9.96323 10.1927 10.1927 9.96323 10.3365 9.68099C10.5 9.36012 10.5 8.94008 10.5 8.1V3.9C10.5 3.05992 10.5 2.63988 10.3365 2.31901C10.1927 2.03677 9.96323 1.8073 9.68099 1.66349C9.36012 1.5 8.94008 1.5 8.1 1.5H3.9C3.05992 1.5 2.63988 1.5 2.31901 1.66349C2.03677 1.8073 1.8073 2.03677 1.66349 2.31901C1.5 2.63988 1.5 3.05992 1.5 3.9V8.1C1.5 8.94008 1.5 9.36012 1.66349 9.68099C1.8073 9.96323 2.03677 10.1927 2.31901 10.3365C2.63988 10.5 3.05992 10.5 3.9 10.5Z" stroke="#667085" strokeLinecap="round" strokeLinejoin="round" />
</svg>
)
const PreviewItem: FC<IPreviewItemProps> = ({
index,
content,
}) => {
const { t } = useTranslation()
const charNums = (content || '').length
const formatedIndex = (() => (index + '').padStart(3, '0'))()
return (
<div className='p-4 rounded-xl bg-gray-50'>
<div className='flex items-center justify-between h-5 text-xs text-gray-500'>
<div className='flex items-center h-[18px] space-x-1 border border-gray-200 box-border rounded-md italic pl-1 pr-1.5 font-medium'>
{sharpIcon}
<span>{formatedIndex}</span>
</div>
<div className='flex items-center space-x-1'>
{textIcon}
<span>{charNums} {t('datasetCreation.stepTwo.characters')}</span>
</div>
</div>
<div className='mt-2 max-h-[120px] line-clamp-6 overflow-hidden text-sm text-gray-800'>
{content}
</div>
</div>
)
}
export default React.memo(PreviewItem)

View File

@@ -0,0 +1,106 @@
.stepsHeader {
@apply flex items-center px-6 py-6;
color: #344054;
font-weight: 600;
font-size: 14px;
line-height: 20px;
}
.navBack {
@apply box-border flex justify-center items-center mr-3 w-8 h-8 bg-white bg-center bg-no-repeat cursor-pointer hover:border-gray-300;
border: 0.5px solid #F2F4F7;
box-shadow: 0px 12px 16px -4px rgba(16, 24, 40, 0.08), 0px 4px 6px -2px rgba(16, 24, 40, 0.03);
border-radius: 32px;
background-image: url(../assets/arrow-narrow-left.svg);
background-size: 16px;
}
.stepList {
@apply p-4;
line-height: 18px;
}
.stepItem {
@apply relative flex justify-items-start pt-3 pr-0 pb-3;
padding-left: 52px;
font-size: 13px;
}
.stepItem.step1::before {
content: '';
position: absolute;
bottom: 0;
left: 23px;
width: 2px;
height: 7px;
background-color: #f2f4f7;
}
.stepItem.step2::before {
content: '';
position: absolute;
top: 0;
left: 23px;
width: 2px;
height: 100%;
background-color: #f2f4f7;
}
.stepItem.step2::after {
content: '';
position: absolute;
top: 6px;
left: 23px;
width: 2px;
height: 28px;
background-color: #fff;
}
.stepItem.step3::before {
content: '';
position: absolute;
top: 0;
left: 23px;
width: 2px;
height: 7px;
background-color: #f2f4f7;
}
.stepNum {
@apply box-border absolute top-2 left-3 flex justify-center items-center w-6 h-6;
color: #98a2b3;
font-size: 12px;
border: 1px solid #F2F4F7;
border-radius: 24px;
z-index: 1;
}
.stepName {
color: #98a2b3;
}
.stepItem.active .stepNum {
color: #1c64f2;
background-color: #EFF4FF;
border: none;
}
.stepItem.active .stepName {
color: #1c64f2;
}
.stepItem.done .stepNum {
color: #667085;
background-color: #f2f4f7;
border: none;
}
.stepItem.done .stepNum::after {
content: '';
display: flex;
width: 12px;
height: 12px;
background: center no-repeat url(../assets/check.svg);
background-size: 12px;
}
.stepItem.done .stepName {
color: #667085;
}

View File

@@ -0,0 +1,51 @@
'use client'
import { useTranslation } from 'react-i18next'
import { useRouter } from 'next/navigation'
import cn from 'classnames'
import s from './index.module.css'
type IStepsNavBarProps = {
step: number,
datasetId?: string,
}
const StepsNavBar = ({
step,
datasetId,
}: IStepsNavBarProps) => {
const { t } = useTranslation()
const router = useRouter()
const navBackHandle = () => {
if (!datasetId) {
router.replace('/datasets')
} else {
router.replace(`/datasets/${datasetId}/documents`)
}
}
return (
<div className='w-full pt-4'>
<div className={s.stepsHeader}>
<div onClick={navBackHandle} className={s.navBack} />
{!datasetId ? t('datasetCreation.steps.header.creation') : t('datasetCreation.steps.header.update')}
</div>
<div className={cn(s.stepList)}>
<div className={cn(s.stepItem, s.step1, step === 1 && s.active, step !== 1 && s.done)}>
<div className={cn(s.stepNum)}>{step === 1 ? 1 : ''}</div>
<div className={cn(s.stepName)}>{t('datasetCreation.steps.one')}</div>
</div>
<div className={cn(s.stepItem, s.step2, step === 2 && s.active, step === 3 && s.done)}>
<div className={cn(s.stepNum)}>{step !== 3 ? 2 : ''}</div>
<div className={cn(s.stepName)}>{t('datasetCreation.steps.two')}</div>
</div>
<div className={cn(s.stepItem, s.step3, step === 3 && s.active)}>
<div className={cn(s.stepNum)}>3</div>
<div className={cn(s.stepName)}>{t('datasetCreation.steps.three')}</div>
</div>
</div>
</div>
)
}
export default StepsNavBar

View File

@@ -0,0 +1,37 @@
.modal {
position: relative;
}
.modal .icon {
width: 48px;
height: 48px;
background: rgba(255, 255, 255, 0.9) center no-repeat url(../assets/annotation-info.svg);
background-size: 24px;
border: 0.5px solid #F2F4F7;
box-shadow: 0px 20px 24px -4px rgba(16, 24, 40, 0.08), 0px 8px 8px -4px rgba(16, 24, 40, 0.03);
border-radius: 12px;
}
.modal .close {
position: absolute;
right: 16px;
top: 16px;
width: 32px;
height: 32px;
border-radius: 8px;
background: center no-repeat url(../assets/close.svg);
background-size: 16px;
cursor: pointer;
}
.modal .title {
@apply mt-3 mb-1;
font-weight: 600;
font-size: 20px;
line-height: 30px;
color: #101828;
}
.modal .content {
@apply mb-10;
font-weight: 400;
font-size: 14px;
line-height: 20px;
color: #667085;
}

View File

@@ -0,0 +1,46 @@
'use client'
import React from 'react'
import { useTranslation } from 'react-i18next'
import Modal from '@/app/components/base/modal'
import Button from '@/app/components/base/button'
import cn from 'classnames'
import s from './index.module.css'
type IProps = {
show: boolean,
onConfirm: () => void,
onHide: () => void,
}
const StopEmbeddingModal = ({
show = false,
onConfirm,
onHide,
}: IProps) => {
const { t } = useTranslation()
const submit = () => {
onConfirm()
onHide()
}
return (
<Modal
isShow={show}
onClose={onHide}
className={cn(s.modal, '!max-w-[480px]', 'px-8')}
>
<div className={s.icon}/>
<span className={s.close} onClick={onHide}/>
<div className={s.title}>{t('datasetCreation.stepThree.modelTitle')}</div>
<div className={s.content}>{t('datasetCreation.stepThree.modelContent')}</div>
<div className='flex flex-row-reverse'>
<Button className='w-24 ml-2' type='primary' onClick={submit}>{t('datasetCreation.stepThree.modelButtonConfirm')}</Button>
<Button className='w-24' onClick={onHide}>{t('datasetCreation.stepThree.modelButtonCancel')}</Button>
</div>
</Modal>
)
}
export default StopEmbeddingModal