Skip to content

Commit

Permalink
feat: edit a local model
Browse files Browse the repository at this point in the history
  • Loading branch information
mikbry authored Feb 16, 2024
2 parents 40a07a1 + c1733ca commit 851447a
Show file tree
Hide file tree
Showing 15 changed files with 312 additions and 122 deletions.
5 changes: 4 additions & 1 deletion webapp/components/common/EditableItem/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ export default function EditableItem({
const [changedValue, setChangedValue] = useState<string | undefined>(undefined);

const onDebouncedChange = (value: string) => {
onChange?.(value, id);
if (value !== title) {
onChange?.(value, id);
}
// setChangedValue(undefined);
};

useDebounceFunc<string>(onDebouncedChange, changedValue, 500);
Expand Down
44 changes: 13 additions & 31 deletions webapp/components/common/Form/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,50 +12,32 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import { useState } from 'react';
import { ParametersDefinition } from '@/types';
import useTranslation from '@/hooks/useTranslation';
import useDebounceFunc from '@/hooks/useDebounceFunc';
import logger from '@/utils/logger';
import Parameter, { ParameterValue, ParametersRecord } from '../Parameter';
import useParameters, { ParametersCallback } from '@/hooks/useParameters';
import Parameter, { ParameterValue } from '../Parameter';

export type FormProps<T> = {
id: string | undefined;
parameters: Record<string, T> | undefined;
parametersDefinition: ParametersDefinition;
debounceDelay?: number;
onParametersChanged: (params: ParametersRecord) => ParametersRecord | undefined;
onParametersChange: ParametersCallback;
};

export default function Form<T>({
id,
parameters,
parametersDefinition,
onParametersChanged,
debounceDelay = 600,
onParametersChange,
debounceDelay,
}: FormProps<T>) {
const [updatedParameters, setUpdatedParameters] = useState<ParametersRecord | undefined>(
undefined,
);
const { t } = useTranslation();

const handleParameterChange = (name: string, value?: ParameterValue) => {
logger.info('handleParameterChange', name, value);
const newParams = updatedParameters || {};
if (newParams[name] !== value) {
setUpdatedParameters({ ...newParams, [name]: value });
}
};

const updateParameters = (newParameters: ParametersRecord) => {
logger.info('updateParameters', newParameters);
let changedParameters = onParametersChanged(newParameters);
if (changedParameters && Object.keys(changedParameters).length === 0) {
changedParameters = undefined;
}
// TODO handle errors
setUpdatedParameters(changedParameters);
};

useDebounceFunc<ParametersRecord>(updateParameters, updatedParameters, debounceDelay);
const [updatedParameters, setUpdatedParameters] = useParameters(
id,
onParametersChange,
debounceDelay,
);

return (
<form>
Expand All @@ -72,7 +54,7 @@ export default function Form<T>({
}
description={t(parametersDefinition[key].description)}
inputCss="max-w-20 pl-2"
onChange={handleParameterChange}
onChange={setUpdatedParameters}
/>
))}
</form>
Expand Down
47 changes: 33 additions & 14 deletions webapp/components/models/Explorer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,21 @@ import { shortcutAsText } from '@/utils/shortcuts';
import useShortcuts, { ShortcutIds } from '@/hooks/useShortcuts';
import ContextMenuList from '../ui/ContextMenu/ContextMenuList';
import { Button } from '../ui/button';
import EditableItem from '../common/EditableItem';

export type ModelsExplorerProps = {
models: Model[];
selectedModelId?: string;
collection: Model[];
onModelRename: (id: string, name: string) => void;
};

function ModelsExplorer({
models,
selectedModelId,
collection,
}: {
models: Model[];
selectedModelId?: string;
collection: Model[];
}) {
onModelRename,
}: ModelsExplorerProps) {
const router = useRouter();
const { t } = useTranslation();
const { showModal } = useContext(ModalsContext);
Expand All @@ -51,6 +56,11 @@ function ModelsExplorer({
showModal(ModalIds.NewLocalModel);
};

const handleChangeModelName = (id: string, name: string) => {
logger.info(`change model name ${id} ${name}`);
onModelRename(id, name);
};

useShortcuts(ShortcutIds.INSTALL_MODEL, (event) => {
event.preventDefault();
logger.info('shortcut install Model');
Expand Down Expand Up @@ -118,13 +128,24 @@ function ModelsExplorer({
className="flex cursor-pointer flex-row items-center"
tabIndex={0}
>
<div>
<div className="flex cursor-pointer flex-row items-center">
<div className="relative flex-1 overflow-hidden text-ellipsis break-all">
{model.title || model.name}
{!model.editable && (
<div>
<div className="line-clamp-1 h-auto w-full flex-1 overflow-hidden text-ellipsis break-all px-3 py-1">
<span>{model.title || model.name}</span>
</div>
</div>
</div>
)}
{model.editable && (
<div>
<EditableItem
id={model.id}
title={model.title || model.name}
editable
className="line-clamp-1 h-auto w-full flex-1 overflow-hidden text-ellipsis break-all px-3 py-1"
onChange={handleChangeModelName}
/>
</div>
)}
</div>
</ContextMenuTrigger>
<ContextMenuList data={model.id} menu={menu} />
Expand Down Expand Up @@ -166,10 +187,8 @@ function ModelsExplorer({
tabIndex={0}
>
<div>
<div className="flex cursor-pointer flex-row items-center">
<div className="relative flex-1 overflow-hidden text-ellipsis break-all">
{model.title || model.name}
</div>
<div className="line-clamp-1 h-auto w-full flex-1 overflow-hidden text-ellipsis break-all px-3 py-1">
<span>{model.title || model.name}</span>
</div>
</div>
</div>
Expand Down
84 changes: 49 additions & 35 deletions webapp/components/models/Model.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { DownloadIcon } from '@radix-ui/react-icons';
import useTranslation from '@/hooks/useTranslation';
import { Model } from '@/types';
import { getEntityName, getResourceUrl } from '@/utils/data';
import useParameters, { ParametersCallback } from '@/hooks/useParameters';
import Parameter from '../common/Parameter';
import { Button } from '../ui/button';
import { Table, TableBody, TableRow, TableCell, TableHeader, TableHead } from '../ui/table';
Expand All @@ -42,20 +43,25 @@ import { Table, TableBody, TableRow, TableCell, TableHeader, TableHead } from '.
DropdownMenuTrigger,
} from '../ui/dropdown-menu'; */

export type ModelViewProps = {
model: Model;
isDownloading: boolean;
local: boolean;
downloadables: Model[];
onChange: (item?: Model) => void;
onParametersChange: ParametersCallback;
};

function ModelView({
model,
isDownloading,
local,
downloadables,
onChange,
}: {
model: Model;
isDownloading: boolean;
local: boolean;
downloadables: Model[];
onChange: (item?: Model) => void;
}) {
onParametersChange,
}: ModelViewProps) {
const { t } = useTranslation();
const [updatedParameters, setUpdatedParameters] = useParameters(model?.id, onParametersChange);

if (!model) {
return null;
Expand Down Expand Up @@ -116,9 +122,10 @@ function ModelView({
<Parameter
title=""
name="description"
value={t(model.description || '')}
disabled
value={updatedParameters?.description || t(model.description || '')}
disabled={!model.editable}
type="large-text"
onChange={setUpdatedParameters}
/>
{model.fileName && (
<Parameter
Expand All @@ -132,10 +139,11 @@ function ModelView({
{model.author && (
<Parameter
title={t('Author')}
name="version"
value={`${getEntityName(model.author)}`}
disabled
name="author"
value={updatedParameters?.author || `${getEntityName(model.author)}`}
disabled={!model.editable}
type="text"
onChange={setUpdatedParameters}
/>
)}
{getEntityName(model.creator).toLowerCase() !==
Expand All @@ -144,7 +152,7 @@ function ModelView({
title={t('Creator')}
name="version"
value={`${getEntityName(model.creator)}`}
disabled
disabled={!model.editable}
type="text"
/>
)}
Expand All @@ -157,31 +165,37 @@ function ModelView({
title={t('Publisher')}
name="version"
value={`${getEntityName(model.publisher)}`}
disabled
disabled={!model.editable}
type="text"
/>
)}
<Parameter
title={t('Version')}
name="version"
value={`${model.version}`}
disabled
type="text"
/>
<Parameter
title={t('License')}
name="license"
value={`${getEntityName(model.license)}`}
disabled
type="text"
/>
<Parameter
title={t('Repository')}
name="url"
value={`${getResourceUrl(model.repository)}`}
disabled
type="url"
/>
{model.version && (
<Parameter
title={t('Version')}
name="version"
value={`${model.version}`}
disabled={!model.editable}
type="text"
/>
)}
{model.license && (
<Parameter
title={t('License')}
name="license"
value={`${getEntityName(model.license)}`}
disabled={!model.editable}
type="text"
/>
)}
{model.repository && (
<Parameter
title={t('Repository')}
name="url"
value={`${getResourceUrl(model.repository)}`}
disabled={!model.editable}
type="url"
/>
)}
</div>
{downloadables.length > 0 && (
<div className="flex w-full flex-col text-sm">
Expand Down
1 change: 1 addition & 0 deletions webapp/components/models/NewLocalModel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ function NewLocalModel({
toast.error(`File not found ${file}`);
return;
}
model.editable = true;
const id = await installModel(model, undefined, filepath, download);
await updateBackendStore();
logger.info('onLocalInstall', id, model, filepath, download);
Expand Down
Loading

0 comments on commit 851447a

Please sign in to comment.