Add new side menu navigation (#819)

Update snapshots

Fix savebar

Fix cypress

Update messages

Fix cypress
This commit is contained in:
Dominik Żegleń 2020-11-18 16:11:15 +01:00 committed by GitHub
parent 6d31be7c2c
commit 33d680639b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
34 changed files with 1057 additions and 405 deletions

View file

@ -0,0 +1,5 @@
<svg width="36" height="33" viewBox="0 0 36 33" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.6072 33C22.4977 33 23.9789 30.6214 23.9789 27.3629C23.9789 23.3549 20.3772 22.6056 17.3814 22.1167C15.0924 21.7258 14.0489 21.5304 14.0489 20.1292C14.0489 19.0867 14.9577 18.6954 16.4389 18.6954C18.2566 18.6954 18.7614 19.2168 18.9298 20.7482L23.7097 20.0314C23.3055 16.7404 21.4542 15.0787 16.5735 15.0787C11.2216 15.0787 9.33654 17.2293 9.33654 20.6504C9.30299 25.082 13.4768 25.5382 16.5735 26.0594C18.492 26.418 19.2328 26.7437 19.2328 28.0146C19.2328 29.0573 18.5933 29.5135 16.6745 29.5135C14.5539 29.5135 13.9144 29.1551 13.6451 27.4281L9 28.1124C9.43753 31.599 11.4908 33 16.6072 33Z" fill="#28234A"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M19.7838 0L13.4043 6.64709H29.1638L35.5433 0H19.7838Z" fill="#8AC4EB"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.15911 2.31187C6.27552 2.1958 6.4332 2.13062 6.59759 2.13062H27.3248C27.5761 2.13062 27.8026 2.28211 27.8987 2.51437C27.9947 2.74664 27.9412 3.01388 27.7632 3.19134L21.7867 9.1508C21.6703 9.26687 21.5126 9.33205 21.3482 9.33205H0.621008C0.369679 9.33205 0.143131 9.18056 0.0471181 8.94829C-0.0488948 8.71603 0.00456112 8.44879 0.182532 8.27133L6.15911 2.31187ZM6.85429 3.37259L2.12325 8.09007H21.0915L25.8225 3.37259H6.85429Z" fill="#28234A"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -1,3 +1,3 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"> <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="M12.375 1.625H1.625V12.375H12.375V1.625ZM0 0V14H14V0H0ZM12.375 19.625H1.625V30.375H12.375V19.625ZM0 18V32H14V18H0ZM19.625 19.625H30.375V30.375H19.625V19.625ZM18 32V18H32V32H18ZM24.25 2H25.875V6.125H30V7.75H25.875V11.875H24.25V7.75H20.125V6.125H24.25V2Z" fill="#3D3D3D"/> <path fill-rule="evenodd" clip-rule="evenodd" d="M24 0H14V10H24V0ZM0 14H10V24H0V14ZM14 14H24V24H14V14ZM4 0H6V4L10 4V6H6V10H4V6H0V4L4 4V0Z" fill="currentColor"/>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 423 B

After

Width:  |  Height:  |  Size: 264 B

View file

@ -1,3 +1,3 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"> <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 0L32 5.74429V26.5168L16 32L0 26.5168V5.74429L16 0ZM11.0139 3.1253L24.6012 7.682L29.4131 6.15075L16 1.3352L11.0139 3.1253ZM30.7451 7.04569L16.6275 11.5382V30.4565L30.7451 25.6184V7.04569ZM15.3726 30.4565V11.5382L1.2549 7.04569V25.6184L15.3726 30.4565ZM2.58688 6.15075L16 10.4191L22.5732 8.32736L9.10504 3.81061L2.58688 6.15075Z" fill="#3D3D3D"/> <path fill-rule="evenodd" clip-rule="evenodd" d="M0.46875 4.07018L11.9062 8.09357L23.4375 4.07018L11.9062 0L0.46875 4.07018ZM0 6.22222L10.6875 9.87134V24L0 20.3509V6.22222ZM24 6.22222L13.3125 9.87134V24L24 20.3509V6.22222Z" fill="currentColor" />
</svg> </svg>

Before

Width:  |  Height:  |  Size: 501 B

After

Width:  |  Height:  |  Size: 350 B

View file

@ -1,3 +1,3 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"> <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="M11.8982 1.55016L13.3465 4.12742L14.18 4.02305C14.6746 3.96111 15.179 3.92913 15.6915 3.92913C16.1878 3.92913 16.6765 3.95911 17.156 4.01724L17.9864 4.11791L19.4293 1.55016L23.3858 3.05016L22.4034 5.93429L23.1024 6.48141C23.8614 7.07548 24.5475 7.75873 25.1448 8.51532L25.6426 9.1458L28.6985 8.39818L30.2711 12.2122L27.5599 13.7725L27.6537 14.5887C27.7061 15.0455 27.7332 15.5105 27.7332 15.9823C27.7332 16.4721 27.704 16.9545 27.6476 17.428L27.5491 18.2536L30.3925 19.8654L28.6492 23.7375L25.5782 22.9128L25.0672 23.5465C24.5021 24.2473 23.8602 24.8834 23.1545 25.4421L22.4726 25.9819L23.356 28.6976L19.2006 30.1655L17.8515 27.87L17.0457 27.9602C16.6016 28.0098 16.1498 28.0354 15.6915 28.0354C15.1849 28.0354 14.6861 28.0042 14.1968 27.9436L13.3645 27.8406L11.8982 30.4498L7.94167 28.9498L8.94434 26.0062L8.24955 25.4587C7.51643 24.881 6.85187 24.2198 6.27026 23.4896L5.75832 22.8469L2.8981 23.6227L1.4998 19.8502L3.8209 18.1465L3.73487 17.4227C3.6788 16.9508 3.6499 16.4702 3.6499 15.9823C3.6499 15.5144 3.67647 15.0532 3.72809 14.6001L3.82093 13.7852L1.63811 12.5273L3.53763 8.66363L5.69954 9.20458L6.19976 8.56429C6.7957 7.80148 7.48143 7.11226 8.24092 6.51265L8.93454 5.96504L7.94167 3.05016L11.8982 1.55016ZM24.9586 2.30961L18.8666 0L17.3064 2.77633C16.7771 2.71216 16.2382 2.67913 15.6915 2.67913C15.127 2.67913 14.5707 2.71436 14.0247 2.78273L12.4609 0L6.3689 2.30961L7.46636 5.53155C6.62851 6.19302 5.87212 6.95327 5.21473 7.79473L2.86141 7.2059L1.89925e-05 13.026L2.48612 14.4587C2.42916 14.9586 2.3999 15.467 2.3999 15.9823C2.3999 16.5196 2.43173 17.0495 2.4936 17.5702L0 19.4004L2.12299 25.1282L5.29251 24.2684C5.93408 25.0739 6.66711 25.8032 7.47588 26.4405L6.3689 29.6904L12.4609 32L14.0433 29.1841C14.5833 29.251 15.1334 29.2854 15.6915 29.2854C16.1963 29.2854 16.6946 29.2572 17.1847 29.2024L18.6452 31.6874L24.9218 29.4702L23.9303 26.4222C24.7089 25.8059 25.4169 25.1042 26.0402 24.3312L29.3524 25.2206L32 19.3398L28.8888 17.5761C28.9511 17.0535 28.9832 16.5217 28.9832 15.9823C28.9832 15.4627 28.9534 14.9501 28.8955 14.4461L31.8445 12.7489L29.4447 6.92875L26.1259 7.74071C25.4669 6.90612 24.7101 6.15246 23.8729 5.49709L24.9586 2.30961ZM20.625 16C20.625 18.5543 18.5543 20.625 16 20.625C13.4457 20.625 11.375 18.5543 11.375 16C11.375 13.4457 13.4457 11.375 16 11.375C18.5543 11.375 20.625 13.4457 20.625 16ZM16 21.875C19.2447 21.875 21.875 19.2447 21.875 16C21.875 12.7553 19.2447 10.125 16 10.125C12.7553 10.125 10.125 12.7553 10.125 16C10.125 19.2447 12.7553 21.875 16 21.875Z" fill="#3D3D3D"/> <path d="M20.7101 8.77354L20.3013 7.80451C21.7011 4.64075 21.6083 4.54674 21.3365 4.2723L19.5483 2.52524L19.3708 2.37571H19.1637C19.0544 2.37571 18.7283 2.37571 16.0101 3.6086L15.0096 3.20523C13.7167 0 13.5841 0 13.2055 0H10.6829C10.3047 0 10.1577 -0.000423225 8.95855 3.21665L7.96243 3.62108C6.12551 2.84545 5.04821 2.4528 4.75748 2.4528L4.51902 2.46021L2.59563 4.346C2.30377 4.62044 2.20192 4.71721 3.68195 7.83202L3.2747 8.79766C0 10.0636 0 10.1864 0 10.5738V13.0472C0 13.4352 0 13.5719 3.28571 14.7489L3.69288 15.7128C2.29333 18.8749 2.38735 18.9698 2.65925 19.2417L4.44743 20.9908L4.62531 21.1438H4.83345C4.94101 21.1438 5.26312 21.1438 7.98514 19.9083L8.9838 20.3145C10.277 23.5193 10.4098 23.5185 10.7893 23.5185H13.3122C13.698 23.5185 13.8349 23.5185 15.0376 20.303L16.0388 19.8982C17.8736 20.674 18.9485 21.0679 19.2374 21.0679L19.4775 21.0612L21.4156 19.1638C21.6913 18.8856 21.7879 18.7894 20.3161 15.6875L20.7205 14.721C23.9999 13.4538 23.9999 13.3208 23.9999 12.9422V10.4715C23.9996 10.0823 23.9996 9.94634 20.7101 8.77354ZM11.9994 15.8738C9.68608 15.8738 7.80247 14.0268 7.80247 11.7573C7.80247 9.4895 9.68615 7.64426 11.9994 7.64426C14.3114 7.64426 16.191 9.48993 16.191 11.7573C16.1906 14.0268 14.311 15.8738 11.9994 15.8738Z" fill="currentColor"/>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -1,3 +1,3 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"> <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="M23.5 9C23.5 13.1421 20.1421 16.5 16 16.5C11.8579 16.5 8.5 13.1421 8.5 9C8.5 4.85786 11.8579 1.5 16 1.5C20.1421 1.5 23.5 4.85786 23.5 9ZM25 9C25 13.9706 20.9706 18 16 18C11.0294 18 7 13.9706 7 9C7 4.02944 11.0294 0 16 0C20.9706 0 25 4.02944 25 9ZM1.60633 30.5C2.33418 25.4116 6.71029 21.5 12 21.5H20C25.2897 21.5 29.6658 25.4116 30.3937 30.5H1.60633ZM20 20C26.1194 20 31.169 24.5805 31.9072 30.5C31.9684 30.9914 32 31.492 32 32H0C0 31.492 0.031565 30.9914 0.0928406 30.5C0.830988 24.5805 5.88057 20 12 20H20Z" fill="#3D3D3D"/> <path fill-rule="evenodd" clip-rule="evenodd" d="M17.625 5.625C17.625 8.7316 15.1066 11.25 12 11.25C8.8934 11.25 6.375 8.7316 6.375 5.625C6.375 2.5184 8.8934 0 12 0C15.1066 0 17.625 2.5184 17.625 5.625ZM15 14.0625C19.5896 14.0625 23.3768 17.4979 23.9304 21.9375C23.9763 22.306 24 23.619 24 24H0C0 23.619 0.0236738 22.306 0.0696305 21.9375C0.623241 17.4979 4.41043 14.0625 9 14.0625H15Z" fill="currentColor"/>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 679 B

After

Width:  |  Height:  |  Size: 512 B

View file

@ -1,3 +1,3 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="24" height="25" viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M15 32L0 17.9399L18.5 0H28.125L32 3.75V13.2063L15 32ZM2.1737 17.9214L3.27153 16.8569L15.9976 28.6611L14.9118 29.8614L2.1737 17.9214ZM4.34987 15.8112L17.0039 27.5486L30.5 12.6285V4.38577L27.518 1.5H19.1079L4.34987 15.8112ZM26.75 6.375C26.75 7.13439 26.1344 7.75 25.375 7.75C24.6156 7.75 24 7.13439 24 6.375C24 5.61561 24.6156 5 25.375 5C26.1344 5 26.75 5.61561 26.75 6.375ZM28.25 6.375C28.25 7.96282 26.9628 9.25 25.375 9.25C23.7872 9.25 22.5 7.96282 22.5 6.375C22.5 4.78718 23.7872 3.5 25.375 3.5C26.9628 3.5 28.25 4.78718 28.25 6.375Z" fill="#3D3D3D"/> <path fill-rule="evenodd" clip-rule="evenodd" d="M14.7809 0H21.2346L24.0003 2.7647L24.0003 9.21617L13.0608 20.1518L3.84137 10.9356L14.7809 0ZM0 14.7756L1.85855 12.9171L11.0849 22.1435L9.22637 24.002L0 14.7756ZM19.0596 6.06587C19.8892 6.06587 20.5618 5.39355 20.5618 4.5642C20.5618 3.73485 19.8892 3.06253 19.0596 3.06253C18.2299 3.06253 17.5574 3.73485 17.5574 4.5642C17.5574 5.39355 18.2299 6.06587 19.0596 6.06587Z" fill="currentColor"/>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 706 B

After

Width:  |  Height:  |  Size: 543 B

View file

@ -1,3 +1,3 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"> <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="M27.8049 0H4.19513L0 8.9457V9.11158C0 12.3944 1.44708 14.6199 3.375 15.6208V32H28.75V15.6154C30.617 14.5943 32 12.3699 32 9.11158V8.9457L27.8049 0ZM4.875 30.5058V16.1355C5.14409 16.1849 5.41713 16.2136 5.69211 16.2214C7.14186 16.2621 8.59031 15.705 9.6709 14.5647C10.0776 14.1355 10.4264 13.6302 10.7034 13.0527C11.0076 13.6455 11.3916 14.1633 11.8384 14.6023C13.002 15.7461 14.5468 16.3113 16.0801 16.3113C17.6133 16.3113 19.1581 15.7461 20.3217 14.6023C20.7652 14.1665 21.1469 13.6531 21.45 13.0657C21.7212 13.6389 22.0617 14.1415 22.4584 14.5697C23.5212 15.7169 24.95 16.2864 26.3852 16.2513C26.6768 16.2442 26.9658 16.2128 27.25 16.1575V30.5058H21.625V18.179H10.5V30.5058H4.875ZM12 30.5058H20.125V19.6731H12V30.5058ZM9.92301 9.83658H1.52765C1.78923 13.1794 3.86009 14.6752 5.73439 14.7278C6.76627 14.7568 7.79945 14.3629 8.58008 13.5391C9.3228 12.7553 9.87435 11.5402 9.92301 9.83658ZM1.9385 8.34241L5.15002 1.49416H26.85L30.0615 8.34241H1.9385ZM30.4734 9.83658H22.237C22.2849 11.544 22.8289 12.7664 23.5608 13.5564C24.3292 14.3858 25.342 14.7822 26.3484 14.7576C28.1717 14.713 30.2183 13.2302 30.4734 9.83658ZM20.7298 9.83658H11.4303C11.4832 11.5221 12.0764 12.7372 12.8919 13.5387C13.7545 14.3866 14.9116 14.8171 16.0801 14.8171C17.2485 14.8171 18.4056 14.3866 19.2682 13.5387C20.0837 12.7372 20.6769 11.5221 20.7298 9.83658Z" fill="#3D3D3D"/> <path fill-rule="evenodd" clip-rule="evenodd" d="M10.6875 0H0V13.4062H10.6875V0ZM24 10.5938H13.3125V24H24V10.5938ZM13.3125 0H24V7.96875H13.3125V0ZM10.6875 16.0312H0V24H10.6875V16.0312Z" fill="currentColor"/>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 311 B

View file

@ -1,3 +1,3 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"> <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="M5.712 3.5H0V2H6.913L7.78154 5.875H32L28.0625 21.375H10.3559H9.5625H9.23912L8.44877 23H28V24.5H6.05121L8.30067 19.875H9.24194L6.36634 6.4194L5.712 3.5ZM10.3125 28.75C10.9683 28.75 11.5 28.2183 11.5 27.5625C11.5 26.9067 10.9683 26.375 10.3125 26.375C9.65666 26.375 9.125 26.9067 9.125 27.5625C9.125 28.2183 9.65666 28.75 10.3125 28.75ZM10.3125 30.25C11.7968 30.25 13 29.0468 13 27.5625C13 26.0782 11.7968 24.875 10.3125 24.875C8.82823 24.875 7.625 26.0782 7.625 27.5625C7.625 29.0468 8.82823 30.25 10.3125 30.25ZM26 27.5625C26 28.2183 25.4683 28.75 24.8125 28.75C24.1567 28.75 23.625 28.2183 23.625 27.5625C23.625 26.9067 24.1567 26.375 24.8125 26.375C25.4683 26.375 26 26.9067 26 27.5625ZM27.5 27.5625C27.5 29.0468 26.2968 30.25 24.8125 30.25C23.3282 30.25 22.125 29.0468 22.125 27.5625C22.125 26.0782 23.3282 24.875 24.8125 24.875C26.2968 24.875 27.5 26.0782 27.5 27.5625ZM30.0713 7.375L26.8959 19.875H10.7758L8.10444 7.375H30.0713Z" fill="#3D3D3D"/> <path fill-rule="evenodd" clip-rule="evenodd" d="M24 1H0V3.16803H3.74269V11.9344C3.74269 13.6311 4.8655 14.998 6.78363 14.998H21.1462V12.9242H6.78363C6.26901 12.9242 5.80117 12.5 5.80117 11.9344V10.6619H20.5848L24 2.93238V1ZM8.98257 20.8893C8.98257 22.6073 7.60015 24 5.89485 24C4.18955 24 2.80713 22.6073 2.80713 20.8893C2.80713 19.1714 4.18955 17.7787 5.89485 17.7787C7.60015 17.7787 8.98257 19.1714 8.98257 20.8893ZM20.8656 24C22.5709 24 23.9533 22.6073 23.9533 20.8893C23.9533 19.1714 22.5709 17.7787 20.8656 17.7787C19.1603 17.7787 17.7778 19.1714 17.7778 20.8893C17.7778 22.6073 19.1603 24 20.8656 24Z" fill="currentColor" />
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 735 B

View file

@ -1,3 +1,3 @@
<svg width="126" height="126" viewBox="0 0 126 126" fill="none" xmlns="http://www.w3.org/2000/svg"> <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="M9.7001 116.365L16.2586 97.9453H35.3012C37.679 103.982 40.6312 110.258 44.1417 116.908C39.855 115.408 35.8027 113.412 32.0522 110.987L29.628 109.42L9.7001 116.365ZM60.0469 120.019V97.9453H41.6706C44.3861 104.516 47.8275 111.48 52.0086 119.038C54.6277 119.548 57.3114 119.88 60.0469 120.019ZM65.9531 97.9453H84.4393C81.7269 104.508 78.2902 111.464 74.1154 119.012C71.4563 119.537 68.7309 119.877 65.9531 120.019V97.9453ZM65.9531 92.0391V65.9531H92.1007C91.7928 74.3536 90.0135 82.8472 86.7212 92.0391H65.9531ZM60.0469 60.0469V33.2227H39.8646C36.3428 42.7476 34.4238 51.4762 34.0351 60.0469H60.0469ZM65.9531 33.2227V60.0469H92.0748C91.6862 51.4762 89.7671 42.7476 86.2453 33.2227H65.9531ZM65.9531 27.3164V5.98131C68.6242 6.1174 71.2468 6.43707 73.8086 6.92794C77.8557 14.2212 81.2134 20.9606 83.9011 27.3164H65.9531ZM60.0469 27.3164V5.98131C57.4185 6.11523 54.8371 6.4269 52.3144 6.90453C48.2615 14.2068 44.8994 20.9538 42.2089 27.3164H60.0469ZM60.0469 92.0391V65.9531H34.0093C34.3172 74.3536 36.0964 82.8472 39.3887 92.0391H60.0469ZM108.153 97.9453C101.496 106.535 92.4421 113.173 81.9944 116.858C85.4934 110.227 88.4369 103.967 90.8088 97.9453H108.153ZM112.168 92.0391H92.9758C96.0234 83.0451 97.7207 74.5074 98.0106 65.9531H120.019C119.535 75.4455 116.733 84.3258 112.168 92.0391ZM120.019 60.0469H97.9867C97.6203 51.3086 95.7869 42.5348 92.5229 33.2227H111.723C116.551 41.1054 119.52 50.2502 120.019 60.0469ZM107.571 27.3164H90.2923C87.9424 21.4966 85.0648 15.4383 81.668 9.02798C91.9513 12.5842 100.902 18.9966 107.571 27.3164ZM33.587 33.2227C30.323 42.5348 28.4897 51.3086 28.1233 60.0469H5.98131C6.48047 50.2502 9.44907 41.1054 14.2769 33.2227H33.587ZM44.4665 8.98166C41.059 15.4091 38.1732 21.4826 35.8176 27.3164H18.4285C25.127 18.9603 34.1267 12.5284 44.4665 8.98166ZM28.0994 65.9531C28.3892 74.5074 30.0865 83.0451 33.1341 92.0391H13.8313C9.26639 84.3283 6.46449 75.4524 5.98119 65.9531H28.0994ZM0 126L10.1935 97.3714C3.7467 87.4871 0 75.6811 0 63C0 28.2061 28.2061 0 63 0C97.7939 0 126 28.2061 126 63C126 97.7939 97.7939 126 63 126C50.4117 126 38.6858 122.308 28.8459 115.948L0 126Z" fill="#3D3D3D"/> <path fill-rule="evenodd" clip-rule="evenodd" d="M12.0019 0C15.2067 0 18.2197 1.24805 20.4859 3.51413C22.752 5.7803 24 8.79328 24 11.9981C24 15.2029 22.752 18.2159 20.4859 20.482C18.2197 22.7481 15.2067 23.9962 12.0019 23.9962C9.99525 23.9962 8.01872 23.4932 6.26752 22.5393L0 24L1.46067 17.7325C0.506766 15.9813 0.00384375 14.0048 0.00384375 11.9981C0.00384375 8.79328 1.25189 5.7803 3.51802 3.51413C5.78414 1.24805 8.79712 0 12.0019 0ZM2.81588 11.9981C2.81588 17.0633 6.9367 21.1841 12.0019 21.1841C17.0671 21.1841 21.188 17.0633 21.188 11.9981C21.188 6.93286 17.0671 2.81203 12.0019 2.81203C6.9367 2.81203 2.81588 6.93286 2.81588 11.9981ZM14.3709 6.31687C13.8901 5.35519 13.3072 4.68942 12.705 4.39261V11.295H15.5253C15.445 9.40683 15.0424 7.65994 14.3709 6.31687ZM12.705 12.7011V12.7011V19.6035C13.3071 19.3067 13.8901 18.6409 14.3709 17.6792C15.0424 16.3363 15.445 14.5893 15.5253 12.7011H12.705ZM9.63291 17.6793C8.96142 16.3363 8.55886 14.5894 8.47856 12.7011H11.2989V19.6035C10.6967 19.3067 10.1137 18.641 9.63291 17.6793ZM9.63291 6.31687C8.96142 7.65984 8.55886 9.40678 8.47856 11.295H11.2989V4.39265C10.6967 4.68947 10.1137 5.35528 9.63291 6.31687ZM15.6285 5.68805C15.4868 5.40446 15.3364 5.1406 15.1786 4.89666C17.686 6.02274 19.4927 8.43886 19.7498 11.295H16.9324C16.8493 9.1882 16.3938 7.21866 15.6285 5.68805ZM16.9324 12.7011C16.8493 14.808 16.3938 16.7775 15.6285 18.3081C15.4867 18.5917 15.3364 18.8556 15.1786 19.0995C17.6859 17.9735 19.4927 15.5573 19.7498 12.7011H16.9324ZM7.07137 12.7011C7.15453 14.8079 7.61001 16.7775 8.3753 18.3081C8.51714 18.5917 8.66742 18.8556 8.8252 19.0995C6.31786 17.9734 4.51106 15.5573 4.254 12.7011H7.07137ZM4.254 11.295H7.07137C7.15453 9.1882 7.60997 7.21866 8.3753 5.68805C8.51714 5.40446 8.66742 5.1406 8.8252 4.89666C6.31781 6.02269 4.51111 8.43881 4.254 11.295Z" fill="currentColor"/>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -1,4 +1,4 @@
/* eslint-disable sort-keys */ /* eslint-disable sort-keys */
export const LEFT_MENU_SELECTORS = { export const LEFT_MENU_SELECTORS = {
catalog: "[data-testid='catalogue']" catalog: "[data-test-id='catalogue']"
}; };

View file

@ -1,6 +1,6 @@
/* eslint-disable sort-keys */ /* eslint-disable sort-keys */
export const PRODUCTS_SELECTORS = { export const PRODUCTS_SELECTORS = {
products: "[href='/dashboard/products?']", products: "[data-test='submenu-item-label'][data-test-id='products']",
createProductBtn: "[data-test='add-product']", createProductBtn: "[data-test='add-product']",
productNameInput: "[name='name']", productNameInput: "[name='name']",
productTypeInput: "[data-test='product-type']", productTypeInput: "[data-test='product-type']",

View file

@ -7,7 +7,7 @@ describe("Warehouse settings", () => {
xit("Warehouse section visible in the configuration", () => { xit("Warehouse section visible in the configuration", () => {
cy.visit("/configuration/") cy.visit("/configuration/")
.loginUser() .loginUser()
.get("[data-testid=warehouses][data-test=settingsSubsection]") .get("[data-test-id=warehouses][data-test=settingsSubsection]")
.click(); .click();
cy.location("pathname").should("eq", "/warehouses/"); cy.location("pathname").should("eq", "/warehouses/");
}); });

View file

@ -1444,14 +1444,6 @@
"src_dot_components_dot_AddressEdit_dot_944851093": { "src_dot_components_dot_AddressEdit_dot_944851093": {
"string": "Country area" "string": "Country area"
}, },
"src_dot_components_dot_AppLayout_dot_21332146": {
"context": "button",
"string": "Log out"
},
"src_dot_components_dot_AppLayout_dot_248888005": {
"context": "button",
"string": "Account Settings"
},
"src_dot_components_dot_AppStatus_dot_1624959454": { "src_dot_components_dot_AppStatus_dot_1624959454": {
"string": "If you want to disable this App please uncheck the box below." "string": "If you want to disable this App please uncheck the box below."
}, },
@ -2007,6 +1999,14 @@
"src_dot_components_dot_Timeline_dot_3028189627": { "src_dot_components_dot_Timeline_dot_3028189627": {
"string": "Leave your note here..." "string": "Leave your note here..."
}, },
"src_dot_components_dot_UserChip_dot_21332146": {
"context": "button",
"string": "Log out"
},
"src_dot_components_dot_UserChip_dot_248888005": {
"context": "button",
"string": "Account Settings"
},
"src_dot_components_dot_VisibilityCard_dot_1311467573": { "src_dot_components_dot_VisibilityCard_dot_1311467573": {
"string": "Show in product listings" "string": "Show in product listings"
}, },

View file

@ -34,7 +34,7 @@ const useStyles = makeStyles(
marginTop: theme.spacing(0.5), marginTop: theme.spacing(0.5),
transition: theme.transitions.duration.standard + "ms", transition: theme.transitions.duration.standard + "ms",
[theme.breakpoints.down("sm")]: { [theme.breakpoints.down("sm")]: {
display: "none" margin: theme.spacing(4, 0, 0, 0)
} }
}, },
skeleton: { skeleton: {
@ -45,10 +45,7 @@ const useStyles = makeStyles(
color: "inherit", color: "inherit",
flex: 1, flex: 1,
marginLeft: theme.spacing(), marginLeft: theme.spacing(),
textTransform: "uppercase", textTransform: "uppercase"
[theme.breakpoints.down("sm")]: {
display: "none"
}
} }
}), }),
{ name: "AppHeader" } { name: "AppHeader" }

View file

@ -1,41 +1,28 @@
import saleorDarkLogoSmall from "@assets/images/logo-dark-small.svg";
import saleorDarkLogo from "@assets/images/logo-dark.svg";
import menuArrowIcon from "@assets/images/menu-arrow-icon.svg";
import Avatar from "@material-ui/core/Avatar";
import Chip from "@material-ui/core/Chip";
import ClickAwayListener from "@material-ui/core/ClickAwayListener";
import Grow from "@material-ui/core/Grow";
import Hidden from "@material-ui/core/Hidden";
import LinearProgress from "@material-ui/core/LinearProgress"; import LinearProgress from "@material-ui/core/LinearProgress";
import MenuItem from "@material-ui/core/MenuItem"; import { makeStyles, Theme } from "@material-ui/core/styles";
import Menu from "@material-ui/core/MenuList"; import useMediaQuery from "@material-ui/core/useMediaQuery";
import Paper from "@material-ui/core/Paper";
import Popper from "@material-ui/core/Popper";
import { makeStyles } from "@material-ui/core/styles";
import { createConfigurationMenu } from "@saleor/configuration"; import { createConfigurationMenu } from "@saleor/configuration";
import useAppState from "@saleor/hooks/useAppState"; import useAppState from "@saleor/hooks/useAppState";
import useLocalStorage from "@saleor/hooks/useLocalStorage";
import useNavigator from "@saleor/hooks/useNavigator"; import useNavigator from "@saleor/hooks/useNavigator";
import useTheme from "@saleor/hooks/useTheme"; import useTheme from "@saleor/hooks/useTheme";
import useUser from "@saleor/hooks/useUser"; import useUser from "@saleor/hooks/useUser";
import ArrowDropdown from "@saleor/icons/ArrowDropdown";
import { staffMemberDetailsUrl } from "@saleor/staff/urls"; import { staffMemberDetailsUrl } from "@saleor/staff/urls";
import classNames from "classnames"; import classNames from "classnames";
import React from "react"; import React from "react";
import SVG from "react-inlinesvg"; import { useIntl } from "react-intl";
import { FormattedMessage, useIntl } from "react-intl";
import useRouter from "use-react-router"; import useRouter from "use-react-router";
import Container from "../Container"; import Container from "../Container";
import ErrorPage from "../ErrorPage"; import ErrorPage from "../ErrorPage";
import Navigator from "../Navigator"; import Navigator from "../Navigator";
import NavigatorButton from "../NavigatorButton/NavigatorButton"; import NavigatorButton from "../NavigatorButton/NavigatorButton";
import SideBar from "../SideBar";
import SideBarDrawer from "../SideBarDrawer/SideBarDrawer";
import UserChip from "../UserChip";
import AppActionContext from "./AppActionContext"; import AppActionContext from "./AppActionContext";
import AppHeaderContext from "./AppHeaderContext"; import AppHeaderContext from "./AppHeaderContext";
import { appLoaderHeight, drawerWidth, drawerWidthExpanded } from "./consts"; import { appLoaderHeight } from "./consts";
import MenuList from "./MenuList";
import createMenuStructure from "./menuStructure"; import createMenuStructure from "./menuStructure";
import ResponsiveDrawer from "./ResponsiveDrawer";
import ThemeSwitch from "./ThemeSwitch"; import ThemeSwitch from "./ThemeSwitch";
const useStyles = makeStyles( const useStyles = makeStyles(
@ -55,231 +42,58 @@ const useStyles = makeStyles(
}, },
appLoader: { appLoader: {
height: appLoaderHeight, height: appLoaderHeight,
marginBottom: theme.spacing(2), marginBottom: theme.spacing(4),
zIndex: 1201 zIndex: 1201
}, },
appLoaderPlaceholder: { appLoaderPlaceholder: {
height: appLoaderHeight, height: appLoaderHeight,
marginBottom: theme.spacing(2) marginBottom: theme.spacing(4)
},
arrow: {
marginLeft: theme.spacing(2),
transition: theme.transitions.duration.standard + "ms"
},
avatar: {
"&&": {
height: 32,
width: 32
}
}, },
content: { content: {
[theme.breakpoints.down("sm")]: { flex: 1
paddingLeft: 0
},
paddingLeft: drawerWidthExpanded,
transition: "padding-left 0.5s ease",
width: "100%"
},
contentToggle: {
[theme.breakpoints.down("sm")]: {
paddingLeft: 0
},
paddingLeft: drawerWidth
}, },
darkThemeSwitch: { darkThemeSwitch: {
[theme.breakpoints.down("sm")]: { [theme.breakpoints.down("sm")]: {
marginRight: -theme.spacing(1.5) marginRight: theme.spacing(1)
}, },
marginRight: theme.spacing(2) marginRight: theme.spacing(2)
}, },
header: { header: {
display: "grid",
gridTemplateAreas: `"headerAnchor headerToolbar"`,
[theme.breakpoints.down("sm")]: { [theme.breakpoints.down("sm")]: {
height: 88, gridTemplateAreas: `"headerToolbar"
marginBottom: 0 "headerAnchor"`
}, },
display: "flex",
height: 40,
marginBottom: theme.spacing(3) marginBottom: theme.spacing(3)
}, },
isMenuSmall: { headerAnchor: {
"& path": { gridArea: "headerAnchor"
fill: theme.palette.primary.main
},
"& span": {
margin: "0 8px"
},
"& svg": {
marginTop: 8,
transform: "rotate(180deg)"
},
"&:hover": {
background: "#E6F3F3"
},
background: theme.palette.background.paper,
border: `solid 1px #EAEAEA`,
borderRadius: "50%",
cursor: "pointer",
height: 32,
position: "absolute",
right: -16,
top: 65,
transition: `background ${theme.transitions.duration.shorter}ms`,
width: 32,
zIndex: 99
}, },
isMenuSmallDark: { headerToolbar: {
"&:hover": { display: "flex",
background: `linear-gradient(0deg, rgba(25, 195, 190, 0.1), rgba(25, 195, 190, 0.1)), ${theme.palette.background.paper}` gridArea: "headerToolbar",
}, height: 40,
border: `solid 1px #252728`,
transition: `background ${theme.transitions.duration.shorter}ms`
},
isMenuSmallHide: {
"& svg": {
marginLeft: "3px",
transform: "rotate(0deg)"
}
},
logo: {
"& svg": {
left: "50%",
position: "absolute",
top: "50%",
transform: "translate(-50%,-50%)"
},
background: theme.palette.secondary.main,
display: "block",
height: 80,
position: "relative"
},
logoDark: {
"& path": {
fill: theme.palette.common.white
},
background: theme.palette.primary.main
},
logoSmall: {
"& svg": {
margin: 0,
padding: 0,
width: "80px"
}
},
menu: {
background: theme.palette.background.paper,
height: "100vh",
padding: "25px 20px"
},
menuIcon: {
"& span": {
"&:nth-child(1)": {
top: 15
},
"&:nth-child(2), &:nth-child(3)": {
top: 20
},
"&:nth-child(4)": {
top: 25
},
background: theme.palette.secondary.light,
display: "block",
height: 1,
left: "20%",
opacity: 1,
position: "absolute",
transform: "rotate(0deg)",
transition: ".25s ease-in-out",
width: "60%"
},
[theme.breakpoints.up("md")]: {
display: "none"
},
[theme.breakpoints.down("sm")]: { [theme.breakpoints.down("sm")]: {
left: 0 height: "auto"
},
background: theme.palette.background.paper,
borderRadius: "50%",
cursor: "pointer",
height: 42,
left: theme.spacing(),
marginRight: theme.spacing(2),
position: "relative",
transform: "rotate(0deg)",
transition: `${theme.transitions.duration.shorter}ms ease-in-out`,
width: 42
},
menuIconDark: {
"& span": {
background: theme.palette.common.white
} }
}, },
menuIconOpen: {
"& span": {
"&:nth-child(1), &:nth-child(4)": {
left: "50%",
top: 20,
width: 0
},
"&:nth-child(2)": {
transform: "rotate(45deg)"
},
"&:nth-child(3)": {
transform: "rotate(-45deg)"
}
},
left: 280,
position: "absolute",
zIndex: 1999
},
menuSmall: {
background: theme.palette.background.paper,
height: "100vh",
overflow: "hidden",
padding: 25
},
popover: {
zIndex: 2
},
root: { root: {
width: `100%` [theme.breakpoints.up("md")]: {
}, display: "flex"
rotate: {
transform: "rotate(180deg)"
},
sideBar: {
[theme.breakpoints.down("sm")]: {
padding: 0
}, },
background: theme.palette.background.paper, width: `100%`
padding: `0 ${theme.spacing(4)}px`
}, },
spacer: { spacer: {
flex: 1 flex: 1
}, },
userBar: { userBar: {
[theme.breakpoints.down("sm")]: {
alignItems: "flex-end",
flexDirection: "column-reverse",
overflow: "hidden"
},
alignItems: "center", alignItems: "center",
display: "flex" display: "flex"
}, },
userChip: {
backgroundColor: theme.palette.background.paper,
borderRadius: 24,
color: theme.palette.text.primary,
height: 40,
padding: theme.spacing(0.5)
},
userMenuContainer: {
position: "relative"
},
userMenuItem: {
textAlign: "right"
},
view: { view: {
backgroundColor: theme.palette.background.default,
flex: 1, flex: 1,
flexGrow: 1, flexGrow: 1,
marginLeft: 0, marginLeft: 0,
@ -304,18 +118,15 @@ interface AppLayoutProps {
const AppLayout: React.FC<AppLayoutProps> = ({ children }) => { const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
const classes = useStyles({}); const classes = useStyles({});
const { isDark, toggleTheme } = useTheme(); const { isDark, toggleTheme } = useTheme();
const [isMenuSmall, setMenuSmall] = useLocalStorage("isMenuSmall", false);
const [isDrawerOpened, setDrawerState] = React.useState(false);
const [isMenuOpened, setMenuState] = React.useState(false);
const appActionAnchor = React.useRef<HTMLDivElement>(); const appActionAnchor = React.useRef<HTMLDivElement>();
const appHeaderAnchor = React.useRef<HTMLDivElement>(); const appHeaderAnchor = React.useRef<HTMLDivElement>();
const anchor = React.useRef<HTMLDivElement>();
const { logout, user } = useUser(); const { logout, user } = useUser();
const navigate = useNavigator(); const navigate = useNavigator();
const intl = useIntl(); const intl = useIntl();
const [appState, dispatchAppState] = useAppState(); const [appState, dispatchAppState] = useAppState();
const { location } = useRouter(); const { location } = useRouter();
const [isNavigatorVisible, setNavigatorVisibility] = React.useState(false); const [isNavigatorVisible, setNavigatorVisibility] = React.useState(false);
const isMdUp = useMediaQuery((theme: Theme) => theme.breakpoints.up("md"));
const [docked, setDocked] = React.useState(true); const [docked, setDocked] = React.useState(true);
const menuStructure = createMenuStructure(intl); const menuStructure = createMenuStructure(intl);
@ -331,27 +142,6 @@ const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
) )
); );
const handleLogout = () => {
setMenuState(false);
logout();
};
const handleViewerProfile = () => {
setMenuState(false);
navigate(staffMemberDetailsUrl(user.id));
};
const handleMenuItemClick = (url: string, event: React.MouseEvent<any>) => {
event.stopPropagation();
event.preventDefault();
setDrawerState(false);
navigate(url);
};
const handleIsMenuSmall = () => {
setMenuSmall(!isMenuSmall);
};
const handleErrorBack = () => { const handleErrorBack = () => {
navigate("/"); navigate("/");
dispatchAppState({ dispatchAppState({
@ -377,49 +167,16 @@ const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
}} }}
> >
<div className={classes.root}> <div className={classes.root}>
<div className={classes.sideBar}> {isMdUp && (
<ResponsiveDrawer <SideBar
onClose={() => setDrawerState(false)} menuItems={menuStructure}
open={isDrawerOpened} location={location.pathname}
small={!isMenuSmall} user={user}
> renderConfigure={renderConfigure}
<div onMenuItemClick={navigate}
className={classNames(classes.logo, { />
[classes.logoSmall]: isMenuSmall, )}
[classes.logoDark]: isDark <div className={classes.content}>
})}
>
<SVG
src={isMenuSmall ? saleorDarkLogoSmall : saleorDarkLogo}
/>
</div>
<Hidden smDown>
<div
className={classNames(classes.isMenuSmall, {
[classes.isMenuSmallHide]: isMenuSmall,
[classes.isMenuSmallDark]: isDark
})}
onClick={handleIsMenuSmall}
>
<SVG src={menuArrowIcon} />
</div>
</Hidden>
<MenuList
className={isMenuSmall ? classes.menuSmall : classes.menu}
menuItems={menuStructure}
isMenuSmall={!isMenuSmall}
location={location.pathname}
user={user}
renderConfigure={renderConfigure}
onMenuItemClick={handleMenuItemClick}
/>
</ResponsiveDrawer>
</div>
<div
className={classNames(classes.content, {
[classes.contentToggle]: isMenuSmall
})}
>
{appState.loading ? ( {appState.loading ? (
<LinearProgress className={classes.appLoader} color="primary" /> <LinearProgress className={classes.appLoader} color="primary" />
) : ( ) : (
@ -430,106 +187,39 @@ const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
<Container> <Container>
<div className={classes.header}> <div className={classes.header}>
<div <div
className={classNames(classes.menuIcon, { className={classes.headerAnchor}
[classes.menuIconOpen]: isDrawerOpened, ref={appHeaderAnchor}
[classes.menuIconDark]: isDark />
})} <div className={classes.headerToolbar}>
onClick={() => setDrawerState(!isDrawerOpened)} {!isMdUp && (
> <SideBarDrawer
<span /> menuItems={menuStructure}
<span /> location={location.pathname}
<span /> user={user}
<span /> renderConfigure={renderConfigure}
</div> onMenuItemClick={navigate}
<div ref={appHeaderAnchor} /> />
<div className={classes.spacer} /> )}
<div className={classes.userBar}> <div className={classes.spacer} />
<ThemeSwitch <div className={classes.userBar}>
className={classes.darkThemeSwitch} <ThemeSwitch
checked={isDark} className={classes.darkThemeSwitch}
onClick={toggleTheme} checked={isDark}
/> onClick={toggleTheme}
<Hidden smDown> />
<NavigatorButton <NavigatorButton
isMac={navigator.platform isMac={navigator.platform
.toLowerCase() .toLowerCase()
.includes("mac")} .includes("mac")}
onClick={() => setNavigatorVisibility(true)} onClick={() => setNavigatorVisibility(true)}
/> />
</Hidden> <UserChip
<div className={classes.userMenuContainer} ref={anchor}> onLogout={logout}
<Chip onProfileClick={() =>
avatar={ navigate(staffMemberDetailsUrl(user.id))
user.avatar && (
<Avatar alt="user" src={user.avatar.url} />
)
} }
classes={{ user={user}
avatar: classes.avatar
}}
className={classes.userChip}
label={
<>
{user.email}
<ArrowDropdown
className={classNames(classes.arrow, {
[classes.rotate]: isMenuOpened
})}
/>
</>
}
onClick={() => setMenuState(!isMenuOpened)}
data-test="userMenu"
/> />
<Popper
className={classes.popover}
open={isMenuOpened}
anchorEl={anchor.current}
transition
placement="bottom-end"
>
{({ TransitionProps, placement }) => (
<Grow
{...TransitionProps}
style={{
transformOrigin:
placement === "bottom"
? "right top"
: "right bottom"
}}
>
<Paper>
<ClickAwayListener
onClickAway={() => setMenuState(false)}
mouseEvent="onClick"
>
<Menu>
<MenuItem
className={classes.userMenuItem}
onClick={handleViewerProfile}
data-test="accountSettingsButton"
>
<FormattedMessage
defaultMessage="Account Settings"
description="button"
/>
</MenuItem>
<MenuItem
className={classes.userMenuItem}
onClick={handleLogout}
data-test="logOutButton"
>
<FormattedMessage
defaultMessage="Log out"
description="button"
/>
</MenuItem>
</Menu>
</ClickAwayListener>
</Paper>
</Grow>
)}
</Popper>
</div> </div>
</div> </div>
</div> </div>

View file

@ -49,6 +49,9 @@ const useStyles = makeStyles(
overflow: "hidden" overflow: "hidden"
}, },
root: { root: {
[theme.breakpoints.down("sm")]: {
height: "auto"
},
height: 500, height: 500,
maxWidth: 600, maxWidth: 600,
outline: 0, outline: 0,

View file

@ -66,6 +66,10 @@ const useStyles = makeStyles(
"&:not(:hover)": { "&:not(:hover)": {
backgroundColor: theme.palette.background.paper backgroundColor: theme.palette.background.paper
}, },
[theme.breakpoints.down("sm")]: {
border: "none",
borderRadius: 16
},
border: `1px solid ${theme.palette.divider}`, border: `1px solid ${theme.palette.divider}`,
height: 40, height: 40,
marginRight: theme.spacing(2), marginRight: theme.spacing(2),

View file

@ -0,0 +1,42 @@
import { ButtonProps } from "@material-ui/core/Button";
import makeStyles from "@material-ui/core/styles/makeStyles";
import ArrowIcon from "@material-ui/icons/ArrowBack";
import classNames from "classnames";
import React from "react";
import SquareButton from "../SquareButton";
const useStyles = makeStyles(
theme => ({
arrow: {
transition: theme.transitions.duration.shortest + "ms"
},
shrunk: {
transform: "scaleX(-1)"
}
}),
{
name: "ExpandButton"
}
);
export interface ExpandButtonProps extends ButtonProps {
isShrunk: boolean;
}
const ExpandButton: React.FC<ExpandButtonProps> = ({ isShrunk, ...rest }) => {
const classes = useStyles({});
return (
<SquareButton {...rest}>
<ArrowIcon
className={classNames(classes.arrow, {
[classes.shrunk]: isShrunk
})}
/>
</SquareButton>
);
};
ExpandButton.displayName = "ExpandButton";
export default ExpandButton;

View file

@ -0,0 +1,199 @@
import ClickAwayListener from "@material-ui/core/ClickAwayListener";
import Paper from "@material-ui/core/Paper";
import Popper from "@material-ui/core/Popper";
import { fade } from "@material-ui/core/styles/colorManipulator";
import makeStyles from "@material-ui/core/styles/makeStyles";
import Typography from "@material-ui/core/Typography";
import { UseNavigatorResult } from "@saleor/hooks/useNavigator";
import classNames from "classnames";
import React from "react";
import SVG from "react-inlinesvg";
import { IMenuItem } from "../AppLayout/menuStructure";
export interface MenuItemProps {
active: boolean;
isMenuShrunk: boolean;
menuItem: IMenuItem;
onClick: UseNavigatorResult;
}
export const menuWidth = 210;
export const shrunkMenuWidth = 72;
const useStyles = makeStyles(
theme => ({
hideLabel: {
"&$label": {
opacity: 0
}
},
icon: {
"& svg": {
height: 24,
width: 24
},
marginRight: theme.spacing(1.5),
transition: theme.transitions.duration.shortest + "ms"
},
label: {
cursor: "pointer",
display: "block",
fontSize: 16,
fontWeight: "bold",
opacity: 1,
transition: theme.transitions.duration.shortest + "ms"
},
menuItemBtn: {
"&:focus": {
color: theme.palette.primary.main,
outline: 0
},
background: "none",
border: "none",
color: "inherit",
cursor: "pointer",
display: "inline-flex",
margin: 0,
padding: 0
},
paper: {
borderRadius: 16,
boxShadow: "0px 6px 30px rgba(0, 0, 0, 0.16)",
cursor: "default",
padding: theme.spacing(3),
textAlign: "left"
},
popper: {
marginLeft: theme.spacing(3),
zIndex: 2
},
root: {
"&:hover, &:focus": {
color: theme.palette.primary.main,
outline: 0
},
borderBottomRightRadius: 100,
borderTopRightRadius: 100,
color: fade(theme.palette.text.primary, 0.6),
cursor: "pointer",
display: "flex",
height: 56,
marginBottom: theme.spacing(),
overflow: "hidden",
padding: theme.spacing(2, 3, 2, 3.5),
transition: theme.transitions.duration.shortest + "ms",
width: shrunkMenuWidth
},
rootActive: {
"&$root": {
background: theme.palette.background.paper,
boxShadow: "0px 6px 30px rgba(0, 0, 0, 0.16)",
color: theme.palette.primary.main
}
},
rootExpanded: {
width: menuWidth
},
subMenuLabel: {
"&$label": {
"&:not(:last-child)": {
marginBottom: theme.spacing(2)
}
},
"&:hover, &:focus": {
color: theme.palette.primary.main,
outline: 0
},
background: "none",
border: "none",
color: fade(theme.palette.text.primary, 0.6),
textAlign: "left",
whiteSpace: "nowrap"
}
}),
{
name: "MenuItem"
}
);
const MenuItem: React.FC<MenuItemProps> = ({
active,
menuItem,
isMenuShrunk,
onClick
}) => {
const classes = useStyles({});
const [open, setOpen] = React.useState(false);
const anchor = React.useRef<HTMLDivElement>(null);
const handleClick = (event: React.MouseEvent, menuItem: IMenuItem) => {
event.stopPropagation();
if (menuItem.children) {
setOpen(true);
} else {
onClick(menuItem.url);
setOpen(false);
}
};
return (
<div
className={classNames(classes.root, {
[classes.rootActive]: active,
[classes.rootExpanded]: !isMenuShrunk
})}
ref={anchor}
onClick={event => handleClick(event, menuItem)}
>
<button
className={classes.menuItemBtn}
data-test="menu-item-label"
data-test-id={menuItem.testingContextId}
>
{menuItem.icon && <SVG className={classes.icon} src={menuItem.icon} />}
<Typography
aria-label={menuItem.ariaLabel}
className={classNames(classes.label, {
[classes.hideLabel]: isMenuShrunk
})}
variant="body2"
>
{menuItem.label}
</Typography>
</button>
{menuItem.children && (
<Popper
className={classes.popper}
open={open}
anchorEl={anchor.current}
transition
disablePortal
placement="right-start"
>
<ClickAwayListener onClickAway={() => setOpen(false)}>
<Paper className={classes.paper}>
{menuItem.children.map(subMenuItem => (
<Typography
aria-label={subMenuItem.ariaLabel}
component="button"
className={classNames(classes.label, classes.subMenuLabel)}
key={subMenuItem.url}
onClick={event => handleClick(event, subMenuItem)}
data-test="submenu-item-label"
data-test-id={subMenuItem.testingContextId}
variant="body2"
>
{subMenuItem.label}
</Typography>
))}
</Paper>
</ClickAwayListener>
</Popper>
)}
</div>
);
};
MenuItem.displayName = "MenuItem";
export default MenuItem;

View file

@ -0,0 +1,134 @@
import logoLight from "@assets/images/logo-sidebar-light.svg";
import configurationIcon from "@assets/images/menu-configure-icon.svg";
import makeStyles from "@material-ui/core/styles/makeStyles";
import { configurationMenuUrl } from "@saleor/configuration";
import { User } from "@saleor/fragments/types/User";
import useLocalStorage from "@saleor/hooks/useLocalStorage";
import { UseNavigatorResult } from "@saleor/hooks/useNavigator";
import { sectionNames } from "@saleor/intl";
import classNames from "classnames";
import React from "react";
import SVG from "react-inlinesvg";
import { IntlShape, useIntl } from "react-intl";
import { IMenuItem } from "../AppLayout/menuStructure";
import ExpandButton from "./ExpandButton";
import MenuItem, { menuWidth, shrunkMenuWidth } from "./MenuItem";
import { isMenuActive } from "./utils";
const useStyles = makeStyles(
theme => ({
expandButton: {
marginLeft: theme.spacing(2)
},
float: {
position: "fixed"
},
logo: {
margin: `36px 0 ${theme.spacing(3)}px ${theme.spacing(3)}px`
},
root: {
transition: "width 0.5s ease",
width: menuWidth,
zIndex: 100
},
rootShrink: {
width: shrunkMenuWidth
}
}),
{
name: "SideBar"
}
);
export interface SideBarProps {
className?: string;
menuItems: IMenuItem[];
location: string;
user: User;
renderConfigure: boolean;
onMenuItemClick: UseNavigatorResult;
}
export interface IActiveSubMenu {
isActive: boolean;
label: string | null;
}
export const getConfigureMenuItem = (intl: IntlShape): IMenuItem => ({
ariaLabel: "configure",
icon: configurationIcon,
label: intl.formatMessage(sectionNames.configuration),
testingContextId: "configure",
url: configurationMenuUrl
});
const SideBar: React.FC<SideBarProps> = ({
location,
menuItems,
renderConfigure,
user,
onMenuItemClick
}) => {
const classes = useStyles({});
const [isShrunk, setShrink] = useLocalStorage("isMenuSmall", false);
const intl = useIntl();
const configureMenuItem = getConfigureMenuItem(intl);
return (
<div
className={classNames(classes.root, {
[classes.rootShrink]: isShrunk
})}
>
<div className={classes.float}>
<div className={classes.logo}>
<SVG src={logoLight} />
</div>
{menuItems.map(menuItem => {
const isActive = isMenuActive(location, menuItem);
if (
menuItem.permission &&
!user.userPermissions
.map(perm => perm.code)
.includes(menuItem.permission)
) {
return null;
}
return (
<MenuItem
active={isActive}
isMenuShrunk={isShrunk}
menuItem={menuItem}
onClick={onMenuItemClick}
key={menuItem.ariaLabel}
/>
);
})}
{renderConfigure && (
<MenuItem
active={
!menuItems.reduce(
(acc, menuItem) => acc || isMenuActive(location, menuItem),
false
)
}
isMenuShrunk={isShrunk}
menuItem={configureMenuItem}
onClick={onMenuItemClick}
/>
)}
<ExpandButton
className={classes.expandButton}
isShrunk={isShrunk}
onClick={() => setShrink(!isShrunk)}
/>
</div>
</div>
);
};
SideBar.displayName = "SideBar";
export default SideBar;

View file

View file

@ -0,0 +1,2 @@
export * from "./SideBar";
export { default } from "./SideBar";

View file

@ -0,0 +1,24 @@
import { orderDraftListUrl, orderListUrl } from "@saleor/orders/urls";
import { matchPath } from "react-router";
import { IMenuItem } from "../AppLayout/menuStructure";
export function isMenuActive(location: string, menuItem: IMenuItem) {
if (menuItem.children) {
return menuItem.children.reduce(
(acc, subMenuItem) => acc || isMenuActive(location, subMenuItem),
false
);
}
const activeUrl = location.split("?")[0];
const menuItemUrl = menuItem.url.split("?")[0];
return activeUrl === orderDraftListUrl().split("?")[0] &&
menuItemUrl === orderListUrl().split("?")[0]
? false
: !!matchPath(activeUrl, {
exact: menuItemUrl === "/",
path: menuItemUrl
});
}

View file

@ -0,0 +1,32 @@
import Typography from "@material-ui/core/Typography";
import { UseNavigatorResult } from "@saleor/hooks/useNavigator";
import React from "react";
import SVG from "react-inlinesvg";
import { IMenuItem } from "../AppLayout/menuStructure";
import useStyles from "./styles";
export interface MenuItemBtnProps {
menuItem: IMenuItem;
onClick: UseNavigatorResult;
}
const MenuItemBtn: React.FC<MenuItemBtnProps> = ({ menuItem, onClick }) => {
const classes = useStyles({});
return (
<button
className={classes.menuItemBtn}
data-test="menu-item-label"
data-test-id={menuItem.testingContextId}
onClick={() => onClick(menuItem.url)}
>
{menuItem.icon && <SVG className={classes.icon} src={menuItem.icon} />}
<Typography aria-label={menuItem.ariaLabel} className={classes.label}>
{menuItem.label}
</Typography>
</button>
);
};
MenuItemBtn.displayName = "MenuItemBtn";
export default MenuItemBtn;

View file

@ -0,0 +1,37 @@
import { staffMember } from "@saleor/staff/fixtures";
import Decorator from "@saleor/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import { config } from "@test/intl";
import React from "react";
import { createIntl } from "react-intl";
import createMenuStructure from "../AppLayout/menuStructure";
import SideBarDrawer from "./SideBarDrawer";
const intl = createIntl(config);
const user = {
__typename: staffMember.__typename,
avatar: {
__typename: staffMember.avatar.__typename,
url: staffMember.avatar.url
},
email: staffMember.email,
firstName: "Adam Evan",
id: staffMember.id,
isStaff: true,
lastName: "Newton",
note: null,
userPermissions: staffMember.userPermissions
};
storiesOf("Generics / Mobile Side Menu", module)
.addDecorator(Decorator)
.add("default", () => (
<SideBarDrawer
location="/"
menuItems={createMenuStructure(intl)}
onMenuItemClick={() => undefined}
renderConfigure={true}
user={user}
/>
));

View file

@ -0,0 +1,132 @@
import logoLight from "@assets/images/logo-sidebar-light.svg";
import { Typography } from "@material-ui/core";
import Drawer from "@material-ui/core/Drawer";
import ArrowLeftIcon from "@material-ui/icons/ArrowLeft";
import MenuIcon from "@material-ui/icons/Menu";
import classNames from "classnames";
import React from "react";
import SVG from "react-inlinesvg";
import { useIntl } from "react-intl";
import { IMenuItem } from "../AppLayout/menuStructure";
import { getConfigureMenuItem, SideBarProps } from "../SideBar/SideBar";
import SquareButton from "../SquareButton";
import MenuItemBtn from "./MenuItemBtn";
import useStyles from "./styles";
export type SideBarDrawerProps = SideBarProps;
const SideBarDrawer: React.FC<SideBarDrawerProps> = ({
menuItems,
onMenuItemClick,
renderConfigure,
user
}) => {
const [isOpened, setOpened] = React.useState(false);
const classes = useStyles({});
const intl = useIntl();
const [activeMenu, setActiveMenu] = React.useState<IMenuItem>(null);
const [showSubmenu, setShowSubmenu] = React.useState(false);
const container = React.useRef<HTMLDivElement>(null);
const configureMenuItem = getConfigureMenuItem(intl);
const handleMenuItemClick = (url: string) => {
setOpened(false);
setShowSubmenu(false);
onMenuItemClick(url);
};
const handleMenuItemWithChildrenClick = (menuItem: IMenuItem) => {
setActiveMenu(menuItem);
setShowSubmenu(true);
container.current.scrollTo({
top: 0
});
};
return (
<>
<SquareButton onClick={() => setOpened(true)}>
<MenuIcon />
</SquareButton>
<Drawer
classes={{
paper: classes.root
}}
open={isOpened}
onClose={() => setOpened(false)}
>
<div
className={classNames(classes.container, {
[classes.containerSubMenu]: showSubmenu
})}
ref={container}
>
<div
className={classNames(classes.innerContainer, {
[classes.secondaryContentActive]: showSubmenu
})}
>
<div className={classes.content}>
<SVG className={classes.logo} src={logoLight} />
{menuItems.map(menuItem => {
if (
menuItem.permission &&
!user.userPermissions
.map(perm => perm.code)
.includes(menuItem.permission)
) {
return null;
}
return (
<MenuItemBtn
menuItem={menuItem}
onClick={
menuItem.children
? () => handleMenuItemWithChildrenClick(menuItem)
: handleMenuItemClick
}
key={menuItem.ariaLabel}
/>
);
})}
{renderConfigure && (
<MenuItemBtn
menuItem={configureMenuItem}
onClick={handleMenuItemClick}
/>
)}
</div>
{activeMenu && (
<div className={classes.content}>
<div className={classes.subMenuTopBar}>
<div className={classes.activeMenuLabel}>
<SVG className={classes.icon} src={activeMenu.icon} />
<Typography className={classes.label}>
{activeMenu.label}
</Typography>
</div>
<SquareButton onClick={() => setShowSubmenu(false)}>
<ArrowLeftIcon />
</SquareButton>
</div>
{activeMenu.children.map(subMenuItem => (
<MenuItemBtn
menuItem={subMenuItem}
onClick={handleMenuItemClick}
key={subMenuItem.ariaLabel}
/>
))}
</div>
)}
</div>
</div>
</Drawer>
</>
);
};
SideBarDrawer.displayName = "SideBarDrawer";
export default SideBarDrawer;

View file

View file

@ -0,0 +1,68 @@
import makeStyles from "@material-ui/core/styles/makeStyles";
const useStyles = makeStyles(
theme => ({
activeMenuLabel: {
display: "flex"
},
container: {
overflowX: "hidden",
width: "100%"
},
containerSubMenu: {
"&$container": {
overflow: "hidden"
}
},
content: {
width: "50%"
},
icon: {
marginRight: theme.spacing(2)
},
innerContainer: {
display: "flex",
position: "relative",
right: 0,
transition: theme.transitions.duration.short + "ms",
width: "200%"
},
label: {
fontWeight: "bold"
},
logo: {
display: "block",
marginBottom: theme.spacing(4)
},
menuItemBtn: {
alignItems: "center",
background: "none",
border: "none",
color: theme.palette.text.secondary,
display: "flex",
marginBottom: theme.spacing(3),
padding: 0
},
root: {
background: theme.palette.background.default,
borderBottomRightRadius: 32,
borderTopRightRadius: 32,
padding: theme.spacing(3),
width: 260
},
secondaryContentActive: {
right: "100%"
},
subMenuTopBar: {
alignItems: "center",
display: "flex",
justifyContent: "space-between",
marginBottom: theme.spacing(3)
}
}),
{
name: "SideBarDrawer"
}
);
export default useStyles;

View file

@ -0,0 +1,14 @@
import CloseIcon from "@material-ui/icons/Close";
import Decorator from "@saleor/storybook/Decorator";
import { storiesOf } from "@storybook/react";
import React from "react";
import SquareButton from "./SquareButton";
storiesOf("Generics / Square Button", module)
.addDecorator(Decorator)
.add("default", () => (
<SquareButton>
<CloseIcon />
</SquareButton>
));

View file

@ -0,0 +1,34 @@
import ButtonBase, { ButtonBaseProps } from "@material-ui/core/ButtonBase";
import makeStyles from "@material-ui/core/styles/makeStyles";
import classNames from "classnames";
import React from "react";
const useStyles = makeStyles(
theme => ({
root: {
"&:hover, &:focus": {
background: "#daedeb"
},
background: theme.palette.background.paper,
borderRadius: 16,
color: theme.palette.primary.main,
height: 48,
transition: theme.transitions.duration.shortest + "ms",
width: 48
}
}),
{
name: "ExpandButton"
}
);
const SquareButton: React.FC<ButtonBaseProps> = ({ className, ...rest }) => {
const classes = useStyles({});
return (
<ButtonBase className={classNames(classes.root, className)} {...rest} />
);
};
SquareButton.displayName = "SquareButton";
export default SquareButton;

View file

@ -0,0 +1,2 @@
export * from "./SquareButton";
export { default } from "./SquareButton";

View file

@ -0,0 +1,183 @@
import Avatar from "@material-ui/core/Avatar";
import Chip from "@material-ui/core/Chip";
import ClickAwayListener from "@material-ui/core/ClickAwayListener";
import Grow from "@material-ui/core/Grow";
import Hidden from "@material-ui/core/Hidden";
import MenuItem from "@material-ui/core/MenuItem";
import Menu from "@material-ui/core/MenuList";
import Paper from "@material-ui/core/Paper";
import Popper from "@material-ui/core/Popper";
import makeStyles from "@material-ui/core/styles/makeStyles";
import { User } from "@saleor/fragments/types/User";
import ArrowDropdown from "@saleor/icons/ArrowDropdown";
import { getUserInitials, getUserName } from "@saleor/misc";
import classNames from "classnames";
import React from "react";
import { FormattedMessage } from "react-intl";
const useStyles = makeStyles(
theme => ({
arrow: {
[theme.breakpoints.down("sm")]: {
marginLeft: 0
},
marginLeft: theme.spacing(2),
transition: theme.transitions.duration.standard + "ms"
},
avatar: {
"&&": {
[theme.breakpoints.down("sm")]: {
height: 40,
width: 40
},
height: 32,
width: 32
}
},
avatarInitials: {
color: theme.palette.primary.contrastText
},
avatarPlaceholder: {
alignItems: "center",
background: theme.palette.primary.main,
borderRadius: "100%",
display: "flex",
justifyContent: "center"
},
popover: {
marginTop: theme.spacing(2),
zIndex: 1
},
rotate: {
transform: "rotate(180deg)"
},
userChip: {
[theme.breakpoints.down("sm")]: {
height: 48
},
backgroundColor: theme.palette.background.paper,
borderRadius: 24,
color: theme.palette.text.primary,
height: 40,
padding: theme.spacing(0.5)
},
userMenuContainer: {
position: "relative"
},
userMenuItem: {
textAlign: "right"
}
}),
{
name: "UserChip"
}
);
export interface UserChipProps {
user: User;
onLogout: () => void;
onProfileClick: () => void;
}
const UserChip: React.FC<UserChipProps> = ({
user,
onLogout,
onProfileClick
}) => {
const classes = useStyles({});
const [isMenuOpened, setMenuState] = React.useState(false);
const anchor = React.useRef<HTMLDivElement>();
const handleLogout = () => {
setMenuState(false);
onLogout();
};
const handleViewerProfile = () => {
setMenuState(false);
onProfileClick();
};
return (
<div className={classes.userMenuContainer} ref={anchor}>
<Chip
avatar={
user.avatar ? (
<Avatar alt="user" src={user.avatar.url} />
) : (
<div className={classes.avatarPlaceholder}>
<div className={classes.avatarInitials}>
{getUserInitials(user)}
</div>
</div>
)
}
classes={{
avatar: classes.avatar
}}
className={classes.userChip}
label={
<>
<Hidden smDown>{getUserName(user, true)}</Hidden>
<ArrowDropdown
className={classNames(classes.arrow, {
[classes.rotate]: isMenuOpened
})}
/>
</>
}
onClick={() => setMenuState(!isMenuOpened)}
data-test="userMenu"
/>
<Popper
className={classes.popover}
open={isMenuOpened}
anchorEl={anchor.current}
transition
placement="bottom-end"
>
{({ TransitionProps, placement }) => (
<Grow
{...TransitionProps}
style={{
transformOrigin:
placement === "bottom" ? "right top" : "right bottom"
}}
>
<Paper>
<ClickAwayListener
onClickAway={() => setMenuState(false)}
mouseEvent="onClick"
>
<Menu>
<MenuItem
className={classes.userMenuItem}
onClick={handleViewerProfile}
data-test="accountSettingsButton"
>
<FormattedMessage
defaultMessage="Account Settings"
description="button"
/>
</MenuItem>
<MenuItem
className={classes.userMenuItem}
onClick={handleLogout}
data-test="logOutButton"
>
<FormattedMessage
defaultMessage="Log out"
description="button"
/>
</MenuItem>
</Menu>
</ClickAwayListener>
</Paper>
</Grow>
)}
</Popper>
</div>
);
};
UserChip.displayName = "UserChip";
export default UserChip;

View file

@ -0,0 +1,2 @@
export * from "./UserChip";
export { default } from "./UserChip";

View file

@ -4843,6 +4843,30 @@ exports[`Storyshots Generics / Metadata loading 1`] = `
</div> </div>
`; `;
exports[`Storyshots Generics / Mobile Side Menu default 1`] = `
<div
style="padding:24px"
>
<button
class="MuiButtonBase-root-id ExpandButton-root-id"
tabindex="0"
type="button"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root-id"
focusable="false"
role="presentation"
viewBox="0 0 24 24"
>
<path
d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"
/>
</svg>
</button>
</div>
`;
exports[`Storyshots Generics / Money formatting default 1`] = ` exports[`Storyshots Generics / Money formatting default 1`] = `
<div <div
style="padding:24px" style="padding:24px"
@ -9266,6 +9290,30 @@ exports[`Storyshots Generics / Skeleton default 1`] = `
</div> </div>
`; `;
exports[`Storyshots Generics / Square Button default 1`] = `
<div
style="padding:24px"
>
<button
class="MuiButtonBase-root-id ExpandButton-root-id"
tabindex="0"
type="button"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root-id"
focusable="false"
role="presentation"
viewBox="0 0 24 24"
>
<path
d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"
/>
</svg>
</button>
</div>
`;
exports[`Storyshots Generics / StatusLabel when error 1`] = ` exports[`Storyshots Generics / StatusLabel when error 1`] = `
<div <div
style="padding:24px" style="padding:24px"