feat: documents db [wip].

This commit is contained in:
Darshan
2025-10-13 14:40:23 +05:30
parent a069f1d04f
commit cc8fe2814b
19 changed files with 980 additions and 105 deletions
@@ -0,0 +1,27 @@
<svg xmlns="http://www.w3.org/2000/svg" width="82" height="20" viewBox="0 0 82 20" fill="none">
<g clip-path="url(#clip0_2754_71636)">
<path d="M6.12566 2.06075C5.32306 1.14006 4.63192 0.204996 4.49073 0.0107893C4.47586 -0.00359643 4.45356 -0.00359643 4.4387 0.0107893C4.2975 0.204996 3.60637 1.14006 2.80376 2.06075C-4.08526 10.5555 3.88877 16.2882 3.88877 16.2882L3.95565 16.3314C4.0151 17.216 4.16373 18.4892 4.16373 18.4892H4.461H4.75826C4.75826 18.4892 4.90689 17.2232 4.96634 16.3314L5.03322 16.281C5.04065 16.2882 13.0147 10.5555 6.12566 2.06075ZM4.461 16.1587C4.461 16.1587 4.10429 15.8638 4.00767 15.7128V15.6983L4.4387 6.44839C4.4387 6.41961 4.4833 6.41961 4.4833 6.44839L4.91432 15.6983V15.7128C4.81771 15.8638 4.461 16.1587 4.461 16.1587Z"
fill="white"/>
<path d="M19.3839 14.2711L16.061 6.4245L16.0536 6.40283H13.4683V6.93027H13.8855C14.0121 6.93027 14.1314 6.98085 14.2208 7.06755C14.3102 7.15425 14.3549 7.26988 14.3549 7.39269L14.2804 15.2899C14.2804 15.5355 14.0718 15.7378 13.8185 15.7451L13.3938 15.7523V16.2725H15.9121V15.7523L15.6513 15.7451C15.398 15.7378 15.1893 15.5355 15.1893 15.2899V7.84787L18.8103 16.2725C18.8624 16.3953 18.9816 16.4748 19.1157 16.4748C19.2498 16.4748 19.369 16.3953 19.4212 16.2725L22.9601 8.03571L23.0123 15.2899C23.0123 15.5428 22.8036 15.7451 22.5429 15.7523H22.2747V16.2725H25.225V15.7523H24.8227C24.5694 15.7523 24.3607 15.5428 24.3533 15.2971L24.331 7.39988C24.331 7.14703 24.5395 6.94472 24.7929 6.93749L25.225 6.93027V6.40283H22.7068L19.3839 14.2711Z"
fill="white"/>
<path d="M42.5528 15.6148C42.4706 15.5352 42.4258 15.4266 42.4258 15.2964V11.4169C42.4258 10.6787 42.2018 10.0997 41.7535 9.68714C41.3128 9.27455 40.7003 9.0647 39.9384 9.0647C38.8702 9.0647 38.0261 9.48448 37.436 10.3096C37.4286 10.324 37.4062 10.3313 37.3838 10.3313C37.3613 10.3313 37.3464 10.3168 37.3464 10.2951L37.07 9.26009H36.6068L35.4192 9.91873V10.2806H35.7255C35.8674 10.2806 35.9869 10.3168 36.0691 10.3892C36.1512 10.4616 36.196 10.5702 36.196 10.7221V15.2891C36.196 15.4194 36.1512 15.5279 36.0691 15.6076C35.9869 15.6871 35.8749 15.7306 35.7404 15.7306H35.4416V16.2589H38.1755V15.7306H37.8767C37.7423 15.7306 37.6302 15.6871 37.5481 15.6076C37.4659 15.5279 37.421 15.4194 37.421 15.2891V12.2638C37.421 11.8802 37.5107 11.4966 37.6751 11.1202C37.8468 10.7511 38.1008 10.4399 38.437 10.201C38.7731 9.96218 39.1765 9.84635 39.6396 9.84635C40.1625 9.84635 40.5584 10.0056 40.8048 10.3241C41.0514 10.6425 41.1784 11.0551 41.1784 11.5472V15.2819C41.1784 15.4121 41.1335 15.5207 41.0514 15.6003C40.9692 15.6799 40.8572 15.7233 40.7227 15.7233H40.4239V16.2517H43.1578V15.7233H42.8591C42.747 15.7379 42.6424 15.6944 42.5528 15.6148Z"
fill="white"/>
<path d="M67.5307 6.99362C66.775 6.60456 65.9304 6.40283 65.0191 6.40283H61.4629V6.92877H61.8111C61.9445 6.92877 62.063 6.97921 62.1815 7.09449C62.2927 7.20254 62.3519 7.32506 62.3519 7.4547V15.2071C62.3519 15.3367 62.2927 15.4592 62.1815 15.5673C62.0705 15.6754 61.9445 15.733 61.8111 15.733H61.4629V16.2589H65.0191C65.9304 16.2589 66.775 16.0572 67.5307 15.6682C68.2864 15.2791 68.9014 14.7027 69.3459 13.9679C69.7904 13.233 70.0201 12.3468 70.0201 11.3381C70.0201 10.3295 69.7904 9.45046 69.3459 8.70837C68.8939 7.95909 68.2864 7.38988 67.5307 6.99362ZM68.5902 11.3237C68.5902 12.2459 68.4198 13.024 68.0864 13.6508C67.753 14.2777 67.3084 14.7459 66.7602 15.0486C66.212 15.3512 65.6044 15.5025 64.9524 15.5025H64.2338C64.1004 15.5025 63.9819 15.452 63.8634 15.3367C63.7522 15.2287 63.693 15.1062 63.693 14.9765V7.6637C63.693 7.53398 63.7448 7.41873 63.8634 7.30341C63.9745 7.19535 64.1004 7.13772 64.2338 7.13772H64.9524C65.6044 7.13772 66.212 7.28902 66.7602 7.59161C67.3084 7.8942 67.753 8.36254 68.0864 8.98931C68.4198 9.62334 68.5902 10.4087 68.5902 11.3237Z"
fill="white"/>
<path d="M78.4261 11.8497C78.0972 11.4822 77.4625 11.1724 76.7161 11.0066C77.7467 10.5095 78.2765 9.81067 78.2765 8.9101C78.2765 8.42017 78.1426 7.98067 77.8732 7.606C77.6046 7.23139 77.2236 6.92877 76.7385 6.71983C76.2526 6.5109 75.6848 6.40283 75.0427 6.40283H71.0172V6.92877H71.3384C71.4728 6.92877 71.5923 6.97921 71.7118 7.09449C71.8238 7.20254 71.8836 7.32506 71.8836 7.4547V15.2071C71.8836 15.3367 71.8238 15.4592 71.7118 15.5673C71.5998 15.6754 71.4728 15.733 71.3384 15.733H70.9873V16.2589H75.3567C76.0212 16.2589 76.641 16.1509 77.2013 15.9347C77.7616 15.7186 78.2096 15.4016 78.531 14.9837C78.8592 14.5659 79.0236 14.0543 79.0236 13.4635C79.0162 12.8295 78.8219 12.2891 78.4261 11.8497ZM73.4146 15.3439C73.3026 15.2359 73.2428 15.1134 73.2428 14.9837V11.5038H75.3195C76.0509 11.5038 76.6112 11.6839 76.9996 12.0441C77.3881 12.4044 77.5823 12.8727 77.5823 13.4491C77.5823 13.7949 77.4922 14.1336 77.3285 14.4433C77.1566 14.7604 76.9022 15.0125 76.5591 15.2071C76.2228 15.4016 75.8046 15.5025 75.3195 15.5025H73.788C73.6536 15.5025 73.5341 15.452 73.4146 15.3439ZM73.2503 10.7617V7.67089C73.2503 7.54118 73.3026 7.42593 73.4221 7.3106C73.5341 7.20254 73.6611 7.14492 73.7955 7.14492H74.7815C75.4906 7.14492 76.0137 7.31787 76.3426 7.64923C76.6708 7.98787 76.8352 8.42017 76.8352 8.95334C76.8352 9.50089 76.6782 9.94039 76.3724 10.2718C76.0658 10.596 75.603 10.7617 74.9906 10.7617H73.2503Z"
fill="white"/>
<path d="M32.1451 9.52427C31.5744 9.22268 30.937 9.0647 30.2477 9.0647C29.5584 9.0647 28.9136 9.21549 28.3503 9.52427C27.7796 9.82578 27.3275 10.2638 26.994 10.8166C26.6605 11.3695 26.49 12.0158 26.49 12.7338C26.49 13.4517 26.6605 14.098 26.994 14.6509C27.3275 15.2038 27.7796 15.6417 28.3503 15.9433C28.921 16.2448 29.5584 16.4028 30.2477 16.4028C30.937 16.4028 31.5818 16.252 32.1451 15.9433C32.7158 15.6417 33.1679 15.2038 33.5014 14.6509C33.8349 14.098 34.0054 13.4517 34.0054 12.7338C34.0054 12.0158 33.8349 11.3695 33.5014 10.8166C33.1679 10.2638 32.7158 9.82578 32.1451 9.52427ZM32.6936 12.7338C32.6936 13.6169 32.4712 14.3349 32.0265 14.8519C31.5892 15.3689 30.9889 15.6346 30.2477 15.6346C29.5066 15.6346 28.9062 15.3689 28.4689 14.8519C28.0242 14.3349 27.8018 13.6169 27.8018 12.7338C27.8018 11.8506 28.0242 11.1326 28.4689 10.6156C28.9062 10.0987 29.5066 9.83297 30.2477 9.83297C30.9889 9.83297 31.5892 10.0987 32.0265 10.6156C32.4712 11.1326 32.6936 11.8506 32.6936 12.7338Z"
fill="white"/>
<path d="M58.4119 9.52427C57.8412 9.22268 57.2038 9.0647 56.5145 9.0647C55.8253 9.0647 55.1804 9.21549 54.6172 9.52427C54.0464 9.82578 53.5943 10.2638 53.2608 10.8166C52.9273 11.3695 52.7568 12.0158 52.7568 12.7338C52.7568 13.4517 52.9273 14.098 53.2608 14.6509C53.5943 15.2038 54.0464 15.6417 54.6172 15.9433C55.1879 16.2448 55.8253 16.4028 56.5145 16.4028C57.2038 16.4028 57.8487 16.252 58.4119 15.9433C58.9827 15.6417 59.4348 15.2038 59.7683 14.6509C60.1018 14.098 60.2723 13.4517 60.2723 12.7338C60.2723 12.0158 60.1018 11.3695 59.7683 10.8166C59.4348 10.2638 58.9752 9.82578 58.4119 9.52427ZM58.9604 12.7338C58.9604 13.6169 58.738 14.3349 58.2933 14.8519C57.856 15.3689 57.2557 15.6346 56.5145 15.6346C55.7733 15.6346 55.173 15.3689 54.7358 14.8519C54.291 14.3349 54.0687 13.6169 54.0687 12.7338C54.0687 11.8434 54.291 11.1326 54.7358 10.6156C55.173 10.0987 55.7733 9.83297 56.5145 9.83297C57.2557 9.83297 57.856 10.0987 58.2933 10.6156C58.7306 11.1326 58.9604 11.8506 58.9604 12.7338Z"
fill="white"/>
<path d="M47.819 9.0647C47.2218 9.0647 46.6769 9.18729 46.1843 9.43254C45.6916 9.67779 45.3035 10.0097 45.0273 10.4352C44.7511 10.8535 44.6093 11.3225 44.6093 11.8202C44.6093 12.2674 44.7138 12.6785 44.9302 13.0464C45.1393 13.3999 45.4229 13.6956 45.7812 13.9408L44.7138 15.3402C44.5794 15.5133 44.5645 15.7441 44.6615 15.9317C44.766 16.1264 44.9601 16.2419 45.184 16.2419H45.4901C45.1915 16.4366 44.9526 16.6674 44.7884 16.9415C44.5943 17.2517 44.4973 17.5763 44.4973 17.9081C44.4973 18.5284 44.781 19.0406 45.3408 19.4229C45.8932 19.8052 46.6694 19.9999 47.6472 19.9999C48.3265 19.9999 48.9759 19.8917 49.5656 19.6825C50.1628 19.4734 50.6479 19.1632 51.0062 18.7593C51.372 18.3553 51.5586 17.8648 51.5586 17.3022C51.5586 16.7107 51.3346 16.2923 50.8121 15.8884C50.3643 15.5494 49.6626 15.3691 48.7893 15.3691H45.8036C45.7961 15.3691 45.7886 15.3618 45.7886 15.3618C45.7886 15.3618 45.7812 15.3474 45.7886 15.3402L46.5649 14.3304C46.774 14.4241 46.968 14.4818 47.1397 14.5179C47.3188 14.554 47.5204 14.5684 47.7443 14.5684C48.3713 14.5684 48.9386 14.4458 49.4312 14.2005C49.9239 13.9553 50.3195 13.6235 50.6032 13.1979C50.8868 12.7795 51.0286 12.3107 51.0286 11.813C51.0286 11.2792 50.7599 10.3053 50.0284 9.80765C50.0284 9.80045 50.0359 9.80045 50.0359 9.80045L51.6407 9.97355V9.25945H49.0729C48.6699 9.13686 48.2519 9.0647 47.819 9.0647ZM48.7147 13.5802C48.431 13.7244 48.125 13.8038 47.819 13.8038C47.3189 13.8038 46.8784 13.6307 46.5052 13.2917C46.132 12.9526 45.9454 12.4549 45.9454 11.8202C45.9454 11.1854 46.132 10.6876 46.5052 10.3487C46.8784 10.0097 47.3189 9.8365 47.819 9.8365C48.1325 9.8365 48.431 9.90865 48.7147 10.0601C48.9983 10.2044 49.2297 10.428 49.4163 10.7238C49.5955 11.0195 49.6925 11.3874 49.6925 11.8202C49.6925 12.2602 49.6029 12.628 49.4163 12.9166C49.2372 13.2123 48.9983 13.4359 48.7147 13.5802ZM46.6918 16.2346H48.7147C49.2745 16.2346 49.6328 16.3428 49.8717 16.5737C50.1105 16.8045 50.2299 17.1146 50.2299 17.4753C50.2299 18.0019 50.0135 18.4347 49.5806 18.7593C49.1476 19.0839 48.5654 19.2498 47.8488 19.2498C47.2218 19.2498 46.6993 19.1128 46.3186 18.853C45.9379 18.5934 45.7438 18.1966 45.7438 17.6917C45.7438 17.3743 45.8334 17.0786 46.0126 16.8189C46.1917 16.5592 46.4082 16.3717 46.6918 16.2346Z"
fill="white"/>
<path d="M80.5379 16.1387C80.3906 16.0607 80.2797 15.9474 80.1912 15.8129C80.1101 15.6713 80.0654 15.5226 80.0654 15.3597C80.0654 15.1969 80.1101 15.0411 80.1912 14.9066C80.2723 14.7649 80.3906 14.6587 80.5379 14.5808C80.686 14.503 80.8482 14.4604 81.0328 14.4604C81.2173 14.4604 81.3795 14.503 81.5276 14.5808C81.6749 14.6587 81.7858 14.772 81.8743 14.9066C81.9555 15.0481 82.0001 15.1969 82.0001 15.3597C82.0001 15.5226 81.9555 15.6784 81.8743 15.8129C81.7932 15.9545 81.6749 16.0607 81.5276 16.1387C81.3795 16.2165 81.2173 16.259 81.0328 16.259C80.8557 16.259 80.686 16.2236 80.5379 16.1387ZM81.4465 16.0395C81.5715 15.9758 81.6608 15.8766 81.7345 15.7633C81.8007 15.643 81.8379 15.5084 81.8379 15.3597C81.8379 15.211 81.8007 15.0765 81.7345 14.9561C81.6675 14.8358 81.5715 14.7437 81.4465 14.6799C81.3207 14.6162 81.1875 14.5808 81.0328 14.5808C80.878 14.5808 80.7448 14.6162 80.619 14.6799C80.494 14.7437 80.4047 14.8428 80.3311 14.9561C80.2648 15.0765 80.2276 15.211 80.2276 15.3597C80.2276 15.5084 80.2648 15.643 80.3311 15.7633C80.398 15.8837 80.494 15.9758 80.619 16.0395C80.7448 16.1033 80.878 16.1387 81.0328 16.1387C81.1875 16.1387 81.3282 16.1033 81.4465 16.0395ZM80.6339 15.7917V15.7279L80.6488 15.7209H80.6934C80.7076 15.7209 80.7225 15.7138 80.7299 15.7067C80.7448 15.6925 80.7448 15.6855 80.7448 15.6713V15.0128C80.7448 14.9986 80.7374 14.9845 80.7299 14.9774C80.715 14.9632 80.7076 14.9632 80.6934 14.9632H80.6488L80.6339 14.9561V14.8924L80.6488 14.8853H81.0328C81.1436 14.8853 81.2247 14.9066 81.291 14.9561C81.3579 15.0057 81.387 15.0694 81.387 15.1544C81.387 15.2181 81.3654 15.2818 81.3133 15.3243C81.2619 15.3739 81.2024 15.4022 81.1288 15.4093L81.2173 15.4376L81.387 15.6996C81.4018 15.7209 81.4167 15.7279 81.439 15.7279H81.4829L81.4904 15.7351V15.7987L81.4829 15.8058H81.2545L81.2396 15.7987L81.003 15.4163H80.9442V15.6713C80.9442 15.6855 80.9517 15.6996 80.9591 15.7067C80.974 15.7209 80.9814 15.7209 80.9956 15.7209H81.0402L81.0551 15.7279V15.7917L81.0402 15.7987H80.6488L80.6339 15.7917ZM81.0104 15.3243C81.07 15.3243 81.1213 15.3102 81.1511 15.2748C81.1801 15.2464 81.2024 15.1969 81.2024 15.1402C81.2024 15.0835 81.1875 15.0411 81.1585 15.0057C81.1287 14.9703 81.0841 14.9561 81.0328 14.9561H81.003C80.9881 14.9561 80.974 14.9632 80.9665 14.9703C80.9517 14.9844 80.9517 14.9915 80.9517 15.0057V15.3243H81.0104Z"
fill="white"/>
</g>
<defs>
<clipPath id="clip0_2754_71636">
<rect width="82" height="20" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 451 KiB

@@ -0,0 +1,27 @@
<svg xmlns="http://www.w3.org/2000/svg" width="82" height="20" viewBox="0 0 82 20" fill="none">
<g clip-path="url(#clip0_2754_71636)">
<path d="M6.12566 2.06075C5.32306 1.14006 4.63192 0.204996 4.49073 0.0107893C4.47586 -0.00359643 4.45356 -0.00359643 4.4387 0.0107893C4.2975 0.204996 3.60637 1.14006 2.80376 2.06075C-4.08526 10.5555 3.88877 16.2882 3.88877 16.2882L3.95565 16.3314C4.0151 17.216 4.16373 18.4892 4.16373 18.4892H4.461H4.75826C4.75826 18.4892 4.90689 17.2232 4.96634 16.3314L5.03322 16.281C5.04065 16.2882 13.0147 10.5555 6.12566 2.06075ZM4.461 16.1587C4.461 16.1587 4.10429 15.8638 4.00767 15.7128V15.6983L4.4387 6.44839C4.4387 6.41961 4.4833 6.41961 4.4833 6.44839L4.91432 15.6983V15.7128C4.81771 15.8638 4.461 16.1587 4.461 16.1587Z"
fill="#001E2B"/>
<path d="M19.3839 14.2711L16.061 6.4245L16.0536 6.40283H13.4683V6.93027H13.8855C14.0121 6.93027 14.1314 6.98085 14.2208 7.06755C14.3102 7.15425 14.3549 7.26988 14.3549 7.39269L14.2804 15.2899C14.2804 15.5355 14.0718 15.7378 13.8185 15.7451L13.3938 15.7523V16.2725H15.9121V15.7523L15.6513 15.7451C15.398 15.7378 15.1893 15.5355 15.1893 15.2899V7.84787L18.8103 16.2725C18.8624 16.3953 18.9816 16.4748 19.1157 16.4748C19.2498 16.4748 19.369 16.3953 19.4212 16.2725L22.9601 8.03571L23.0123 15.2899C23.0123 15.5428 22.8036 15.7451 22.5429 15.7523H22.2747V16.2725H25.225V15.7523H24.8227C24.5694 15.7523 24.3607 15.5428 24.3533 15.2971L24.331 7.39988C24.331 7.14703 24.5395 6.94472 24.7929 6.93749L25.225 6.93027V6.40283H22.7068L19.3839 14.2711Z"
fill="#001E2B"/>
<path d="M42.5528 15.6148C42.4706 15.5352 42.4258 15.4266 42.4258 15.2964V11.4169C42.4258 10.6787 42.2018 10.0997 41.7535 9.68714C41.3128 9.27455 40.7003 9.0647 39.9384 9.0647C38.8702 9.0647 38.0261 9.48448 37.436 10.3096C37.4286 10.324 37.4062 10.3313 37.3838 10.3313C37.3613 10.3313 37.3464 10.3168 37.3464 10.2951L37.07 9.26009H36.6068L35.4192 9.91873V10.2806H35.7255C35.8674 10.2806 35.9869 10.3168 36.0691 10.3892C36.1512 10.4616 36.196 10.5702 36.196 10.7221V15.2891C36.196 15.4194 36.1512 15.5279 36.0691 15.6076C35.9869 15.6871 35.8749 15.7306 35.7404 15.7306H35.4416V16.2589H38.1755V15.7306H37.8767C37.7423 15.7306 37.6302 15.6871 37.5481 15.6076C37.4659 15.5279 37.421 15.4194 37.421 15.2891V12.2638C37.421 11.8802 37.5107 11.4966 37.6751 11.1202C37.8468 10.7511 38.1008 10.4399 38.437 10.201C38.7731 9.96218 39.1765 9.84635 39.6396 9.84635C40.1625 9.84635 40.5584 10.0056 40.8048 10.3241C41.0514 10.6425 41.1784 11.0551 41.1784 11.5472V15.2819C41.1784 15.4121 41.1335 15.5207 41.0514 15.6003C40.9692 15.6799 40.8572 15.7233 40.7227 15.7233H40.4239V16.2517H43.1578V15.7233H42.8591C42.747 15.7379 42.6424 15.6944 42.5528 15.6148Z"
fill="#001E2B"/>
<path d="M67.5307 6.99362C66.775 6.60456 65.9304 6.40283 65.0191 6.40283H61.4629V6.92877H61.8111C61.9445 6.92877 62.063 6.97921 62.1815 7.09449C62.2927 7.20254 62.3519 7.32506 62.3519 7.4547V15.2071C62.3519 15.3367 62.2927 15.4592 62.1815 15.5673C62.0705 15.6754 61.9445 15.733 61.8111 15.733H61.4629V16.2589H65.0191C65.9304 16.2589 66.775 16.0572 67.5307 15.6682C68.2864 15.2791 68.9014 14.7027 69.3459 13.9679C69.7904 13.233 70.0201 12.3468 70.0201 11.3381C70.0201 10.3295 69.7904 9.45046 69.3459 8.70837C68.8939 7.95909 68.2864 7.38988 67.5307 6.99362ZM68.5902 11.3237C68.5902 12.2459 68.4198 13.024 68.0864 13.6508C67.753 14.2777 67.3084 14.7459 66.7602 15.0486C66.212 15.3512 65.6044 15.5025 64.9524 15.5025H64.2338C64.1004 15.5025 63.9819 15.452 63.8634 15.3367C63.7522 15.2287 63.693 15.1062 63.693 14.9765V7.6637C63.693 7.53398 63.7448 7.41873 63.8634 7.30341C63.9745 7.19535 64.1004 7.13772 64.2338 7.13772H64.9524C65.6044 7.13772 66.212 7.28902 66.7602 7.59161C67.3084 7.8942 67.753 8.36254 68.0864 8.98931C68.4198 9.62334 68.5902 10.4087 68.5902 11.3237Z"
fill="#001E2B"/>
<path d="M78.4261 11.8497C78.0972 11.4822 77.4625 11.1724 76.7161 11.0066C77.7467 10.5095 78.2765 9.81067 78.2765 8.9101C78.2765 8.42017 78.1426 7.98067 77.8732 7.606C77.6046 7.23139 77.2236 6.92877 76.7385 6.71983C76.2526 6.5109 75.6848 6.40283 75.0427 6.40283H71.0172V6.92877H71.3384C71.4728 6.92877 71.5923 6.97921 71.7118 7.09449C71.8238 7.20254 71.8836 7.32506 71.8836 7.4547V15.2071C71.8836 15.3367 71.8238 15.4592 71.7118 15.5673C71.5998 15.6754 71.4728 15.733 71.3384 15.733H70.9873V16.2589H75.3567C76.0212 16.2589 76.641 16.1509 77.2013 15.9347C77.7616 15.7186 78.2096 15.4016 78.531 14.9837C78.8592 14.5659 79.0236 14.0543 79.0236 13.4635C79.0162 12.8295 78.8219 12.2891 78.4261 11.8497ZM73.4146 15.3439C73.3026 15.2359 73.2428 15.1134 73.2428 14.9837V11.5038H75.3195C76.0509 11.5038 76.6112 11.6839 76.9996 12.0441C77.3881 12.4044 77.5823 12.8727 77.5823 13.4491C77.5823 13.7949 77.4922 14.1336 77.3285 14.4433C77.1566 14.7604 76.9022 15.0125 76.5591 15.2071C76.2228 15.4016 75.8046 15.5025 75.3195 15.5025H73.788C73.6536 15.5025 73.5341 15.452 73.4146 15.3439ZM73.2503 10.7617V7.67089C73.2503 7.54118 73.3026 7.42593 73.4221 7.3106C73.5341 7.20254 73.6611 7.14492 73.7955 7.14492H74.7815C75.4906 7.14492 76.0137 7.31787 76.3426 7.64923C76.6708 7.98787 76.8352 8.42017 76.8352 8.95334C76.8352 9.50089 76.6782 9.94039 76.3724 10.2718C76.0658 10.596 75.603 10.7617 74.9906 10.7617H73.2503Z"
fill="#001E2B"/>
<path d="M32.1451 9.52427C31.5744 9.22268 30.937 9.0647 30.2477 9.0647C29.5584 9.0647 28.9136 9.21549 28.3503 9.52427C27.7796 9.82578 27.3275 10.2638 26.994 10.8166C26.6605 11.3695 26.49 12.0158 26.49 12.7338C26.49 13.4517 26.6605 14.098 26.994 14.6509C27.3275 15.2038 27.7796 15.6417 28.3503 15.9433C28.921 16.2448 29.5584 16.4028 30.2477 16.4028C30.937 16.4028 31.5818 16.252 32.1451 15.9433C32.7158 15.6417 33.1679 15.2038 33.5014 14.6509C33.8349 14.098 34.0054 13.4517 34.0054 12.7338C34.0054 12.0158 33.8349 11.3695 33.5014 10.8166C33.1679 10.2638 32.7158 9.82578 32.1451 9.52427ZM32.6936 12.7338C32.6936 13.6169 32.4712 14.3349 32.0265 14.8519C31.5892 15.3689 30.9889 15.6346 30.2477 15.6346C29.5066 15.6346 28.9062 15.3689 28.4689 14.8519C28.0242 14.3349 27.8018 13.6169 27.8018 12.7338C27.8018 11.8506 28.0242 11.1326 28.4689 10.6156C28.9062 10.0987 29.5066 9.83297 30.2477 9.83297C30.9889 9.83297 31.5892 10.0987 32.0265 10.6156C32.4712 11.1326 32.6936 11.8506 32.6936 12.7338Z"
fill="#001E2B"/>
<path d="M58.4119 9.52427C57.8412 9.22268 57.2038 9.0647 56.5145 9.0647C55.8253 9.0647 55.1804 9.21549 54.6172 9.52427C54.0464 9.82578 53.5943 10.2638 53.2608 10.8166C52.9273 11.3695 52.7568 12.0158 52.7568 12.7338C52.7568 13.4517 52.9273 14.098 53.2608 14.6509C53.5943 15.2038 54.0464 15.6417 54.6172 15.9433C55.1879 16.2448 55.8253 16.4028 56.5145 16.4028C57.2038 16.4028 57.8487 16.252 58.4119 15.9433C58.9827 15.6417 59.4348 15.2038 59.7683 14.6509C60.1018 14.098 60.2723 13.4517 60.2723 12.7338C60.2723 12.0158 60.1018 11.3695 59.7683 10.8166C59.4348 10.2638 58.9752 9.82578 58.4119 9.52427ZM58.9604 12.7338C58.9604 13.6169 58.738 14.3349 58.2933 14.8519C57.856 15.3689 57.2557 15.6346 56.5145 15.6346C55.7733 15.6346 55.173 15.3689 54.7358 14.8519C54.291 14.3349 54.0687 13.6169 54.0687 12.7338C54.0687 11.8434 54.291 11.1326 54.7358 10.6156C55.173 10.0987 55.7733 9.83297 56.5145 9.83297C57.2557 9.83297 57.856 10.0987 58.2933 10.6156C58.7306 11.1326 58.9604 11.8506 58.9604 12.7338Z"
fill="#001E2B"/>
<path d="M47.819 9.0647C47.2218 9.0647 46.6769 9.18729 46.1843 9.43254C45.6916 9.67779 45.3035 10.0097 45.0273 10.4352C44.7511 10.8535 44.6093 11.3225 44.6093 11.8202C44.6093 12.2674 44.7138 12.6785 44.9302 13.0464C45.1393 13.3999 45.4229 13.6956 45.7812 13.9408L44.7138 15.3402C44.5794 15.5133 44.5645 15.7441 44.6615 15.9317C44.766 16.1264 44.9601 16.2419 45.184 16.2419H45.4901C45.1915 16.4366 44.9526 16.6674 44.7884 16.9415C44.5943 17.2517 44.4973 17.5763 44.4973 17.9081C44.4973 18.5284 44.781 19.0406 45.3408 19.4229C45.8932 19.8052 46.6694 19.9999 47.6472 19.9999C48.3265 19.9999 48.9759 19.8917 49.5656 19.6825C50.1628 19.4734 50.6479 19.1632 51.0062 18.7593C51.372 18.3553 51.5586 17.8648 51.5586 17.3022C51.5586 16.7107 51.3346 16.2923 50.8121 15.8884C50.3643 15.5494 49.6626 15.3691 48.7893 15.3691H45.8036C45.7961 15.3691 45.7886 15.3618 45.7886 15.3618C45.7886 15.3618 45.7812 15.3474 45.7886 15.3402L46.5649 14.3304C46.774 14.4241 46.968 14.4818 47.1397 14.5179C47.3188 14.554 47.5204 14.5684 47.7443 14.5684C48.3713 14.5684 48.9386 14.4458 49.4312 14.2005C49.9239 13.9553 50.3195 13.6235 50.6032 13.1979C50.8868 12.7795 51.0286 12.3107 51.0286 11.813C51.0286 11.2792 50.7599 10.3053 50.0284 9.80765C50.0284 9.80045 50.0359 9.80045 50.0359 9.80045L51.6407 9.97355V9.25945H49.0729C48.6699 9.13686 48.2519 9.0647 47.819 9.0647ZM48.7147 13.5802C48.431 13.7244 48.125 13.8038 47.819 13.8038C47.3189 13.8038 46.8784 13.6307 46.5052 13.2917C46.132 12.9526 45.9454 12.4549 45.9454 11.8202C45.9454 11.1854 46.132 10.6876 46.5052 10.3487C46.8784 10.0097 47.3189 9.8365 47.819 9.8365C48.1325 9.8365 48.431 9.90865 48.7147 10.0601C48.9983 10.2044 49.2297 10.428 49.4163 10.7238C49.5955 11.0195 49.6925 11.3874 49.6925 11.8202C49.6925 12.2602 49.6029 12.628 49.4163 12.9166C49.2372 13.2123 48.9983 13.4359 48.7147 13.5802ZM46.6918 16.2346H48.7147C49.2745 16.2346 49.6328 16.3428 49.8717 16.5737C50.1105 16.8045 50.2299 17.1146 50.2299 17.4753C50.2299 18.0019 50.0135 18.4347 49.5806 18.7593C49.1476 19.0839 48.5654 19.2498 47.8488 19.2498C47.2218 19.2498 46.6993 19.1128 46.3186 18.853C45.9379 18.5934 45.7438 18.1966 45.7438 17.6917C45.7438 17.3743 45.8334 17.0786 46.0126 16.8189C46.1917 16.5592 46.4082 16.3717 46.6918 16.2346Z"
fill="#001E2B"/>
<path d="M80.5379 16.1387C80.3906 16.0607 80.2797 15.9474 80.1912 15.8129C80.1101 15.6713 80.0654 15.5226 80.0654 15.3597C80.0654 15.1969 80.1101 15.0411 80.1912 14.9066C80.2723 14.7649 80.3906 14.6587 80.5379 14.5808C80.686 14.503 80.8482 14.4604 81.0328 14.4604C81.2173 14.4604 81.3795 14.503 81.5276 14.5808C81.6749 14.6587 81.7858 14.772 81.8743 14.9066C81.9555 15.0481 82.0001 15.1969 82.0001 15.3597C82.0001 15.5226 81.9555 15.6784 81.8743 15.8129C81.7932 15.9545 81.6749 16.0607 81.5276 16.1387C81.3795 16.2165 81.2173 16.259 81.0328 16.259C80.8557 16.259 80.686 16.2236 80.5379 16.1387ZM81.4465 16.0395C81.5715 15.9758 81.6608 15.8766 81.7345 15.7633C81.8007 15.643 81.8379 15.5084 81.8379 15.3597C81.8379 15.211 81.8007 15.0765 81.7345 14.9561C81.6675 14.8358 81.5715 14.7437 81.4465 14.6799C81.3207 14.6162 81.1875 14.5808 81.0328 14.5808C80.878 14.5808 80.7448 14.6162 80.619 14.6799C80.494 14.7437 80.4047 14.8428 80.3311 14.9561C80.2648 15.0765 80.2276 15.211 80.2276 15.3597C80.2276 15.5084 80.2648 15.643 80.3311 15.7633C80.398 15.8837 80.494 15.9758 80.619 16.0395C80.7448 16.1033 80.878 16.1387 81.0328 16.1387C81.1875 16.1387 81.3282 16.1033 81.4465 16.0395ZM80.6339 15.7917V15.7279L80.6488 15.7209H80.6934C80.7076 15.7209 80.7225 15.7138 80.7299 15.7067C80.7448 15.6925 80.7448 15.6855 80.7448 15.6713V15.0128C80.7448 14.9986 80.7374 14.9845 80.7299 14.9774C80.715 14.9632 80.7076 14.9632 80.6934 14.9632H80.6488L80.6339 14.9561V14.8924L80.6488 14.8853H81.0328C81.1436 14.8853 81.2247 14.9066 81.291 14.9561C81.3579 15.0057 81.387 15.0694 81.387 15.1544C81.387 15.2181 81.3654 15.2818 81.3133 15.3243C81.2619 15.3739 81.2024 15.4022 81.1288 15.4093L81.2173 15.4376L81.387 15.6996C81.4018 15.7209 81.4167 15.7279 81.439 15.7279H81.4829L81.4904 15.7351V15.7987L81.4829 15.8058H81.2545L81.2396 15.7987L81.003 15.4163H80.9442V15.6713C80.9442 15.6855 80.9517 15.6996 80.9591 15.7067C80.974 15.7209 80.9814 15.7209 80.9956 15.7209H81.0402L81.0551 15.7279V15.7917L81.0402 15.7987H80.6488L80.6339 15.7917ZM81.0104 15.3243C81.07 15.3243 81.1213 15.3102 81.1511 15.2748C81.1801 15.2464 81.2024 15.1969 81.2024 15.1402C81.2024 15.0835 81.1875 15.0411 81.1585 15.0057C81.1287 14.9703 81.0841 14.9561 81.0328 14.9561H81.003C80.9881 14.9561 80.974 14.9632 80.9665 14.9703C80.9517 14.9844 80.9517 14.9915 80.9517 15.0057V15.3243H81.0104Z"
fill="#001E2B"/>
</g>
<defs>
<clipPath id="clip0_2754_71636">
<rect width="82" height="20" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 35 KiB

@@ -1,35 +1,29 @@
<script lang="ts">
import { goto } from '$app/navigation';
import { page } from '$app/state';
import { Empty, PaginationWithLimit } from '$lib/components';
import { PaginationWithLimit } from '$lib/components';
import { Button } from '$lib/elements/forms';
import { Container, ResponsiveContainerHeader } from '$lib/layout';
import type { Models } from '@appwrite.io/console';
import Create from './create.svelte';
import Grid from './grid.svelte';
import { columns } from './store';
import Table from './table.svelte';
import type { PageProps } from './$types';
import { Icon } from '@appwrite.io/pink-svelte';
import { registerCommands } from '$lib/commandCenter';
import { canWriteDatabases } from '$lib/stores/roles';
import { Icon } from '@appwrite.io/pink-svelte';
import { IconPlus } from '@appwrite.io/pink-icons-svelte';
import EmptySearch from '$lib/components/emptySearch.svelte';
import { resolveRoute } from '$lib/stores/navigation';
import { resolveRoute, withPath } from '$lib/stores/navigation';
import EmptyDatabaseCloud from './empty.svelte';
const { data }: PageProps = $props();
let showCreate = $state(false);
async function handleCreate(event: CustomEvent<Models.Database>) {
showCreate = false;
async function goToCreateDatabaseWizard() {
await goto(
resolveRoute('/(console)/project-[region]-[project]/databases/database-[database]', {
...page.params,
database: event.detail.$id
})
resolveRoute('/(console)/project-[region]-[project]/databases/create', page.params)
);
}
@@ -51,22 +45,11 @@
</script>
<Container>
<ResponsiveContainerHeader
hasSearch
{columns}
bind:view={data.view}
searchPlaceholder="Search by name or ID">
{#if $canWriteDatabases}
<Button event="create_database" on:click={() => (showCreate = true)}>
<Icon icon={IconPlus} slot="start" size="s" />
Create database
</Button>
{/if}
</ResponsiveContainerHeader>
{#if data.databases.total}
{@render containerHeader()}
{#if data.view === 'grid'}
<Grid {data} bind:showCreate />
<Grid {data} onCreateDatabaseClick={goToCreateDatabaseWizard} />
{:else}
<Table {data} />
{/if}
@@ -84,13 +67,33 @@
secondary>Clear Search</Button>
</EmptySearch>
{:else}
<Empty
single
href="https://appwrite.io/docs/products/databases/databases"
target="database"
allowCreate={$canWriteDatabases}
on:click={() => (showCreate = true)} />
<EmptyDatabaseCloud
disabled={$canWriteDatabases}
onDatabaseTypeSelected={async (type) => {
await goto(
withPath(
resolveRoute(
'/(console)/project-[region]-[project]/databases/create',
page.params
),
`?type=${type}`
)
);
}} />
{/if}
</Container>
<Create bind:showCreate on:created={handleCreate} />
{#snippet containerHeader()}
<ResponsiveContainerHeader
hasSearch
{columns}
bind:view={data.view}
searchPlaceholder="Search by name or ID">
{#if $canWriteDatabases}
<Button event="create_database" on:click={goToCreateDatabaseWizard}>
<Icon icon={IconPlus} slot="start" size="s" />
Create database
</Button>
{/if}
</ResponsiveContainerHeader>
{/snippet}
@@ -0,0 +1,296 @@
<script lang="ts">
import { Wizard } from '$lib/layout';
import { writable } from 'svelte/store';
import { Form, InputText, Button } from '$lib/elements/forms';
import { Alert, Card, Fieldset, Icon, Layout, Tag, Typography } from '@appwrite.io/pink-svelte';
import { resolveRoute } from '$lib/stores/navigation';
import { afterNavigate, goto } from '$app/navigation';
import { CustomId } from '$lib/components';
import { page } from '$app/state';
import { IconPencil } from '@appwrite.io/pink-icons-svelte';
import { addNotification } from '$lib/stores/notifications';
import { ID, type Models } from '@appwrite.io/console';
import { type DatabaseType, useDatabasesSdk } from '$database/(entity)';
import { isCloud } from '$lib/system';
import { upgradeURL } from '$lib/stores/billing';
import { BillingPlan } from '$lib/constants';
import { organization } from '$lib/stores/organization';
import { isSmallViewport, isTabletViewport } from '$lib/stores/viewport';
import EmptyDarkMobile from '$lib/images/backups/upgrade/backups-mobile-dark.png';
import EmptyLightMobile from '$lib/images/backups/upgrade/backups-mobile-light.png';
import { app } from '$lib/stores/app';
import EmptyDarkTablet from '$lib/images/backups/upgrade/backups-tablet-dark.png';
import EmptyLightTablet from '$lib/images/backups/upgrade/backups-tablet-light.png';
let formComponent: Form;
let databaseId = $state(null);
let databaseName = $state(null);
let backupGroup = $state(null);
let showCustomId = $state(false);
let showExitModal = $state(false);
let isSubmitting = $state(writable(false));
let previousPage: string = $state(resolveRoute('/'));
const typeFromParams = page.url.searchParams.get('type') ?? (null as DatabaseType);
let type = $state(typeFromParams ?? 'tablesdb') as DatabaseType;
const isDark = $derived($app.themeInUse === 'dark');
const theme = $derived(isDark ? 'u-only-dark' : 'u-only-light');
const mobileImg = $derived(isDark ? EmptyDarkMobile : EmptyLightMobile);
const tabletImg = $derived(isDark ? EmptyDarkTablet : EmptyLightTablet);
const databaseTypes: Array<{
type: DatabaseType;
title: string;
subtitle: string;
}> = [
{
type: 'tablesdb',
title: 'TablesDB',
subtitle:
'Structure your data in rows and columns. Best for relational data and advanced querying.'
},
{
type: 'documentsdb',
title: 'DocumentsDB',
subtitle:
'Store flexible data without a fixed schema. Best for unstructured data and simple querying.'
}
];
// TODO: implement!
const backupOptions = [
{
id: 'daily',
title: 'Backup every 24 hours',
subtitle: 'One backup every 24 hours, retained for 30 days'
},
{
id: 'custom',
title: '',
subtitle: '',
policy: ''
},
{
id: '',
title: '',
subtitle: '',
policy: ''
}
];
afterNavigate(({ from }) => (previousPage = from?.url?.pathname || previousPage));
// TODO: Backup policies!
async function createDatabase() {
try {
databaseId ??= ID.unique();
let database: Models.Database;
const databasesSdk = useDatabasesSdk(page.params.region, page.params.project);
database = await databasesSdk.create(type, {
databaseId,
name: databaseName
});
addNotification({
type: 'success',
message: `${database.name} has been created`
});
// goto the database id
await goto(
resolveRoute(
'/(console)/project-[region]-[project]/databases/database-[database]',
{
...page.params,
database: database.$id
}
)
);
} catch (error) {
addNotification({
type: 'error',
message: error.message
});
}
}
</script>
<Wizard
title="Create database"
href={previousPage}
bind:showExitModal
confirmExit
column
columnSize="s">
<Form bind:this={formComponent} onSubmit={createDatabase} bind:isSubmitting>
<Layout.Stack gap="xxl">
<Fieldset legend="Details">
<Layout.Stack direction="column" gap="l">
<InputText
required
id="name"
autofocus
label="Name"
bind:value={databaseName}
placeholder="Enter database name" />
{#if !showCustomId}
<div>
<Tag size="s" on:click={() => (showCustomId = true)}>
<Icon icon={IconPencil} slot="start" size="s" />
Database ID
</Tag>
</div>
{/if}
<CustomId bind:show={showCustomId} name="Database" bind:id={databaseId} />
</Layout.Stack>
</Fieldset>
{#if typeFromParams === null}
<Fieldset legend="Database type">
{@render selectDatabaseType()}
</Fieldset>
{/if}
<Fieldset legend="Backups">
{#if isCloud}
{@render cloudBackupOptions()}
{:else}
{@render selfHostedBackupOptions()}
{/if}
</Fieldset>
</Layout.Stack>
</Form>
<svelte:fragment slot="footer">
<Button
secondary
fullWidthMobile
disabled={$isSubmitting}
on:click={() => (showExitModal = true)}>
Cancel
</Button>
<Button
fullWidthMobile
disabled={$isSubmitting}
on:click={() => formComponent.triggerSubmit()}
>Create
</Button>
</svelte:fragment>
</Wizard>
{#snippet cloudBackupOptions()}
{#if $organization?.billingPlan === BillingPlan.FREE}
<Layout.Grid columns={3} columnsS={1}>
{#each Array.from({ length: 3 }) as _}
<Card.Selector
bind:group={backupGroup}
name="24h"
id="everyDay"
value="24h"
title="Backup every 24 hours"
imageRadius="s">
One backup every 24 hours, retained for 30 days
</Card.Selector>
{/each}
</Layout.Grid>
{:else}
<Alert.Inline title="This database won't be backed up" status="warning">
Upgrade your plan to ensure your data stays safe and backed up.
<svelte:fragment slot="actions">
<Button compact href={$upgradeURL}>Upgrade plan</Button>
</svelte:fragment>
</Alert.Inline>
{/if}
{/snippet}
{#snippet selfHostedBackupOptions()}
<Layout.Stack gap="xl" style="position: relative;">
{@const length = $isTabletViewport ? 2 : 3}
{@const gridsColumn = $isSmallViewport ? 2 : 3}
<Layout.Grid columns={gridsColumn} columnsS={1}>
{#if $isSmallViewport}
<div
style:--p-file-preview-border-color="transparent"
class="is-full-cover-image is-full-width-mobile u-height-100-percent">
<!-- mobile -->
<div
style:min-height="172px"
class="is-only-mobile u-width-full-line u-height-100-percent">
<img
src={mobileImg}
style:width="100vw"
class="placeholder u-image-object-fit-contain {theme}"
alt="Mock Numbers Example" />
</div>
</div>
{:else if $isTabletViewport}
<!-- tablet -->
<div
style:--p-file-preview-border-color="transparent"
class="is-full-cover-image is-full-width-mobile u-height-100-percent">
<div style:min-height="140px" class="is-tablet">
<img
src={tabletImg}
style:width="100vw"
class="u-image-object-fit-contain {theme}"
alt="Backups Example" />
</div>
</div>
{:else}
{#each Array.from({ length }) as _}
<Card.Selector
bind:group={backupGroup}
name="24h"
id="everyDay"
value="24h"
title="Backup every 24 hours"
imageRadius="s"
disabled>
One backup every 24 hours, retained for 30 days
</Card.Selector>
{/each}
{/if}
</Layout.Grid>
<Layout.Stack gap="l">
<Layout.Stack gap="xs">
<Typography.Text variant="m-600">
Database Backups are available on Appwrite Cloud
</Typography.Text>
<Typography.Text>
Sign up now to access Appwrite's backups. Schedule automatic or manual backups
to protect your data and ensure quick recovery.
</Typography.Text>
</Layout.Stack>
<Button external secondary fullWidthMobile href="https://cloud.appwrite.io/register">
Sign up
</Button>
</Layout.Stack>
</Layout.Stack>
{/snippet}
{#snippet selectDatabaseType()}
<Layout.Grid columns={2} columnsS={1}>
{#each databaseTypes as databaseType}
<Card.Selector
bind:group={type}
name={databaseType.type}
id={databaseType.type}
value={databaseType.type}
title={databaseType.title}
imageRadius="s">
{databaseType.subtitle}
</Card.Selector>
{/each}
</Layout.Grid>
{/snippet}
@@ -17,7 +17,7 @@ export type Terminologies = {
analytics: AnalyticsResult;
terminology: TerminologyResult;
dependencies: DependenciesResult;
databaseSdk: DatabaseSdkResult;
databasesSdk: DatabaseSdkResult;
};
export function getTerminologies(): Terminologies {
@@ -5,6 +5,14 @@ import { type DatabaseType, type Entity, type EntityList, toSupportiveEntity } f
import type { Models } from '@appwrite.io/console';
export type DatabaseSdkResult = {
create: (
type: DatabaseType,
params: {
databaseId: string;
name: string;
enabled?: boolean;
}
) => Promise<Models.Database>;
list: (params: { queries?: string[]; search?: string }) => Promise<Models.DatabaseList>;
getEntity: (params: {
databaseId: string;
@@ -42,6 +50,22 @@ export function useDatabasesSdk(
const baseSdk = sdk.forProject(region, project);
return {
async create(type, params): Promise<Models.Database> {
switch (type) {
case 'legacy': /* databases api */
case 'tablesdb': {
return await baseSdk.tablesDB.create(params);
}
case 'documentsdb': {
return await baseSdk.documentsDB.create(params);
}
case 'vectordb':
throw new Error(`Database type not supported yet`);
default:
throw new Error('Unknown database type');
}
},
async list(params): Promise<Models.DatabaseList> {
const results = await Promise.all([
baseSdk.tablesDB.list(params)
@@ -74,7 +98,7 @@ export function useDatabasesSdk(
case 'vectordb':
throw new Error(`Database type not supported yet`);
default:
throw new Error(`Unknown database type`);
throw new Error('Unknown database type');
}
},
@@ -16,19 +16,39 @@
const featureActive = $derived(isCloud);
const { terminology } = getTerminologies();
const type = terminology.type;
const field = terminology.field.lower;
const entity = terminology.entity.lower.singular;
const title = $derived.by(() => {
return featureActive
? `Smart ${field.singular} suggestions`
: `Smart ${field.singular} suggestions available on Cloud`;
switch (type) {
default:
case 'legacy':
case 'tablesdb':
return featureActive
? `Smart ${field.singular} suggestions`
: `Smart ${field.singular} suggestions available on Cloud`;
case 'documentsdb':
return featureActive ? `Sample Data` : `Sample Data available on Cloud`;
}
});
const subtitle = $derived.by(() => {
return featureActive
? `Enable AI to suggest useful ${field.plural} based on your ${entity} name`
: `Sign up for Cloud to generate ${field.plural} based on your ${entity} name`;
switch (type) {
default:
case 'legacy':
case 'tablesdb':
return featureActive
? `Enable AI to suggest useful ${field.plural} based on your ${entity} name`
: `Sign up for Cloud to generate ${field.plural} based on your ${entity} name`;
case 'documentsdb':
return featureActive
? `Enable AI to generate sample documents based on your ${entity} name`
: `Sign up for Cloud to generate sample documents based on your ${entity} name`;
}
});
</script>
@@ -1,8 +1,8 @@
import { sdk } from '$lib/stores/sdk';
import { Dependencies } from '$lib/constants';
import type { LayoutLoad } from './$types';
import Breadcrumbs from './breadcrumbs.svelte';
import Header from './header.svelte';
import { sdk } from '$lib/stores/sdk';
import type { LayoutLoad } from './$types';
import { Dependencies } from '$lib/constants';
import Breadcrumbs from './breadcrumbs.svelte';
import SubNavigation from './subNavigation.svelte';
export const load: LayoutLoad = async ({ params, depends }) => {
@@ -34,6 +34,17 @@
function getImageRoute(type: 'light' | 'dark'): string {
return withPath(resolveRoute('/'), `/images/empty-database-${type}.svg`);
}
const emptyPageText = $derived.by(() => {
switch (terminology.type) {
default:
case 'legacy':
case 'tablesdb':
return `Create, organize, and query structured data with ${entityTitle.plural}.`;
case 'documentsdb':
return `Create, organize, and query flexible data with ${entityTitle.plural}.`;
}
});
</script>
<Container databasesMainScreen>
@@ -53,7 +64,7 @@
{#if $canWriteTables}
<Button event="create_table" on:click={() => ($showCreateEntity = true)}>
<Icon icon={IconPlus} slot="start" size="s" />
Create table
Create {entityLower.singular}
</Button>
{/if}
</Layout.Stack>
@@ -86,9 +97,7 @@
<Empty
src={getImageRoute($app.themeInUse)}
title="Create your first {entityLower.singular}">
<span slot="description">
Create, organize, and query structured data with {entityTitle.plural}.
</span>
<span slot="description">{emptyPageText}</span>
<span slot="actions">
<Button
@@ -4,34 +4,36 @@
import { resolveRoute } from '$lib/stores/navigation';
import { type Organization } from '$lib/stores/organization';
const params = $derived(page.params);
const project = $derived(page.data.project);
const database = $derived(page.data.database);
const organization = $derived(page.data.organization) as Organization;
const breadcrumbs = $derived.by(() => {
const params = page.params;
const project = page.data.project;
const database = page.data.database;
const organization = page.data.organization as Organization;
const breadcrumbs = $derived([
{
href: resolveRoute('/(console)/organization-[organization]', {
organization: organization?.$id ?? project.teamId
}),
title: organization.name
},
{
href: resolveRoute('/(console)/project-[region]-[project]', params),
title: project.name
},
{
href: resolveRoute('/(console)/project-[region]-[project]/databases', params),
title: 'Databases'
},
{
href: resolveRoute(
'/(console)/project-[region]-[project]/databases/database-[database]',
params
),
title: database.name
}
]);
return [
{
href: resolveRoute('/(console)/organization-[organization]', {
organization: organization?.$id ?? project.teamId
}),
title: organization.name
},
{
href: resolveRoute('/(console)/project-[region]-[project]', params),
title: project.name
},
{
href: resolveRoute('/(console)/project-[region]-[project]/databases', params),
title: 'Databases'
},
{
href: resolveRoute(
'/(console)/project-[region]-[project]/databases/database-[database]',
params
),
title: database.name
}
];
});
</script>
<Breadcrumbs {breadcrumbs} />
@@ -24,7 +24,7 @@
let entityItems = $state([]);
let entities: EntityList | null = $state(null);
const { databaseSdk } = getTerminologies();
const { databasesSdk } = getTerminologies();
const database = $derived(page.data.database);
function buildQueries(): string[] {
@@ -48,7 +48,7 @@
try {
const queries = buildQueries();
entities = await databaseSdk.listEntities({
entities = await databasesSdk.listEntities({
databaseId: page.params.database,
queries
});
@@ -71,7 +71,7 @@
const handleDelete = async () => {
try {
await databaseSdk.delete({
await databasesSdk.delete({
databaseId: page.params.database
});
@@ -27,15 +27,15 @@
let errorType: 'error' | 'warning' | 'success' = $state('error');
let showError: false | 'name' | 'email' | 'password' = $state(false);
const { databaseSdk, terminology } = getTerminologies();
const { databasesSdk, terminology } = getTerminologies();
onMount(async () => {
databaseName ??= database.name;
});
async function loadEntityCount() {
const { total } = await databaseSdk.listEntities({
databaseId: database.$id,
const { total } = await databasesSdk.listEntities({
databaseId: page.params.database,
queries: [Query.limit(1)]
});
@@ -41,7 +41,7 @@
let workData = $state<Map<string, Writable<Models.Row>>>(new Map());
let columnFormWrapper = $state<HTMLElement | null>(null);
const { databaseSdk } = getTerminologies();
const { databasesSdk } = getTerminologies();
onMount(() => {
if (rows && tableId) {
@@ -89,7 +89,7 @@
});
if (missingTableIds.length > 0) {
const tablesResponse = await databaseSdk.listEntities({
const tablesResponse = await databasesSdk.listEntities({
databaseId,
queries: [
Query.equal('$id', missingTableIds),
@@ -0,0 +1,129 @@
<script lang="ts">
import { app } from '$lib/stores/app';
import { Card } from '$lib/components';
import { IconArrowRight } from '@appwrite.io/pink-icons-svelte';
import { Layout, Typography, Icon } from '@appwrite.io/pink-svelte';
// TODO: the images have bottom rounded borders.
import MongoDB from './(assets)/mongo-db.svg';
import MongoDBDark from './(assets)/dark/mongo-db.svg';
import TablesDB from './(assets)/tables-db.svg';
import DocumentsDB from './(assets)/documents-db.svg';
import type { DatabaseType } from '$database/(entity)';
import { isSmallViewport, isTabletViewport } from '$lib/stores/viewport';
const {
disabled,
onDatabaseTypeSelected
}: {
disabled?: boolean;
onDatabaseTypeSelected?: (type: DatabaseType) => Promise<void> | void;
} = $props();
const isDark = $derived($app.themeInUse === 'dark');
const mongoDbImage = $derived(isDark ? MongoDBDark : MongoDB);
</script>
{#if $isSmallViewport}
{@render mainContentView()}
{:else}
<Card padding="l" radius="l">
{@render mainContentView()}
</Card>
{/if}
{#snippet mainContentView()}
<Layout.Stack direction="column" gap="xxl">
<Layout.Stack gap="none" direction="column" alignItems="center" alignContent="center">
<Typography.Title>Create your first database</Typography.Title>
<Typography.Text variant="l-400"
>Store, organize, and manage your app data</Typography.Text>
</Layout.Stack>
</Layout.Stack>
<Layout.Grid columns={2} columnsS={1}>
<!-- legacy, tablesDB -->
{@render databaseTypeCard({
type: 'tablesdb',
title: 'TablesDB',
subtitle:
'Structure your data in rows and columns. Best for relational data and advanced querying.',
image: TablesDB
})}
<!-- documentsDB -->
{@render databaseTypeCard({
type: 'documentsdb',
title: 'DocumentsDB',
subtitle:
'Store flexible data without a fixed schema. Best for unstructured data and simple querying.',
image: DocumentsDB,
footer: true
})}
</Layout.Grid>
{/snippet}
{#snippet databaseTypeCard({ type, title, subtitle, image = undefined, footer = false })}
<Card
isButton
radius="s"
padding="none"
{disabled}
on:click={() => onDatabaseTypeSelected?.(type)}>
<Layout.Stack gap="none" direction={$isTabletViewport ? 'column' : 'row'}>
<img class="database-image" src={image} alt="database type artwork" />
<Layout.Stack
gap="xxs"
direction="column"
justifyContent="space-between"
style="margin-block-start: 20px; padding-inline: 20px; flex: 1;">
<Layout.Stack direction="column" gap="xxs">
<Layout.Stack
inline
direction="row"
alignItems="center"
justifyContent="space-between">
<Typography.Title size="s">{title}</Typography.Title>
<Icon size="m" icon={IconArrowRight} color="--fgcolor-neutral-tertiary" />
</Layout.Stack>
<Typography.Text variant="l-400">{subtitle}</Typography.Text>
</Layout.Stack>
<Layout.Stack
inline
gap="xxs"
direction="row"
alignContent="center"
style="margin-block-end: 20px;">
{#if footer}
<Typography.Text>Powered by</Typography.Text>
<img
height="20px"
width="auto"
src={mongoDbImage}
alt="mongo-db artwork"
style:padding-block-end="2px" />
{/if}
</Layout.Stack>
</Layout.Stack>
</Layout.Stack>
</Card>
{/snippet}
<style lang="scss">
@media (max-width: 768px) {
.database-image {
object-fit: cover;
background: white; /* because images have rounded borders atm */
object-position: center 20%;
border-radius: var(--border-radius-s) var(--border-radius-s) 0 0;
}
}
</style>
@@ -1,36 +1,67 @@
<script lang="ts">
import { base } from '$app/paths';
import { page } from '$app/state';
import { CardContainer, GridItem1, Id } from '$lib/components';
import { canWriteDatabases } from '$lib/stores/roles';
import type { PageData } from './$types';
export let data: PageData;
export let showCreate = false;
const project = page.params.project;
import type { Models } from '@appwrite.io/console';
import { resolveRoute } from '$lib/stores/navigation';
import { canWriteDatabases } from '$lib/stores/roles';
import { Badge, Icon, Layout } from '@appwrite.io/pink-svelte';
import { CardContainer, GridItem1, Id } from '$lib/components';
import { IconExclamation } from '@appwrite.io/pink-icons-svelte';
import { getDatabaseTypeTitle } from '$routes/(console)/project-[region]-[project]/databases/store';
let {
data,
onCreateDatabaseClick
}: {
data: PageData;
onCreateDatabaseClick: () => Promise<void> | void;
} = $props();
function getDatabaseRoute(database: Models.Database) {
return resolveRoute('/(console)/project-[region]-[project]/databases/database-[database]', {
...page.params,
database: database.$id
});
}
</script>
<CardContainer
disableEmpty={!$canWriteDatabases}
total={data.databases.total}
on:click={() => (showCreate = true)}
disableEmpty={!$canWriteDatabases}
on:click={onCreateDatabaseClick}
event="database"
service="databases">
{#each data.databases.databases as database}
<GridItem1
href={`${base}/project-${page.params.region}-${project}/databases/database-${database.$id}`}>
<svelte:fragment slot="title">{database.name}</svelte:fragment>
<GridItem1 href={getDatabaseRoute(database)}>
<svelte:fragment slot="title">
<Layout.Stack inline direction="row" gap="s" alignItems="center">
{database.name}
<Badge
size="xs"
type="success"
variant="secondary"
content={getDatabaseTypeTitle(database)} />
</Layout.Stack>
</svelte:fragment>
<svelte:fragment slot="subtitle">
{#if data.lastBackups && data.lastBackups[database.$id]}
Last backup: {data.lastBackups[database.$id]}
{:else if !data.policies || !data.policies[database.$id]}
<span class="icon-exclamation"></span> No backup policies
<Layout.Stack inline direction="row" gap="s" alignItems="center">
<Icon icon={IconExclamation} size="s" color="--bgcolor-warning" />
No backup policies
</Layout.Stack>
{:else}
Last backup: No backups yet
{/if}
</svelte:fragment>
<Id value={database.$id}>{database.$id}</Id>
</GridItem1>
{/each}
<svelte:fragment slot="empty">
<p>Create a database</p>
</svelte:fragment>
@@ -1,20 +1,37 @@
import type { Column } from '$lib/helpers/types';
import { isCloud } from '$lib/system';
import { writable } from 'svelte/store';
import type { Column } from '$lib/helpers/types';
import type { Models } from '@appwrite.io/console';
import type { DatabaseType } from '$database/(entity)';
export const columns = writable<Column[]>(
isCloud
? [
{ id: '$id', title: 'Database ID', type: 'string', width: 200 },
{ id: 'name', title: 'Name', type: 'string', width: { min: 120 } },
{ id: 'backup', title: 'Backups', type: 'string', width: { min: 120 } },
{ id: '$createdAt', title: 'Created', type: 'datetime', width: { min: 120 } },
{ id: '$updatedAt', title: 'Updated', type: 'datetime', width: { min: 120 } }
{ id: 'type', title: 'Type', type: 'string', width: { min: 180 } },
{ id: 'name', title: 'Name', type: 'string', width: { min: 180 } },
{ id: 'backup', title: 'Backups', type: 'string', width: { min: 180 } },
{ id: '$createdAt', title: 'Created', type: 'datetime', width: { min: 180 } },
{ id: '$updatedAt', title: 'Updated', type: 'datetime', width: { min: 180 } }
]
: [
{ id: '$id', title: 'Database ID', type: 'string', width: 200 },
{ id: 'name', title: 'Name', type: 'string', width: { min: 120 } },
{ id: '$createdAt', title: 'Created', type: 'datetime', width: { min: 120 } },
{ id: '$updatedAt', title: 'Updated', type: 'datetime', width: { min: 120 } }
{ id: 'type', title: 'Type', type: 'string', width: { min: 180 } },
{ id: 'name', title: 'Name', type: 'string', width: { min: 180 } },
{ id: '$createdAt', title: 'Created', type: 'datetime', width: { min: 180 } },
{ id: '$updatedAt', title: 'Updated', type: 'datetime', width: { min: 180 } }
]
);
export function getDatabaseTypeTitle(database: Models.Database) {
switch (database.type as DatabaseType) {
default:
case 'legacy':
case 'tablesdb':
return 'TablesDB';
case 'documentsdb':
return 'DocumentsDB';
case 'vectordb':
return 'VectorDB';
}
}
@@ -1,6 +1,6 @@
<script lang="ts">
import { page } from '$app/state';
import { columns } from './store';
import { columns, getDatabaseTypeTitle } from './store';
import { Id } from '$lib/components';
import type { PageData } from './$types';
import type { Models } from '@appwrite.io/console';
@@ -62,6 +62,8 @@
{/key}
{:else if column.id === 'name'}
{database.name}
{:else if column.id === 'type'}
{getDatabaseTypeTitle(database)}
{:else if column.id === 'backup'}
{@const policies = data.policies?.[database.$id] ?? null}
{@const lastBackup = data.lastBackups?.[database.$id] ?? null}