fix: comment from QA regarding import model (#2213)
Signed-off-by: James <james@jan.ai> Co-authored-by: James <james@jan.ai>
This commit is contained in:
parent
52f84dce9f
commit
b70e7fb917
@ -93,12 +93,12 @@ export function handleAppIPCs() {
|
|||||||
const { canceled, filePaths } = await dialog.showOpenDialog(mainWindow, {
|
const { canceled, filePaths } = await dialog.showOpenDialog(mainWindow, {
|
||||||
title: 'Select model files',
|
title: 'Select model files',
|
||||||
buttonLabel: 'Select',
|
buttonLabel: 'Select',
|
||||||
properties: ['openFile', 'multiSelections'],
|
properties: ['openFile', 'openDirectory', 'multiSelections'],
|
||||||
})
|
})
|
||||||
if (canceled) {
|
if (canceled) {
|
||||||
return
|
return
|
||||||
} else {
|
|
||||||
return filePaths
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return filePaths
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,29 +0,0 @@
|
|||||||
type Props = {
|
|
||||||
title: string
|
|
||||||
description?: string
|
|
||||||
disabled?: boolean
|
|
||||||
onChange?: (text?: string) => void
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function ItemCardSidebar({
|
|
||||||
description,
|
|
||||||
title,
|
|
||||||
disabled,
|
|
||||||
onChange,
|
|
||||||
}: Props) {
|
|
||||||
return (
|
|
||||||
<div className="flex flex-col gap-2">
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<span>{title}</span>
|
|
||||||
</div>
|
|
||||||
<input
|
|
||||||
value={description}
|
|
||||||
disabled={disabled}
|
|
||||||
type="text"
|
|
||||||
className="block w-full rounded-md border-0 px-1 py-1.5 text-white shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
|
|
||||||
placeholder=""
|
|
||||||
onChange={(e) => onChange?.(e.target.value)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -39,7 +39,7 @@ export default function useDropModelBinaries() {
|
|||||||
}))
|
}))
|
||||||
if (unsupportedFiles.length > 0) {
|
if (unsupportedFiles.length > 0) {
|
||||||
snackbar({
|
snackbar({
|
||||||
description: `File has to be a .gguf file`,
|
description: `Only files with .gguf extension can be imported.`,
|
||||||
type: 'error',
|
type: 'error',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -116,6 +116,11 @@ const EditModelInfoModal: React.FC = () => {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onTagsChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
const tags = e.target.value.split(',')
|
||||||
|
setTags(tags)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
open={importModelStage === 'EDIT_MODEL_INFO'}
|
open={importModelStage === 'EDIT_MODEL_INFO'}
|
||||||
@ -128,22 +133,24 @@ const EditModelInfoModal: React.FC = () => {
|
|||||||
|
|
||||||
<div className="flex flex-row space-x-4 rounded-xl border p-4">
|
<div className="flex flex-row space-x-4 rounded-xl border p-4">
|
||||||
<div className="flex h-10 w-10 items-center justify-center rounded-full bg-blue-400">
|
<div className="flex h-10 w-10 items-center justify-center rounded-full bg-blue-400">
|
||||||
<Paperclip />
|
<Paperclip color="#fff" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-1 flex-col">
|
||||||
<p>{editingModel.name}</p>
|
<p>{editingModel.name}</p>
|
||||||
<div className="flex flex-row">
|
<div className="flex flex-row">
|
||||||
<span className="mr-2 text-sm text-[#71717A]">
|
<span className="mr-2 text-sm text-[#71717A]">
|
||||||
{toGibibytes(editingModel.size)}
|
{toGibibytes(editingModel.size)}
|
||||||
</span>
|
</span>
|
||||||
|
<div className="flex flex-row space-x-1">
|
||||||
<span className="text-sm font-semibold text-[#71717A]">
|
<span className="text-sm font-semibold text-[#71717A]">
|
||||||
Format:{' '}
|
Format:
|
||||||
</span>
|
</span>
|
||||||
<span className="text-sm font-normal text-[#71717A]">
|
<span className="text-sm font-normal text-[#71717A]">
|
||||||
{editingModel.format.toUpperCase()}
|
{editingModel.format.toUpperCase()}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div className="mt-1 flex flex-row items-center space-x-2">
|
<div className="mt-1 flex flex-row items-center space-x-2">
|
||||||
<span className="line-clamp-1 text-xs font-normal text-[#71717A]">
|
<span className="line-clamp-1 text-xs font-normal text-[#71717A]">
|
||||||
{modelPath}
|
{modelPath}
|
||||||
@ -189,7 +196,7 @@ const EditModelInfoModal: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<label className="mb-1">Tags</label>
|
<label className="mb-1">Tags</label>
|
||||||
<Input />
|
<Input value={tags.join(',')} onChange={onTagsChange} />
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { useCallback } from 'react'
|
import { useCallback } from 'react'
|
||||||
import { useDropzone } from 'react-dropzone'
|
import { useDropzone } from 'react-dropzone'
|
||||||
|
|
||||||
import { ImportingModel, baseName, fs } from '@janhq/core'
|
import { ImportingModel, baseName, fs, joinPath } from '@janhq/core'
|
||||||
import { Modal, ModalContent, ModalHeader, ModalTitle } from '@janhq/uikit'
|
import { Modal, ModalContent, ModalHeader, ModalTitle } from '@janhq/uikit'
|
||||||
import { useAtomValue, useSetAtom } from 'jotai'
|
import { useAtomValue, useSetAtom } from 'jotai'
|
||||||
|
|
||||||
@ -34,14 +34,31 @@ const SelectingModelModal: React.FC = () => {
|
|||||||
const sanitizedFilePaths: FilePathWithSize[] = []
|
const sanitizedFilePaths: FilePathWithSize[] = []
|
||||||
for (const filePath of filePaths) {
|
for (const filePath of filePaths) {
|
||||||
const fileStats = await fs.fileStat(filePath, true)
|
const fileStats = await fs.fileStat(filePath, true)
|
||||||
if (!fileStats || fileStats.isDirectory) continue
|
if (!fileStats) continue
|
||||||
|
|
||||||
|
if (!fileStats.isDirectory) {
|
||||||
const fileName = await baseName(filePath)
|
const fileName = await baseName(filePath)
|
||||||
sanitizedFilePaths.push({
|
sanitizedFilePaths.push({
|
||||||
path: filePath,
|
path: filePath,
|
||||||
name: fileName,
|
name: fileName,
|
||||||
size: fileStats.size,
|
size: fileStats.size,
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
// allowing only one level of directory
|
||||||
|
const files = await fs.readdirSync(filePath)
|
||||||
|
|
||||||
|
for (const file of files) {
|
||||||
|
const fullPath = await joinPath([filePath, file])
|
||||||
|
const fileStats = await fs.fileStat(fullPath, true)
|
||||||
|
if (!fileStats || fileStats.isDirectory) continue
|
||||||
|
|
||||||
|
sanitizedFilePaths.push({
|
||||||
|
path: fullPath,
|
||||||
|
name: file,
|
||||||
|
size: fileStats.size,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsupportedFiles = sanitizedFilePaths.filter(
|
const unsupportedFiles = sanitizedFilePaths.filter(
|
||||||
@ -68,7 +85,7 @@ const SelectingModelModal: React.FC = () => {
|
|||||||
)
|
)
|
||||||
if (unsupportedFiles.length > 0) {
|
if (unsupportedFiles.length > 0) {
|
||||||
snackbar({
|
snackbar({
|
||||||
description: `File has to be a .gguf file`,
|
description: `Only files with .gguf extension can be imported.`,
|
||||||
type: 'error',
|
type: 'error',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user