version-0.1 #1

Merged
wamplerj merged 18 commits from version-0.1 into main 2026-07-01 13:30:08 -07:00
4 changed files with 69 additions and 30 deletions
Showing only changes of commit 5506151f19 - Show all commits

View File

@@ -319,6 +319,7 @@ interface Props {
modelValue: boolean;
feature: FeatureResponse | null;
featureState: FeatureStateResponse | null;
initialTab?: string;
}
const props = defineProps<Props>();
@@ -472,7 +473,7 @@ watch(
() => props.modelValue,
(open) => {
if (open) {
activeTab.value = 'value';
activeTab.value = props.initialTab ?? 'value';
valueErrorMessage.value = null;
settingsErrorMessage.value = null;
segmentsErrorMessage.value = null;

View File

@@ -1,14 +1,24 @@
<template>
<div data-testid="feature-value-editor">
<!-- Type selector -->
<v-btn-toggle
v-model="detectedMode"
density="compact"
data-testid="value-mode-toggle"
>
<v-btn value="text" size="small">Text</v-btn>
<v-btn value="json" size="small">JSON</v-btn>
</v-btn-toggle>
<div class="d-flex mb-3" data-testid="value-mode-toggle">
<v-btn
size="small"
:variant="detectedMode === 'text' ? 'flat' : 'outlined'"
color="primary"
rounded="0"
style="border-radius: 4px 0 0 4px"
@click="detectedMode = 'text'"
>Text</v-btn>
<v-btn
size="small"
:variant="detectedMode === 'json' ? 'flat' : 'outlined'"
color="primary"
rounded="0"
style="border-radius: 0 4px 4px 0; margin-left: -1px"
@click="detectedMode = 'json'"
>JSON</v-btn>
</div>
<!-- JSON mode -->
<v-textarea
@@ -83,11 +93,3 @@ const rules = {
};
</script>
<style scoped>
/* Materio forces square icon-toggle sizing; override for text-label toggles */
:deep(.v-btn-toggle .v-btn) {
block-size: auto !important;
inline-size: auto !important;
padding-inline: 16px !important;
}
</style>

View File

@@ -3,18 +3,26 @@
<!-- AND / OR toggle -->
<div class="d-flex align-center ga-2 mb-3">
<span class="text-body-2 font-weight-medium text-medium-emphasis">Match</span>
<v-btn-toggle
:model-value="rule.type"
density="compact"
mandatory
color="primary"
variant="outlined"
data-testid="rule-type-toggle"
@update:model-value="onTypeChange"
>
<v-btn value="All" size="small" data-testid="rule-type-and">ALL (AND)</v-btn>
<v-btn value="Any" size="small" data-testid="rule-type-or">ANY (OR)</v-btn>
</v-btn-toggle>
<div class="d-flex" data-testid="rule-type-toggle">
<v-btn
size="small"
:variant="rule.type === 'All' ? 'flat' : 'outlined'"
color="primary"
rounded="0"
style="border-radius: 4px 0 0 4px"
data-testid="rule-type-and"
@click="onTypeChange('All')"
>ALL (AND)</v-btn>
<v-btn
size="small"
:variant="rule.type === 'Any' ? 'flat' : 'outlined'"
color="primary"
rounded="0"
style="border-radius: 0 4px 4px 0; margin-left: -1px"
data-testid="rule-type-or"
@click="onTypeChange('Any')"
>ANY (OR)</v-btn>
</div>
<v-spacer />
<v-btn
v-if="removable"

View File

@@ -53,7 +53,26 @@
<!-- Name + description -->
<template #item.name="{ item }: { item: FeatureResponse }">
<div>
<span class="text-body-2 font-weight-medium">{{ item.name }}</span>
<div class="d-flex align-center ga-1">
<span class="text-subtitle-1 font-weight-bold">{{ item.name }}</span>
<v-tooltip
v-if="(featureSegmentsMap.get(item.id) ?? []).length > 0"
text="Has segment overrides"
location="top"
>
<template #activator="{ props: tooltipProps }">
<v-btn
v-bind="tooltipProps"
icon="ri-donut-chart-fill"
size="small"
variant="text"
color="secondary"
:data-testid="`segment-override-icon-${item.id}`"
@click.stop="openDetailOnSegments(item)"
/>
</template>
</v-tooltip>
</div>
<p v-if="item.description" class="text-caption text-medium-emphasis mb-0">
{{ item.description }}
</p>
@@ -158,6 +177,7 @@
v-model="showDetail"
:feature="selectedFeature"
:feature-state="selectedFeatureState"
:initial-tab="detailInitialTab"
@updated="onFeatureUpdated"
@deleted="onFeatureDeleted"
@state-updated="onStateUpdated"
@@ -236,6 +256,7 @@ function showError(message: string): void {
const showDialog = ref(false);
const showDetail = ref(false);
const selectedFeature = ref<FeatureResponse | null>(null);
const detailInitialTab = ref('value');
// Delete dialog state
const showDeleteDialog = ref(false);
@@ -333,6 +354,13 @@ function openCreateDialog(): void {
}
function onRowClick(_event: Event, { item }: { item: FeatureResponse }): void {
detailInitialTab.value = 'value';
selectedFeature.value = item;
showDetail.value = true;
}
function openDetailOnSegments(item: FeatureResponse): void {
detailInitialTab.value = 'segments';
selectedFeature.value = item;
showDetail.value = true;
}