diff --git a/web/blueprint/src/lib/components/common/DropdownPill.svelte b/web/blueprint/src/lib/components/common/DropdownPill.svelte index 78a7ca42..4e967365 100644 --- a/web/blueprint/src/lib/components/common/DropdownPill.svelte +++ b/web/blueprint/src/lib/components/common/DropdownPill.svelte @@ -62,7 +62,6 @@ diff --git a/web/blueprint/src/lib/components/concepts/ConceptView.svelte b/web/blueprint/src/lib/components/concepts/ConceptView.svelte index 6d5024ee..4fd7c5b3 100644 --- a/web/blueprint/src/lib/components/concepts/ConceptView.svelte +++ b/web/blueprint/src/lib/components/concepts/ConceptView.svelte @@ -142,23 +142,6 @@ {/if} - - {#if $embeddings.data} - -
Metrics
-
- {#each $embeddings.data as embedding} - {@const model = $conceptModels.data?.find(m => m.embedding_name == embedding.name)} - - {/each} -
-
- {/if}
Collect labels
@@ -176,6 +159,23 @@ {/if}
+ {#if $embeddings.data} + +
Metrics
+
+ {#each $embeddings.data as embedding} + {@const model = $conceptModels.data?.find(m => m.embedding_name == embedding.name)} + + {/each} +
+
+ {/if} +
{ if (!conceptName || !conceptNamespace) throw Error('Label could not be added, no active concept.'); - $conceptEdit.mutate([conceptNamespace, conceptName, {insert: [{text, label}]}]); + $conceptEdit.mutate([conceptNamespace, conceptName, {insert: [{text, label}]}], { + onSuccess: () => { + notificationStore.addNotification({ + kind: 'success', + title: `Added ${ + label ? 'positive' : 'negative' + } example to concept ${conceptNamespace}/${conceptName}`, + message: text + }); + } + }); }; let editorContainer: HTMLElement; @@ -331,42 +356,109 @@ } } - // Add the concept actions to the right-click menu. + // Add to concept. + let addToConceptText: string | undefined = undefined; + function addToConceptTextChanged(e: Event) { + addToConceptText = (e.target as HTMLInputElement).value; + } + let addToConceptSelectedConcept: string | undefined = undefined; + + let addToConceptPositive = true; + function selectConceptFromModal( + e: CustomEvent<{ + selectedId: DropdownItemId; + selectedItem: DropdownItem; + }> + ) { + addToConceptSelectedConcept = e.detail.selectedId; + } + function addToConceptFromModal() { + if (addToConceptSelectedConcept == null || addToConceptText == null) return; + const [conceptNamespace, conceptName] = addToConceptSelectedConcept.split('/'); + addConceptLabel(conceptNamespace, conceptName, addToConceptText, addToConceptPositive); + addToConceptText = undefined; + } + + const conceptQuery = queryConcepts(); + $: concepts = $conceptQuery.data; + let conceptsInMenu: Set; + let addToConceptItems: DropdownItem[] = []; + $: { - if (editor != null && searches != null) { - for (const search of searches) { + if (concepts != null) { + conceptsInMenu = new Set(); + for (const concept of concepts) { + if (concept.namespace == 'lilac') continue; + conceptsInMenu.add(conceptIdentifier(concept.namespace, concept.name)); + } + for (const search of searches || []) { if (search.type == 'concept') { - const idAdd = `add-positive-to-concept-${search.concept_name}`; - if (editor.getAction(idAdd) != null) continue; - editor.addAction({ - id: idAdd, - label: `👍 add as positive to concept "${search.concept_name}"`, - contextMenuGroupId: 'navigation_concepts', - precondition: conceptActionKeyId(search.concept_namespace, search.concept_name), - run: () => { - const selection = getEditorSelection(); - if (selection == null) return; - - const label = true; - addConceptLabel(search.concept_namespace, search.concept_name, selection, label); - } - }); - editor.addAction({ - id: 'add-negative-to-concept', - label: `👎 add as negative to concept "${search.concept_name}"`, - contextMenuGroupId: 'navigation_concepts', - precondition: conceptActionKeyId(search.concept_namespace, search.concept_name), - run: () => { - const selection = getEditorSelection(); - if (selection == null) return; - - const label = false; - addConceptLabel(search.concept_namespace, search.concept_name, selection, label); - } - }); + conceptsInMenu.add(conceptIdentifier(search.concept_namespace, search.concept_name)); } } } + addToConceptItems = Array.from(conceptsInMenu).map(concept => ({ + id: concept, + text: concept + })); + } + + // Add the concept actions to the right-click menu. + $: { + if (editor != null && concepts != null) { + for (const concept of conceptsInMenu) { + const [conceptNamespace, conceptName] = concept.split('/'); + const idPositive = `add-positive-to-concept-${conceptNamespace}/${conceptName}`; + if (editor.getAction(idPositive) != null) continue; + editor.addAction({ + id: idPositive, + label: `👍 add as positive to concept "${conceptName}"`, + contextMenuGroupId: 'navigation_concepts', + precondition: conceptActionKeyId(conceptNamespace, conceptName), + run: () => { + const selection = getEditorSelection(); + if (selection == null) return; + + const label = true; + addConceptLabel(conceptNamespace, conceptName, selection, label); + } + }); + const idNegative = `add-negative-to-concept-${conceptNamespace}/${conceptName}`; + if (editor.getAction(idNegative) != null) continue; + editor.addAction({ + id: idNegative, + label: `👎 add as negative to concept "${conceptName}"`, + contextMenuGroupId: 'navigation_concepts', + precondition: conceptActionKeyId(conceptNamespace, conceptName), + run: () => { + const selection = getEditorSelection(); + if (selection == null) return; + + const label = false; + addConceptLabel(conceptNamespace, conceptName, selection, label); + } + }); + } + } + } + $: { + if (editor != null) { + const idAddToConcept = 'add-to-concept'; + if (editor.getAction(idAddToConcept) == null) { + editor.addAction({ + id: 'add-to-concept', + label: `➕ Add to concept`, + contextMenuOrder: 1000, + contextMenuGroupId: 'navigation_concepts', + run: () => { + const selection = getEditorSelection(); + if (selection == null) return; + addToConceptSelectedConcept = addToConceptItems[0].id; + addToConceptText = selection; + } + }); + } + } } // Add the search actions to the right-click menu. @@ -669,6 +761,73 @@ {/if}
+
+ (addToConceptText = undefined)} + > + + +
+
+
Concept
+
+
+ + {@const groupByItem = addToConceptItems?.find(x => x === item)} + {#if groupByItem} +
+ {groupByItem.text} +
+ {/if} +
+
+
+ +
+
+
+
+
+
+
Text
+ +