Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions client/src/components/Tracks/TrackList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,9 @@ export default defineComponent({
font-weight: 600;
}
.compact-column-headers {
/* The header is padded 8px more than the rows; without this every label sits right of its column */
margin-left: -8px;

.col-header {
font-size: 10px;
color: #888;
Expand All @@ -600,12 +603,15 @@ export default defineComponent({
}
}
.col-spacer {
/* Matches color box: 10px + 6px margin */
min-width: 16px;
/* Matches track-lead-compact (checkbox or color box): 24px + 6px margin */
min-width: 30px;
}
.col-id {
/* Matches trackNumber-compact: 30px + 8px margin */
min-width: 38px;
/* Matches trackNumber-compact: 30px + 8px margin, centered like its values */
width: 30px;
min-width: 30px;
flex-shrink: 0;
margin-right: 8px;
}
.col-type {
/* Matches track-type-compact: 80px */
Expand Down Expand Up @@ -643,6 +649,13 @@ export default defineComponent({
text-align: left;
margin-right: 8px;
}
.col-length {
/* Matches track-length: a number needs less room than free text */
width: 64px;
min-width: 64px;
max-width: 64px;
}
.col-id,
.col-conf,
.col-length {
position: relative;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { defineComponent, h, ref } from 'vue';
import {
defineComponent, h, nextTick, ref,
} from 'vue';
import { shallowMount } from '@vue/test-utils';
import Track from '../../../track';
import BottomBarTrackItemView from './BottomBarTrackItemView.vue';
Expand All @@ -9,6 +11,7 @@ const providerState = vi.hoisted(() => ({
setTrackNotes: vi.fn(),
setTrackAttribute: vi.fn(),
setTrackFirstFeatureAttribute: vi.fn(),
updateCheckedId: vi.fn(),
}));

vi.mock('../../../provides', () => ({
Expand All @@ -17,6 +20,7 @@ vi.mock('../../../provides', () => ({
useTrackFilters: () => ({
allTypes: ref(['root', 'leaf']),
hierarchyIndex: ref(undefined),
updateCheckedId: providerState.updateCheckedId,
}),
useCameraStore: () => ({
assignTrackType: providerState.assignTrackType,
Expand All @@ -27,7 +31,7 @@ vi.mock('../../../provides', () => ({
}),
}));

function mountItem(displayPairIndex: number) {
function mountItem(displayPairIndex: number, extra: Record<string, unknown> = {}, attach = false) {
const track = new Track(1, {
begin: 0,
end: 0,
Expand Down Expand Up @@ -57,10 +61,14 @@ function mountItem(displayPairIndex: number) {
toggleKeyframe: vi.fn(),
toggleInterpolation: vi.fn(),
toggleAllInterpolation: vi.fn(),
...extra,
},
}),
});
const wrapper = shallowMount(Host, { stubs: { BottomBarTrackItemView: false } });
const wrapper = shallowMount(Host, {
stubs: { BottomBarTrackItemView: false },
...(attach ? { attachTo: document.body } : {}),
});
if (!child) {
throw new Error('BottomBarTrackItemView did not mount');
}
Expand Down Expand Up @@ -130,4 +138,34 @@ describe('BottomBarTrackItemView hierarchy display', () => {
expect(providerState.setTrackFirstFeatureAttribute)
.toHaveBeenCalledWith(1, 'occluded', 'yes');
});

it('shows a checkbox for the track, as the side list does, and a color box when solo', () => {
const { wrapper } = mountItem(0);
expect(wrapper.find('.type-color-box-compact').exists()).toBe(false);
wrapper.find('.track-checkbox-compact').trigger('change');
expect(providerState.updateCheckedId.mock.calls[0][0]).toBe(1);

const solo = mountItem(0, { solo: true });
expect(solo.wrapper.find('.track-checkbox-compact').exists()).toBe(false);
expect(solo.wrapper.find('.type-color-box-compact').exists()).toBe(true);
});

it('focuses an attribute field when editing starts, so leaving it closes it', async () => {
const { wrapper, vm } = mountItem(
0,
{ columnVisibility: { attributeColumns: ['track_length'] } },
true,
);
expect(wrapper.find('.compact-attribute-input').exists()).toBe(false);
vm.startEditAttribute('track_length', new MouseEvent('click'));
await nextTick();
await nextTick();
const input = wrapper.find('.compact-attribute-input');
expect(input.classes()).toContain('track-length');
expect(document.activeElement).toBe(input.element);

await input.trigger('blur');
expect(wrapper.find('.compact-attribute-input').exists()).toBe(false);
wrapper.destroy();
});
});
65 changes: 58 additions & 7 deletions client/src/components/Tracks/bottombar/BottomBarTrackItemView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import {
computed, defineComponent, nextTick, PropType, ref, watch,
} from 'vue';
import type { ComponentPublicInstance } from 'vue';
import { ColumnVisibilitySettings } from 'dive-common/store/settings';
import TooltipBtn from '../../TooltipButton.vue';
import {
Expand All @@ -26,6 +27,8 @@ export default defineComponent({
fps: { type: Number, default: null },
editing: { type: Boolean, required: true },
inputValue: { type: Boolean, required: true },
solo: { type: Boolean, default: false },
disabled: { type: Boolean, default: false },
merging: { type: Boolean, default: false },
toggleKeyframe: { type: Function as PropType<() => void>, required: true },
toggleInterpolation: { type: Function as PropType<() => void>, required: true },
Expand Down Expand Up @@ -53,6 +56,10 @@ export default defineComponent({
const attributeInputRef = ref<HTMLInputElement | null>(null);
const localAttributeDisplay = ref<Record<string, string>>({});

function setAttributeInputRef(el: Element | ComponentPublicInstance | null) {
attributeInputRef.value = el instanceof HTMLInputElement ? el : null;
}

watch(() => props.track.id, () => {
localNotesDisplay.value = '';
localAttributeDisplay.value = {};
Expand Down Expand Up @@ -209,6 +216,7 @@ export default defineComponent({
editAttributeValue.value = getAttributeValue(attrKey);
editingAttributeKey.value = attrKey;
nextTick(() => {
// Without focus the field would never blur, and so never close
attributeInputRef.value?.focus();
attributeInputRef.value?.select();
});
Expand Down Expand Up @@ -258,7 +266,7 @@ export default defineComponent({

return {
allTypes,
attributeInputRef,
setAttributeInputRef,
cancelEditAttribute,
cancelEditConfidence,
cancelEditNotes,
Expand Down Expand Up @@ -294,6 +302,7 @@ export default defineComponent({
startTimestamp,
topConfidence,
trackAttributeColumns,
trackFilters,
typeInputRef,
};
},
Expand Down Expand Up @@ -328,10 +337,27 @@ export default defineComponent({
:style="itemStyle"
@click="handleClicked"
>
<div
class="type-color-box-compact"
:style="{ backgroundColor: color }"
/>
<div class="track-lead-compact">
<div
v-if="solo"
class="type-color-box-compact"
:style="{ backgroundColor: color }"
/>
<div
v-else
@click.stop
>
<v-checkbox
class="track-checkbox-compact my-0 pt-0"
dense
hide-details
:disabled="disabled"
:input-value="inputValue"
:color="color"
@change="trackFilters.updateCheckedId(track.trackId, $event)"
/>
</div>
</div>
<div class="trackNumber-compact">
{{ track.trackId }}
</div>
Expand Down Expand Up @@ -425,7 +451,7 @@ export default defineComponent({
<input
v-if="editingAttributeKey === attrKey"
:key="attrKey + '-input'"
ref="attributeInputRef"
:ref="setAttributeInputRef"
:value="editAttributeValue"
type="text"
class="compact-attribute-input"
Expand Down Expand Up @@ -516,20 +542,35 @@ export default defineComponent({
background-color: #2a2a2a;
}

.track-lead-compact {
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
width: 24px;
margin-right: 6px;
}

.type-color-box-compact {
min-width: 10px;
max-width: 10px;
min-height: 10px;
max-height: 10px;
margin-right: 6px;
border-radius: 2px;
}

.track-checkbox-compact {
::v-deep .v-input--selection-controls__input {
margin-right: 0;
}
}

.trackNumber-compact {
font-size: 14px;
font-weight: bold;
margin-right: 8px;
min-width: 30px;
text-align: center;
}

.track-frame-start,
Expand Down Expand Up @@ -602,9 +643,19 @@ export default defineComponent({
padding: 1px 4px;
margin-right: 8px;
outline: none;

&.track-length {
width: 64px;
min-width: 64px;
max-width: 64px;
text-align: center;
}
}

.track-length {
width: 64px;
min-width: 64px;
max-width: 64px;
text-align: center;
}

Expand Down
Loading