diff --git a/packages/backend/src/managers/modelsManager.spec.ts b/packages/backend/src/managers/modelsManager.spec.ts index fbf0ea0a6..94f6d5033 100644 --- a/packages/backend/src/managers/modelsManager.spec.ts +++ b/packages/backend/src/managers/modelsManager.spec.ts @@ -19,6 +19,12 @@ test('getLocalModels should return models in local directory', () => { } return true; }); + const statSyncSpy = vi.spyOn(fs, 'statSync'); + const info = new fs.Stats(); + const now = new Date(); + info.size = 32000; + info.mtime = now; + statSyncSpy.mockReturnValue(info); const readdirSyncMock = vi.spyOn(fs, 'readdirSync') as unknown as MockInstance< [path: string], string[] | fs.Dirent[] @@ -53,10 +59,14 @@ test('getLocalModels should return models in local directory', () => { { id: 'model-id-1', file: 'model-id-1-model', + size: 32000, + creation: now, }, { id: 'model-id-2', file: 'model-id-2-model', + size: 32000, + creation: now, }, ]); }); diff --git a/packages/backend/src/managers/modelsManager.ts b/packages/backend/src/managers/modelsManager.ts index 32ac7d3bf..b46327bb9 100644 --- a/packages/backend/src/managers/modelsManager.ts +++ b/packages/backend/src/managers/modelsManager.ts @@ -19,9 +19,13 @@ export class ModelsManager { // we support models with one file only for now continue; } + const modelFile = modelEntries[0]; + const info = fs.statSync(path.resolve(d.path, d.name, modelFile)); result.push({ id: d.name, - file: modelEntries[0], + file: modelFile, + size: info.size, + creation: info.mtime, }); } return result; diff --git a/packages/backend/src/studio-api-impl.ts b/packages/backend/src/studio-api-impl.ts index 9347ab04f..122a6a361 100644 --- a/packages/backend/src/studio-api-impl.ts +++ b/packages/backend/src/studio-api-impl.ts @@ -30,6 +30,7 @@ import type { CatalogManager } from './managers/catalogManager'; import type { Catalog } from '@shared/src/models/ICatalog'; import type { PlaygroundState } from '@shared/src/models/IPlaygroundState'; import type { ModelsManager } from './managers/modelsManager'; +import type { LocalModelInfo } from '@shared/src/models/ILocalModelInfo'; export class StudioApiImpl implements StudioAPI { constructor( @@ -81,8 +82,15 @@ export class StudioApiImpl implements StudioAPI { async getLocalModels(): Promise { const local = this.modelsManager.getLocalModels(); + const localMap = new Map(); + for (const l of local) { + localMap.set(l.id, l); + } const localIds = local.map(l => l.id); - return this.catalogManager.getModels().filter(m => localIds.includes(m.id)); + return this.catalogManager + .getModels() + .filter(m => localIds.includes(m.id)) + .map(m => ({ ...m, file: localMap.get(m.id) })); } async startPlayground(modelId: string): Promise { diff --git a/packages/frontend/package.json b/packages/frontend/package.json index e3b105746..2ca9ed9bc 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -27,8 +27,12 @@ "@testing-library/svelte": "^4.0.5", "@testing-library/user-event": "^14.5.1", "@tsconfig/svelte": "^5.0.2", + "@types/humanize-duration": "^3.27.4", "@typescript-eslint/eslint-plugin": "6.15.0", + "filesize": "^10.1.0", + "humanize-duration": "^3.31.0", "jsdom": "^23.2.0", + "moment": "^2.30.1", "postcss": "^8.4.33", "postcss-load-config": "^5.0.2", "svelte": "4.2.8", diff --git a/packages/frontend/src/lib/progress/TasksProgress.svelte b/packages/frontend/src/lib/progress/TasksProgress.svelte index 4fb6cc636..c4aa2b2db 100644 --- a/packages/frontend/src/lib/progress/TasksProgress.svelte +++ b/packages/frontend/src/lib/progress/TasksProgress.svelte @@ -1,5 +1,5 @@ diff --git a/packages/frontend/src/lib/table/model/ModelColumnCreation.spec.ts b/packages/frontend/src/lib/table/model/ModelColumnCreation.spec.ts new file mode 100644 index 000000000..3bd96ddb3 --- /dev/null +++ b/packages/frontend/src/lib/table/model/ModelColumnCreation.spec.ts @@ -0,0 +1,51 @@ +/********************************************************************** + * Copyright (C) 2024 Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ***********************************************************************/ + +import '@testing-library/jest-dom/vitest'; +import { test, expect } from 'vitest'; +import { render, screen } from '@testing-library/svelte'; +import type { ModelInfo } from '@shared/src/models/IModelInfo'; +import ModelColumnCreation from './ModelColumnCreation.svelte'; + +test('Expect simple column styling', async () => { + const d = new Date(); + d.setDate(d.getDate() - 2); + + const object: ModelInfo = { + id: 'my-model', + description: '', + hw: '', + license: '', + name: '', + popularity: 3, + registry: '', + url: '', + file: { + id: 'my-model', + file: 'file', + creation: d, + size: 1000, + }, + }; + render(ModelColumnCreation, { object }); + + const text = screen.getByText('2 days'); + expect(text).toBeInTheDocument(); + expect(text).toHaveClass('text-sm'); + expect(text).toHaveClass('text-gray-700'); +}); diff --git a/packages/frontend/src/lib/table/model/ModelColumnCreation.svelte b/packages/frontend/src/lib/table/model/ModelColumnCreation.svelte new file mode 100644 index 000000000..12ffbc59a --- /dev/null +++ b/packages/frontend/src/lib/table/model/ModelColumnCreation.svelte @@ -0,0 +1,11 @@ + + +
+ {#if (object.file?.creation)} + {humanizeAge(object.file.creation.getTime()/1000)} + {/if} +
diff --git a/packages/frontend/src/lib/table/model/ModelColumnHW.svelte b/packages/frontend/src/lib/table/model/ModelColumnHW.svelte index a9d1a35ae..56033b778 100644 --- a/packages/frontend/src/lib/table/model/ModelColumnHW.svelte +++ b/packages/frontend/src/lib/table/model/ModelColumnHW.svelte @@ -1,5 +1,5 @@ diff --git a/packages/frontend/src/lib/table/model/ModelColumnLicense.svelte b/packages/frontend/src/lib/table/model/ModelColumnLicense.svelte index ff8e02093..f326aa3b2 100644 --- a/packages/frontend/src/lib/table/model/ModelColumnLicense.svelte +++ b/packages/frontend/src/lib/table/model/ModelColumnLicense.svelte @@ -1,5 +1,5 @@ diff --git a/packages/frontend/src/lib/table/model/ModelColumnName.svelte b/packages/frontend/src/lib/table/model/ModelColumnName.svelte index 0822bb7e2..1fbd6c011 100644 --- a/packages/frontend/src/lib/table/model/ModelColumnName.svelte +++ b/packages/frontend/src/lib/table/model/ModelColumnName.svelte @@ -1,5 +1,5 @@ diff --git a/packages/frontend/src/lib/table/model/ModelColumnRegistry.svelte b/packages/frontend/src/lib/table/model/ModelColumnRegistry.svelte index fb48caf85..0786bd415 100644 --- a/packages/frontend/src/lib/table/model/ModelColumnRegistry.svelte +++ b/packages/frontend/src/lib/table/model/ModelColumnRegistry.svelte @@ -1,5 +1,5 @@ diff --git a/packages/frontend/src/lib/table/model/ModelColumnSize.spec.ts b/packages/frontend/src/lib/table/model/ModelColumnSize.spec.ts new file mode 100644 index 000000000..ef383aaff --- /dev/null +++ b/packages/frontend/src/lib/table/model/ModelColumnSize.spec.ts @@ -0,0 +1,48 @@ +/********************************************************************** + * Copyright (C) 2024 Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ***********************************************************************/ + +import '@testing-library/jest-dom/vitest'; +import { test, expect } from 'vitest'; +import { render, screen } from '@testing-library/svelte'; +import type { ModelInfo } from '@shared/src/models/IModelInfo'; +import ModelColumnSize from './ModelColumnSize.svelte'; + +test('Expect simple column styling', async () => { + const object: ModelInfo = { + id: 'my-model', + description: '', + hw: '', + license: '', + name: '', + popularity: 3, + registry: '', + url: '', + file: { + id: 'my-model', + file: 'file', + creation: new Date(), + size: 1000, + }, + }; + render(ModelColumnSize, { object }); + + const text = screen.getByText('1 kB'); + expect(text).toBeInTheDocument(); + expect(text).toHaveClass('text-sm'); + expect(text).toHaveClass('text-gray-700'); +}); diff --git a/packages/frontend/src/lib/table/model/ModelColumnSize.svelte b/packages/frontend/src/lib/table/model/ModelColumnSize.svelte new file mode 100644 index 000000000..1453ae595 --- /dev/null +++ b/packages/frontend/src/lib/table/model/ModelColumnSize.svelte @@ -0,0 +1,11 @@ + + +
+ {#if (object.file?.size)} + {filesize(object.file.size)} + {/if} +
diff --git a/packages/frontend/src/pages/ModelPlayground.svelte b/packages/frontend/src/pages/ModelPlayground.svelte index 6331e74aa..7394256b9 100644 --- a/packages/frontend/src/pages/ModelPlayground.svelte +++ b/packages/frontend/src/pages/ModelPlayground.svelte @@ -1,11 +1,11 @@