From 00b27a3e1d5f87d48d3f1abcc2366aa9fc08d6c4 Mon Sep 17 00:00:00 2001
From: Philippe Martin <phmartin@redhat.com>
Date: Tue, 23 Jan 2024 14:27:14 +0100
Subject: [PATCH] frontend: display size and creation age of models

---
 packages/frontend/package.json                |  4 ++++
 .../src/lib/progress/TasksProgress.svelte     |  2 +-
 .../table/model/ModelColumnCreation.svelte    | 11 ++++++++++
 .../src/lib/table/model/ModelColumnHW.svelte  |  2 +-
 .../lib/table/model/ModelColumnLicense.svelte |  2 +-
 .../lib/table/model/ModelColumnName.svelte    |  2 +-
 .../table/model/ModelColumnPopularity.svelte  |  2 +-
 .../table/model/ModelColumnRegistry.svelte    |  2 +-
 .../lib/table/model/ModelColumnSize.svelte    | 11 ++++++++++
 .../frontend/src/pages/ModelPlayground.svelte |  6 +++---
 packages/frontend/src/pages/Models.svelte     | 14 ++++++++-----
 packages/frontend/src/utils/dimensions.ts     |  9 +++++++++
 yarn.lock                                     | 20 +++++++++++++++++++
 13 files changed, 73 insertions(+), 14 deletions(-)
 create mode 100644 packages/frontend/src/lib/table/model/ModelColumnCreation.svelte
 create mode 100644 packages/frontend/src/lib/table/model/ModelColumnSize.svelte
 create mode 100644 packages/frontend/src/utils/dimensions.ts

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 @@
 <script lang="ts">
-import type { Task } from '@shared/models/ITask';
+import type { Task } from '@shared/src/models/ITask';
 
 export let tasks: Task[] = [];
 </script>
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 @@
+<script lang="ts">
+  import type { ModelInfo } from "@shared/src/models/IModelInfo";
+  import { humanizeAge } from "/@/utils/dimensions";
+  export let object: ModelInfo;
+</script>
+
+<div class="text-sm text-gray-700">
+  {#if (object.file?.creation)}
+    {humanizeAge(object.file.creation.getTime()/1000)}
+  {/if}
+</div>
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 @@
 <script lang="ts">
-  import type { ModelInfo } from "@shared/models/IModelInfo";
+  import type { ModelInfo } from "@shared/src/models/IModelInfo";
   export let object: ModelInfo;
 </script>
 
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 @@
 <script lang="ts">
-  import type { ModelInfo } from "@shared/models/IModelInfo";
+  import type { ModelInfo } from "@shared/src/models/IModelInfo";
   export let object: ModelInfo;
 </script>
 
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 @@
 <script lang="ts">
-  import type { ModelInfo } from "@shared/models/IModelInfo";
+  import type { ModelInfo } from "@shared/src/models/IModelInfo";
   import { router } from "tinro";
   export let object: ModelInfo;
 
diff --git a/packages/frontend/src/lib/table/model/ModelColumnPopularity.svelte b/packages/frontend/src/lib/table/model/ModelColumnPopularity.svelte
index 16d127a55..f7ecfefa4 100644
--- a/packages/frontend/src/lib/table/model/ModelColumnPopularity.svelte
+++ b/packages/frontend/src/lib/table/model/ModelColumnPopularity.svelte
@@ -1,5 +1,5 @@
 <script lang="ts">
-  import type { ModelInfo } from "@shared/models/IModelInfo";
+  import type { ModelInfo } from "@shared/src/models/IModelInfo";
   export let object: ModelInfo;
 </script>
 
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 @@
 <script lang="ts">
-  import type { ModelInfo } from "@shared/models/IModelInfo";
+  import type { ModelInfo } from "@shared/src/models/IModelInfo";
   export let object: ModelInfo;
 </script>
 
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 @@
+<script lang="ts">
+  import type { ModelInfo } from "@shared/src/models/IModelInfo";
+  import { filesize } from 'filesize';
+  export let object: ModelInfo;
+</script>
+
+<div class="text-sm text-gray-700">
+  {#if (object.file?.size)}
+    {filesize(object.file.size)}
+  {/if}
+</div>
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 @@
 <script lang="ts">
-  import type { ModelInfo } from '@shared/models/IModelInfo';
-  import type { ModelResponseChoice } from '@shared/models/IModelResponse';
+  import type { ModelInfo } from '@shared/src/models/IModelInfo';
+  import type { ModelResponseChoice } from '@shared/src/models/IModelResponse';
   import Button from '../lib/button/Button.svelte';
   import { onMount } from 'svelte';
   import { studioClient } from '../utils/client';
   import { playgroundQueries } from '../stores/playground-queries';
-  import type { QueryState } from '@shared/models/IPlaygroundQueryState';
+  import type { QueryState } from '@shared/src/models/IPlaygroundQueryState';
   import { playgroundStates } from '/@/stores/playground-states';
   import type { PlaygroundState } from '@shared/src/models/IPlaygroundState';
   import Card from '/@/lib/Card.svelte';
diff --git a/packages/frontend/src/pages/Models.svelte b/packages/frontend/src/pages/Models.svelte
index af6eca362..4420ec43b 100644
--- a/packages/frontend/src/pages/Models.svelte
+++ b/packages/frontend/src/pages/Models.svelte
@@ -12,15 +12,19 @@ import ModelColumnHw from '../lib/table/model/ModelColumnHW.svelte';
 import type { Task } from '@shared/src/models/ITask';
 import TasksProgress from '/@/lib/progress/TasksProgress.svelte';
 import Card from '/@/lib/Card.svelte';
-  import { modelsPulling } from '../stores/recipe';
-  import { onMount } from 'svelte';
+import { modelsPulling } from '../stores/recipe';
+import { onMount } from 'svelte';
+import ModelColumnSize from '../lib/table/model/ModelColumnSize.svelte';
+  import ModelColumnCreation from '../lib/table/model/ModelColumnCreation.svelte';
 
 const columns: Column<ModelInfo>[] = [
-  new Column<ModelInfo>('Name', { width: '4fr', renderer: ModelColumnName }),
+  new Column<ModelInfo>('Name', { width: '3fr', renderer: ModelColumnName }),
+  new Column<ModelInfo>('Size', { width: '1fr', renderer: ModelColumnSize }),
+  new Column<ModelInfo>('Creation', { width: '1fr', renderer: ModelColumnCreation }),
   new Column<ModelInfo>('HW Compat', { width: '1fr', renderer: ModelColumnHw }),
-  new Column<ModelInfo>('Registry', { width: '1fr', renderer: ModelColumnRegistry }),
+  new Column<ModelInfo>('Registry', { width: '2fr', renderer: ModelColumnRegistry }),
   new Column<ModelInfo>('Popularity', { width: '1fr', renderer: ModelColumnPopularity }),
-  new Column<ModelInfo>('License', { width: '1fr', renderer: ModelColumnLicense }),
+  new Column<ModelInfo>('License', { width: '2fr', renderer: ModelColumnLicense }),
 ];
 const row = new Row<ModelInfo>({});
 
diff --git a/packages/frontend/src/utils/dimensions.ts b/packages/frontend/src/utils/dimensions.ts
new file mode 100644
index 000000000..feb63aeb3
--- /dev/null
+++ b/packages/frontend/src/utils/dimensions.ts
@@ -0,0 +1,9 @@
+import moment from 'moment';
+import humanizeDuration from 'humanize-duration';
+
+export function humanizeAge(created: number): string {
+  // get start time in ms (using unix timestamp for the created)
+  const age = moment().diff(moment.unix(created));
+  // make it human friendly
+  return humanizeDuration(age, { round: true, largest: 1 });
+}
diff --git a/yarn.lock b/yarn.lock
index ef695ab7a..cf72b528f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -570,6 +570,11 @@
   resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz"
   integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==
 
+"@types/humanize-duration@^3.27.4":
+  version "3.27.4"
+  resolved "https://registry.yarnpkg.com/@types/humanize-duration/-/humanize-duration-3.27.4.tgz#51d6d278213374735440bc3749de920935e9127e"
+  integrity sha512-yaf7kan2Sq0goxpbcwTQ+8E9RP6HutFBPv74T/IA/ojcHKhuKVlk2YFYyHhWZeLvZPzzLE3aatuQB4h0iqyyUA==
+
 "@types/istanbul-lib-coverage@^2.0.1":
   version "2.0.4"
   resolved "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz"
@@ -1975,6 +1980,11 @@ file-entry-cache@^6.0.1:
   dependencies:
     flat-cache "^3.0.4"
 
+filesize@^10.1.0:
+  version "10.1.0"
+  resolved "https://registry.yarnpkg.com/filesize/-/filesize-10.1.0.tgz#846f5cd8d16e073c5d6767651a8264f6149183cd"
+  integrity sha512-GTLKYyBSDz3nPhlLVPjPWZCnhkd9TrrRArNcy8Z+J2cqScB7h2McAzR6NBX6nYOoWafql0roY8hrocxnZBv9CQ==
+
 fill-range@^7.0.1:
   version "7.0.1"
   resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz"
@@ -2283,6 +2293,11 @@ human-signals@^5.0.0:
   resolved "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz"
   integrity sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==
 
+humanize-duration@^3.31.0:
+  version "3.31.0"
+  resolved "https://registry.yarnpkg.com/humanize-duration/-/humanize-duration-3.31.0.tgz#a0384d22555024cd17e6e9f8561540d37756bf4c"
+  integrity sha512-fRrehgBG26NNZysRlTq1S+HPtDpp3u+Jzdc/d5A4cEzOD86YLAkDaJyJg8krSdCi7CJ+s7ht3fwRj8Dl+Btd0w==
+
 iconv-lite@0.6.3:
   version "0.6.3"
   resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501"
@@ -2865,6 +2880,11 @@ mlly@^1.2.0, mlly@^1.4.2:
     pkg-types "^1.0.3"
     ufo "^1.3.0"
 
+moment@^2.30.1:
+  version "2.30.1"
+  resolved "https://registry.yarnpkg.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae"
+  integrity sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==
+
 ms@2.1.2, ms@^2.1.1:
   version "2.1.2"
   resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"