@meaningfully/ui 0.0.7 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/App.svelte CHANGED
@@ -11,14 +11,14 @@
11
11
 
12
12
  interface Props {
13
13
  api: MeaningfullyAPI;
14
- basePath_prop: string;
14
+ basepath: string;
15
15
  }
16
- let { api, basePath_prop }: Props = $props();
16
+ let { api, basepath }: Props = $props();
17
17
 
18
18
  // basepath must not be blank;
19
19
  // unclear if it needs a trailing slash when using a subpath.
20
- let basepath = $state(basePath_prop || '/');
21
- console.log(`basepath App "${basepath}" (prop: "${basePath_prop}")`);
20
+ let basepath_app = $state(basepath || '/');
21
+ console.log(`basepath App "${basepath_app}" (prop: "${basepath}")`);
22
22
  let url = $state('');
23
23
  // Ensure $state returns Settings | null
24
24
  let settings = $state<Settings | null>(null);
@@ -47,7 +47,7 @@
47
47
 
48
48
  <!-- <img alt="logo" class="logo" src={electronLogo} /> -->
49
49
 
50
- <Router url={url} basepath={basepath}>
50
+ <Router url={url} basepath={basepath_app}>
51
51
  <Link to="/">
52
52
  <h1 class="text-2xl font-bold">
53
53
  Meaningfully
@@ -64,20 +64,20 @@
64
64
 
65
65
  <main class="container mx-auto px-4 py-8">
66
66
  <Route path="">
67
- <FrontPage validApiKeysSet={validApiKeysSet} api={api} />
67
+ <FrontPage validApiKeysSet={validApiKeysSet} api={api} basepath={basepath_app} />
68
68
  </Route>
69
69
  <Route path="configure-upload">
70
- <DatabaseConfig validApiKeysSet={validApiKeysSet} api={api} />
70
+ <DatabaseConfig validApiKeysSet={validApiKeysSet} api={api} basepath={basepath_app} />
71
71
  </Route>
72
72
  <Route path="search/:id" let:params>
73
- <SearchPage validApiKeysSet={validApiKeysSet} documentSetId={Number(params.id)} api={api} />
73
+ <SearchPage validApiKeysSet={validApiKeysSet} documentSetId={Number(params.id)} api={api} basepath={basepath_app} />
74
74
  </Route>
75
75
  <Route path="help">
76
76
  <HelpPage />
77
77
  </Route>
78
78
  <Route path="settings">
79
79
  {#if settings}
80
- <ApiKeyPage settings={settings} settingsUpdated={() => getSettings() } api={api} />
80
+ <ApiKeyPage settings={settings} settingsUpdated={() => getSettings() } api={api} basepath={basepath_app} />
81
81
  {/if}
82
82
  </Route>
83
83
  </main>
@@ -1,7 +1,7 @@
1
1
  import type { MeaningfullyAPI } from './types.js';
2
2
  interface Props {
3
3
  api: MeaningfullyAPI;
4
- basePath_prop: string;
4
+ basepath: string;
5
5
  }
6
6
  declare const App: import("svelte").Component<Props, {}, "">;
7
7
  type App = ReturnType<typeof App>;
@@ -6,9 +6,10 @@
6
6
  settings: Settings;
7
7
  settingsUpdated: () => void;
8
8
  api: MeaningfullyAPI;
9
+ basepath: string;
9
10
  }
10
11
 
11
- let { settings, settingsUpdated, api }: Props = $props();
12
+ let { settings, settingsUpdated, api, basepath }: Props = $props();
12
13
  let openAIKey: string = $state(settings.openAIKey);
13
14
  let oLlamaBaseURL: string = $state(settings.oLlamaBaseURL);
14
15
  let azureOpenAIKey: string = $state(settings.azureOpenAIKey);
@@ -34,7 +35,7 @@
34
35
  throw new Error('Failed to save settings');
35
36
  }
36
37
  settingsUpdated();
37
- navigate("/");
38
+ navigate(basepath.replace(/\/+$/g, "") + "/");
38
39
  } catch (error) {
39
40
  console.error(error);
40
41
  alert('Error saving settings');
@@ -3,6 +3,7 @@ interface Props {
3
3
  settings: Settings;
4
4
  settingsUpdated: () => void;
5
5
  api: MeaningfullyAPI;
6
+ basepath: string;
6
7
  }
7
8
  declare const ApiKeyPage: import("svelte").Component<Props, {}, "">;
8
9
  type ApiKeyPage = ReturnType<typeof ApiKeyPage>;
@@ -4,7 +4,8 @@
4
4
  import { fileDataStore } from '../stores/fileDataStore.js';
5
5
 
6
6
  let {
7
- validApiKeysSet
7
+ validApiKeysSet,
8
+ basepath
8
9
  } = $props();
9
10
 
10
11
  let error = $state('');
@@ -57,7 +58,8 @@
57
58
  fileContent
58
59
  });
59
60
  // Navigate to configuration page
60
- navigate('/configure-upload');
61
+ navigate(basepath.replace(/\/+$/g, "") + "/configure-upload");
62
+
61
63
  };
62
64
  reader.readAsDataURL(file);
63
65
  },
@@ -69,8 +71,10 @@
69
71
  </script>
70
72
 
71
73
  <div class="bg-white p-6 rounded-lg shadow space-y-6 text-black mb-10" data-testid="upload-a-spreadsheet">
72
- <h2 class="text-xl font-semibold">Upload A Spreadsheet</h2>
74
+ <h2 class="text-xl font-semibold mb-[2px]">Upload a Spreadsheet</h2>
73
75
 
76
+ <p class="text-gray-700 text-[10px]">CSVs up to 10,000 rows work great. Those with more than 10,000 rows may be slow or could fail. Modify the CSV beforehand to ensure the CSV has exactly one header row.</p>
77
+
74
78
  <label class="block">
75
79
  <span class="sr-only">Choose CSV file</span>
76
80
  <input
@@ -1,5 +1,6 @@
1
1
  declare const CsvUpload: import("svelte").Component<{
2
2
  validApiKeysSet: any;
3
+ basepath: any;
3
4
  }, {}, "">;
4
5
  type CsvUpload = ReturnType<typeof CsvUpload>;
5
6
  export default CsvUpload;
@@ -13,7 +13,8 @@
13
13
 
14
14
  let {
15
15
  validApiKeysSet,
16
- api
16
+ api,
17
+ basepath
17
18
  } = $props();
18
19
 
19
20
  let fileData: any = $state(null);
@@ -79,9 +80,9 @@
79
80
 
80
81
  onMount(() => {
81
82
  // Subscribe to the file data store
82
- const unsubscribe = fileDataStore.subscribe((data) => {
83
+ const unsubscribe = fileDataStore.subscribe((data: any) => {
83
84
  if (!data) {
84
- navigate('/'); // Redirect back to home if no file data
85
+ navigate(basepath.replace(/\/+$/g, "") + "/"); // Redirect back to home if no file data
85
86
  return;
86
87
  }
87
88
  fileData = data;
@@ -187,7 +188,8 @@
187
188
  });
188
189
 
189
190
  if (uploadResponse.success) {
190
- navigate("/search/" + uploadResponse.documentSetId);
191
+ navigate(basepath.replace(/\/+$/g, "") + "/search/" + uploadResponse.documentSetId);
192
+
191
193
  } else {
192
194
  error = uploadResponse.message || 'Upload failed'; // fastify responses don't throw
193
195
  }
@@ -237,7 +239,7 @@
237
239
  });
238
240
 
239
241
  const goBack = () => {
240
- navigate('/');
242
+ navigate(basepath.replace(/\/+$/g, "") + "/");
241
243
  };
242
244
  </script>
243
245
 
@@ -1,6 +1,7 @@
1
1
  declare const DatabaseConfig: import("svelte").Component<{
2
2
  validApiKeysSet: any;
3
3
  api: any;
4
+ basepath: any;
4
5
  }, {}, "">;
5
6
  type DatabaseConfig = ReturnType<typeof DatabaseConfig>;
6
7
  export default DatabaseConfig;
@@ -35,7 +35,7 @@
35
35
  totalDocuments = result.total;
36
36
  totalPages = Math.ceil(totalDocuments / pageSize);
37
37
  } catch (e) {
38
- error = e instanceof Error ? e.message : 'Failed to load document sets';
38
+ error = e instanceof Error ? e.message : 'Failed to load list of spreadsheets';
39
39
  } finally {
40
40
  loading = false;
41
41
  }
@@ -48,7 +48,7 @@
48
48
  await api.deleteDocumentSet(documentSetId);
49
49
  await loadDocumentSets(currentPage);
50
50
  } catch (e) {
51
- error = e instanceof Error ? e.message : 'Failed to delete document set';
51
+ error = e instanceof Error ? e.message : 'Failed to delete spreadsheet';
52
52
  }
53
53
  }
54
54
  }
@@ -87,7 +87,7 @@
87
87
  <div class="my-10 bg-white p-6 rounded-lg shadow space-y-6 text-black" data-testid="existing-spreadsheets">
88
88
  <h2 class="text-2xl font-bold">Existing Spreadsheets</h2>
89
89
  {#if documentSets.length === 0}
90
- <p class="text-gray-500">No spreadsheets found. Upload one to get started.</p>
90
+ <p class="text-gray-500">No spreadsheets found. Upload a CSV to get started.</p>
91
91
  {:else}
92
92
  <div class="overflow-x-auto">
93
93
  <table class="min-w-full table-auto">
@@ -96,7 +96,7 @@
96
96
  <th class="px-4 py-2 text-left">Name</th>
97
97
  <th class="px-4 py-2 text-left">Upload Date</th>
98
98
  <th class="px-4 py-2 text-left">Documents</th>
99
- <th class="px-4 py-2 text-left">Parameters</th>
99
+ <th class="px-4 py-2 text-left">Details and Settings</th>
100
100
  <th class="px-4 py-2 text-left"><span class="sr-only">Actions</span></th>
101
101
  </tr>
102
102
  </thead>
@@ -121,7 +121,7 @@
121
121
  <td class="px-4 py-2">
122
122
  {#if Object.keys(set.parameters).length > 0}
123
123
  <details>
124
- <summary class="cursor-pointer text-sm text-blue-600">View Parameters</summary>
124
+ <summary class="cursor-pointer text-sm text-blue-600">See Details</summary>
125
125
  <pre class="mt-2 p-2 bg-gray-50 rounded text-sm">{JSON.stringify(set.parameters, null, 2)}</pre>
126
126
  </details>
127
127
  {:else}
@@ -1,18 +1,22 @@
1
1
  <script lang="ts">
2
2
  import ExistingDatabases from './ExistingDatabases.svelte'
3
3
  import CsvUpload from './CsvUpload.svelte'
4
- import type { MeaningfullyAPI } from '../types';
4
+ import type { MeaningfullyAPI } from '../types';
5
+ import { Link } from 'svelte-routing';
5
6
 
6
7
  interface Props {
7
8
  validApiKeysSet: boolean;
8
9
  api: MeaningfullyAPI;
10
+ basepath: string;
9
11
  }
10
12
 
11
- let { validApiKeysSet, api }: Props = $props();
13
+ let { validApiKeysSet, api, basepath }: Props = $props();
12
14
  </script>
13
15
 
14
16
  <div class="container mx-auto px-4 space-y-8">
15
- <CsvUpload validApiKeysSet={validApiKeysSet} />
17
+ <CsvUpload validApiKeysSet={validApiKeysSet} basepath={basepath} />
16
18
  <ExistingDatabases api={api} />
19
+ <div class="max-w-2xl mx-auto text-left leading-tight space-y-2">
20
+ Meaningfully is a semantic search tool for text data in spreadsheets. Search by the meaning of a sentence instead of keywords. <Link to="help" class="nav-link underline text-blue-600 hover:text-blue-800 visited:text-purple-600">Learn more</Link>.
21
+ </div>
17
22
  </div>
18
-
@@ -2,6 +2,7 @@ import type { MeaningfullyAPI } from '../types';
2
2
  interface Props {
3
3
  validApiKeysSet: boolean;
4
4
  api: MeaningfullyAPI;
5
+ basepath: string;
5
6
  }
6
7
  declare const FrontPage: import("svelte").Component<Props, {}, "">;
7
8
  type FrontPage = ReturnType<typeof FrontPage>;
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import { navigate } from 'svelte-routing';
2
+ import { navigate, Link } from 'svelte-routing';
3
3
  import type { DocumentSet, MeaningfullyAPI } from '../types.js';
4
4
  import Results from './Results.svelte';
5
5
 
@@ -7,9 +7,10 @@
7
7
  validApiKeysSet: boolean;
8
8
  documentSetId: number;
9
9
  api: MeaningfullyAPI;
10
+ basepath: string;
10
11
  }
11
12
 
12
- let { validApiKeysSet, documentSetId, api }: Props = $props();
13
+ let { validApiKeysSet, documentSetId, api, basepath }: Props = $props();
13
14
 
14
15
  let documentSet: DocumentSet | null = $state(null);
15
16
  let documentSetLoading = $state(true);
@@ -36,7 +37,7 @@
36
37
  documentSetLoading = false;
37
38
  }).catch(error => {
38
39
  console.error('Error fetching document set:', error);
39
- navigate('/');
40
+ navigate(basepath.replace(/\/+$/g, "") + "/");
40
41
  });
41
42
 
42
43
  const placeholderQueries = [
@@ -105,15 +106,15 @@
105
106
 
106
107
  <div class="p-6 space-y-6">
107
108
  <div class="flex items-center space-x-4">
108
- <button
109
+ <Link
109
110
  class="text-blue-500 hover:text-blue-600 flex items-center space-x-1"
110
- onclick={() => navigate('/') }
111
+ to=""
111
112
  >
112
113
  <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
113
114
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7" />
114
115
  </svg>
115
- <span>Back to Document Sets</span>
116
- </button>
116
+ <span>Back to Home</span>
117
+ </Link>
117
118
  </div>
118
119
 
119
120
  {#if documentSetLoading}
@@ -131,19 +132,15 @@
131
132
  <div class="space-y-4 max-w-3xl">
132
133
  <!-- Search Input -->
133
134
  <div class="space-y-2">
134
- <label for="search" class="block text-sm font-medium text-gray-700">
135
+ <label for="search" class="block text-sm font-medium text-gray-300">
135
136
  Semantic Search
136
137
  </label>
137
- <p class="text-xs text-gray-500">
138
- Imagine the perfect document that you hope might exist in your spreadsheet. Type it here. Meaningfully will find the real documents that mean
139
- about the same thing -- even if they have no keywords in common.
140
- </p>
141
138
  <div class="flex space-x-4">
142
139
  <input
143
140
  id="search"
144
141
  type="text"
145
142
  bind:value={searchQuery}
146
- placeholder={placeholderQuery}
143
+ placeholder={"... " + placeholderQuery}
147
144
  data-testid="search-bar"
148
145
  class="flex-1 px-4 py-2 border border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 placeholder-gray-400"
149
146
  />
@@ -156,13 +153,17 @@
156
153
  {loading ? 'Searching...' : 'Search'}
157
154
  </button>
158
155
  </div>
156
+ <p class="text-xs text-gray-500">
157
+ Need a hint? Imagine the perfect document that you hope might exist in your spreadsheet. Type it here. Meaningfully will find the real documents that mean
158
+ about the same thing -- even if they have no keywords in common.
159
+ </p>
159
160
  </div>
160
161
 
161
162
  <!-- Metadata Filters -->
162
163
  {#if metadataColumns.length > 0}
163
164
  <div class="space-y-2">
164
- <p class="block text-sm font-medium text-gray-700">
165
- Search only records that match...
165
+ <p class="block text-sm font-medium text-gray-300">
166
+ Use filters to search a subset of rows in your spreadsheet.
166
167
  </p>
167
168
  <div class="space-y-4">
168
169
  {#each metadataFilters as filter, index}
@@ -224,6 +225,8 @@
224
225
  originalDocumentClick={handleOriginalDocumentClick}
225
226
  />
226
227
  </div>
228
+ {:else}
229
+ <div class="text-gray-500">You won't find any results unless you search</div>
227
230
  {/if}
228
231
  {/if}
229
232
  </div>
@@ -3,6 +3,7 @@ interface Props {
3
3
  validApiKeysSet: boolean;
4
4
  documentSetId: number;
5
5
  api: MeaningfullyAPI;
6
+ basepath: string;
6
7
  }
7
8
  declare const SearchPage: import("svelte").Component<Props, {}, "">;
8
9
  type SearchPage = ReturnType<typeof SearchPage>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meaningfully/ui",
3
- "version": "0.0.7",
3
+ "version": "0.0.9",
4
4
  "license": "MIT",
5
5
  "description": "Svelte components for meaningfully semantic search",
6
6
  "repo": "https://github.com/jeremybmerrill/meaningfully-ui",