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}
+
+
+
+
+
+
+
+
+
+
+ {
+ addToConceptText = undefined;
+ }}
+ />
+
+
+
diff --git a/web/blueprint/src/lib/components/datasetView/RowItem.svelte b/web/blueprint/src/lib/components/datasetView/RowItem.svelte
index d7253dbf..45176506 100644
--- a/web/blueprint/src/lib/components/datasetView/RowItem.svelte
+++ b/web/blueprint/src/lib/components/datasetView/RowItem.svelte
@@ -156,7 +156,7 @@
return;
}
- if (key.code === 'Delete' || key.code === 'Backspace') {
+ if (key.ctrlKey && (key.code === 'Delete' || key.code === 'Backspace')) {
openDeleteModal = true;
} else {
// Find the key code in the label keyboard shortcuts.