| | <script lang="ts"> |
| | import { toast } from 'svelte-sonner'; |
| | import dayjs from 'dayjs'; |
| | import { onMount, getContext } from 'svelte'; |
| | |
| | import { getDocs } from '$lib/apis/documents'; |
| | import Modal from '../common/Modal.svelte'; |
| | import { documents } from '$lib/stores'; |
| | import { SUPPORTED_FILE_EXTENSIONS, SUPPORTED_FILE_TYPE } from '$lib/constants'; |
| | |
| | import Tags from '../common/Tags.svelte'; |
| | |
| | const i18n = getContext('i18n'); |
| | |
| | export let show = false; |
| | export let uploadDoc: Function; |
| | let uploadDocInputElement: HTMLInputElement; |
| | let inputFiles; |
| | let tags = []; |
| | |
| | let doc = { |
| | name: '', |
| | title: '', |
| | content: null |
| | }; |
| | |
| | const submitHandler = async () => { |
| | if (inputFiles && inputFiles.length > 0) { |
| | for (const file of inputFiles) { |
| | console.log(file, file.name.split('.').at(-1)); |
| | if ( |
| | SUPPORTED_FILE_TYPE.includes(file['type']) || |
| | SUPPORTED_FILE_EXTENSIONS.includes(file.name.split('.').at(-1)) |
| | ) { |
| | uploadDoc(file, tags); |
| | } else { |
| | toast.error( |
| | `Unknown File Type '${file['type']}', but accepting and treating as plain text` |
| | ); |
| | uploadDoc(file, tags); |
| | } |
| | } |
| | |
| | inputFiles = null; |
| | uploadDocInputElement.value = ''; |
| | } else { |
| | toast.error($i18n.t(`File not found.`)); |
| | } |
| | |
| | show = false; |
| | documents.set(await getDocs(localStorage.token)); |
| | }; |
| | |
| | const addTagHandler = async (tagName) => { |
| | if (!tags.find((tag) => tag.name === tagName) && tagName !== '') { |
| | tags = [...tags, { name: tagName }]; |
| | } else { |
| | console.log('tag already exists'); |
| | } |
| | }; |
| | |
| | const deleteTagHandler = async (tagName) => { |
| | tags = tags.filter((tag) => tag.name !== tagName); |
| | }; |
| | |
| | onMount(() => {}); |
| | </script> |
| |
|
| | <Modal size="sm" bind:show> |
| | <div> |
| | <div class=" flex justify-between dark:text-gray-300 px-5 pt-4"> |
| | <div class=" text-lg font-medium self-center">{$i18n.t('Add Docs')}</div> |
| | <button |
| | class="self-center" |
| | on:click={() => { |
| | show = false; |
| | }} |
| | > |
| | <svg |
| | xmlns="http://www.w3.org/2000/svg" |
| | viewBox="0 0 20 20" |
| | fill="currentColor" |
| | class="w-5 h-5" |
| | > |
| | <path |
| | d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z" |
| | /> |
| | </svg> |
| | </button> |
| | </div> |
| | <div class="flex flex-col md:flex-row w-full px-5 py-4 md:space-x-4 dark:text-gray-200"> |
| | <div class=" flex flex-col w-full sm:flex-row sm:justify-center sm:space-x-6"> |
| | <form |
| | class="flex flex-col w-full" |
| | on:submit|preventDefault={() => { |
| | submitHandler(); |
| | }} |
| | > |
| | <div class="mb-3 w-full"> |
| | <input |
| | id="upload-doc-input" |
| | bind:this={uploadDocInputElement} |
| | hidden |
| | bind:files={inputFiles} |
| | type="file" |
| | multiple |
| | /> |
| |
|
| | <button |
| | class="w-full text-sm font-medium py-3 bg-gray-100 hover:bg-gray-200 dark:bg-gray-850 dark:hover:bg-gray-800 text-center rounded-xl" |
| | type="button" |
| | on:click={() => { |
| | uploadDocInputElement.click(); |
| | }} |
| | > |
| | {#if inputFiles} |
| | {inputFiles.length > 0 ? `${inputFiles.length}` : ''} document(s) selected. |
| | {:else} |
| | {$i18n.t('Click here to select documents.')} |
| | {/if} |
| | </button> |
| | </div> |
| |
|
| | <div class=" flex flex-col space-y-1.5"> |
| | <div class="flex flex-col w-full"> |
| | <div class=" mb-1.5 text-xs text-gray-500">{$i18n.t('Tags')}</div> |
| |
|
| | <Tags {tags} addTag={addTagHandler} deleteTag={deleteTagHandler} /> |
| | </div> |
| | </div> |
| |
|
| | <div class="flex justify-end pt-5 text-sm font-medium"> |
| | <button |
| | class=" px-4 py-2 bg-emerald-700 hover:bg-emerald-800 text-gray-100 transition rounded-lg" |
| | type="submit" |
| | > |
| | {$i18n.t('Save')} |
| | </button> |
| | </div> |
| | </form> |
| | </div> |
| | </div> |
| | </div> |
| | </Modal> |
| |
|
| | <style> |
| | input::-webkit-outer-spin-button, |
| | input::-webkit-inner-spin-button { |
| | |
| | -webkit-appearance: none; |
| | margin: 0; |
| | } |
| | |
| | .tabs::-webkit-scrollbar { |
| | display: none; |
| | } |
| | |
| | .tabs { |
| | -ms-overflow-style: none; |
| | scrollbar-width: none; |
| | } |
| | |
| | input[type='number'] { |
| | -moz-appearance: textfield; |
| | } |
| | </style> |
| |
|