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
900 changes: 900 additions & 0 deletions client/dive-common/components/Attributes/AttributeCustomUI.vue

Large diffs are not rendered by default.

49 changes: 37 additions & 12 deletions client/dive-common/components/Attributes/AttributeEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,19 @@ import {
computed, defineComponent, PropType, Ref, ref, watch,
} from 'vue';
import {
Attribute, AttributeShortcut, MetadataLinkOptions, NumericAttributeEditorOptions, StringAttributeEditorOptions,
Attribute, AttributeCustomUI, AttributeShortcut, MetadataLinkOptions, NumericAttributeEditorOptions, StringAttributeEditorOptions,
} from 'vue-media-annotator/use/AttributeTypes';
import {
buildCustomUIPayload,
resolvedCustomUIToEditorValue,
resolveAttributeCustomUI,
stripLegacyDisplayValueFromShortcuts,
} from 'vue-media-annotator/use/attributeCustomUI';
import { usePrompt } from 'dive-common/vue-utilities/prompt-service';
import { useTrackStyleManager } from 'vue-media-annotator/provides';
import AttributeShortcuts from './AttributeShortcuts.vue';
import AttributeRendering from './AttributeRendering.vue';
import AttributeCustomUIEditor from './AttributeCustomUI.vue';
import AttributeValueColors from './AttributeValueColors.vue';
import AttributeNumberValueColors from './AttributeNumberColors.vue';
import AttributeMetadataLink from './AttributeMetadataLink.vue';
Expand All @@ -18,6 +25,7 @@ export default defineComponent({
components: {
AttributeShortcuts,
AttributeRendering,
AttributeCustomUIEditor,
AttributeValueColors,
AttributeNumberValueColors,
AttributeMetadataLink,
Expand Down Expand Up @@ -84,10 +92,19 @@ export default defineComponent({
metadataLinkFromAttribute(props.selectedAttribute),
);

const customUIFromAttribute = (attr: Attribute): AttributeCustomUI => (
resolvedCustomUIToEditorValue(resolveAttributeCustomUI(attr))
);

const customUI: Ref<AttributeCustomUI> = ref(
customUIFromAttribute(props.selectedAttribute),
);

watch(
() => props.selectedAttribute.key,
() => {
metadataLink.value = metadataLinkFromAttribute(props.selectedAttribute);
customUI.value = customUIFromAttribute(props.selectedAttribute);
},
);
let values: string[] = props.selectedAttribute.values ? props.selectedAttribute.values : [];
Expand Down Expand Up @@ -121,6 +138,7 @@ export default defineComponent({
metadataLink.value = {
key: '', updateValue: false, useDynamicKeyFromAttribute: false, dynamicKeyAttributeKey: undefined,
};
customUI.value = customUIFromAttribute({ shortcuts: [] });
}
function add() {
setDefaultValue();
Expand All @@ -146,11 +164,13 @@ export default defineComponent({
key: `${belongs.value}_${name.value}`,
editor: editor.value,
color: color.value ? color.value : tempColor.value,
shortcuts: shortcuts.value,
shortcuts: stripLegacyDisplayValueFromShortcuts(shortcuts.value),
user: user.value ? true : undefined,
render: renderingVals.value,
lockedValues: lockedValues.value,
};
const customUIPayload = buildCustomUIPayload(customUI.value);
data.customUI = customUIPayload;
if (valueOrder) {
data.valueOrder = valueOrder;
}
Expand Down Expand Up @@ -329,6 +349,7 @@ export default defineComponent({
launchColorEditor,
saveAttributeValueColors,
metadataLink,
customUI,
};
},
});
Expand All @@ -343,11 +364,12 @@ export default defineComponent({
<v-tabs v-model="currentTab">
<v-tab> Main </v-tab>
<v-tab> Shortcuts </v-tab>
<v-tab> Custom UI </v-tab>
<v-tab> Rendering </v-tab>
<v-tab> MetadataLink </v-tab>
<v-tab v-if="datatype === 'text' || datatype === 'number'">
Value Colors
</v-tab>
<v-tab> MetadataLink </v-tab>
</v-tabs>
</v-card-title>

Expand Down Expand Up @@ -539,6 +561,9 @@ export default defineComponent({
:attribute-color="color || tempColor"
/>
</v-tab-item>
<v-tab-item>
<AttributeCustomUIEditor v-model="customUI" :attribute="selectedAttribute" />
</v-tab-item>
<v-tab-item>
<v-switch
v-model="attributeRendering"
Expand All @@ -550,15 +575,6 @@ export default defineComponent({
:attribute="selectedAttribute"
/>
</v-tab-item>
<v-tab-item>
<attribute-metadata-link
v-model="metadataLink"
:belongs="belongs"
:datatype="datatype"
:all-attributes="allAttributes"
:current-attribute-key="selectedAttribute.key"
/>
</v-tab-item>
<v-tab-item v-if="datatype === 'text'">
<attribute-value-colors
:attribute="selectedAttribute"
Expand All @@ -571,6 +587,15 @@ export default defineComponent({
@save="saveAttributeValueColors($event)"
/>
</v-tab-item>
<v-tab-item>
<attribute-metadata-link
v-model="metadataLink"
:belongs="belongs"
:datatype="datatype"
:all-attributes="allAttributes"
:current-attribute-key="selectedAttribute.key"
/>
</v-tab-item>
</v-tabs-items>

<v-card-actions>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -336,9 +336,9 @@ export default defineComponent({
<v-col cols="2">
Value
</v-col>
<v-col cols="2" class="shortcut-list-col-button">
Button
</v-col>
<v-col cols="2" class="shortcut-list-col-button">
Button
</v-col>
<v-col cols="1">
Info
</v-col>
Expand Down Expand Up @@ -474,7 +474,7 @@ export default defineComponent({
</draggable>
<v-dialog
v-model="editShortcutDialog"
max-width="600"
max-width="850"
>
<v-card>
<v-card-title>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,14 @@ export default defineComponent({

const applyTypeDefaults = () => {
syncingFromProps = true;
const { displayValue, buttonToolTip } = buttonShortcut.value;
const { buttonToolTip } = buttonShortcut.value;
buttonShortcut.value = {
...defaultButtonForType(
props.shortcutType,
props.attributeName,
props.attributeColor,
),
...(buttonToolTip !== undefined ? { buttonToolTip } : {}),
...(displayValue !== undefined ? { displayValue } : {}),
};
syncingFromProps = false;
updateButtonShortcut();
Expand Down Expand Up @@ -188,7 +187,6 @@ export default defineComponent({
</v-col>
</v-row>
<v-color-picker v-model="buttonShortcut.buttonColor" label="Button Color" />
<v-checkbox v-if="attribute" v-model="buttonShortcut.displayValue" label="Display Value" />
</div>
</div>
</template>
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
<script lang="ts">
import { defineComponent, PropType } from 'vue';
import {
getCustomUIDisplayValueStyle,
getCustomUIValueDisplayContent,
getTruncatedCustomUIDisplayValue,
LONG_VALUE_EXPAND_THRESHOLD,
ResolvedAttributeCustomUI,
shouldShowCustomUIValueTooltip,
shouldUseCustomUIValueExpansion,
} from 'vue-media-annotator/use/attributeCustomUI';

export interface CustomUIValueEntry {
attribute: string;
value: string;
rawLength: number;
longValueMode: ResolvedAttributeCustomUI['longValueMode'];
inherited: boolean;
indicatorStyle: Record<string, string>;
tooltip: string;
valuePrepend?: string;
valueAppend?: string;
valueFontSizeScale: number;
valueAlign: NonNullable<ResolvedAttributeCustomUI['valueAlign']>;
valueColorStyle: Record<string, string>;
}

export default defineComponent({
name: 'CustomUIAttributeValueDisplay',
props: {
entry: {
type: Object as PropType<CustomUIValueEntry>,
required: true,
},
attributeName: {
type: String,
required: true,
},
panelExpanded: {
type: Number as PropType<number | undefined>,
default: undefined,
},
inline: {
type: Boolean,
default: false,
},
headerValueOffset: {
type: Number,
default: 4,
},
reserveSpace: {
type: Boolean,
default: true,
},
},
setup() {
return {
LONG_VALUE_EXPAND_THRESHOLD,
getCustomUIDisplayValueStyle,
getCustomUIValueDisplayContent,
getTruncatedCustomUIDisplayValue,
shouldShowCustomUIValueTooltip,
shouldUseCustomUIValueExpansion,
};
},
computed: {
displayValueText(): string {
return getCustomUIValueDisplayContent(this.entry.value, this.reserveSpace);
},
truncatedDisplayValueText(): string {
return getTruncatedCustomUIDisplayValue(
this.displayValueText,
this.entry.rawLength,
this.entry.longValueMode,
);
},
isEmptyDisplayValue(): boolean {
return this.entry.value.length === 0;
},
},
methods: {
onPanelChange() {
this.$emit('toggle-panel', this.attributeName);
},
getValueTextStyle(entry: CustomUIValueEntry) {
return {
...entry.valueColorStyle,
...entry.indicatorStyle,
};
},
showValueTooltip(entry: CustomUIValueEntry) {
return shouldShowCustomUIValueTooltip(
entry.inherited,
entry.rawLength,
entry.longValueMode,
);
},
},
});
</script>

<template>
<div
class="custom-ui-attribute-value-display"
:class="{
'custom-ui-attribute-value-display--inline': inline,
'custom-ui-attribute-value-display--reserve-space': reserveSpace,
'custom-ui-attribute-value-display--scroll': entry.longValueMode === 'scroll',
}"
:style="inline
? { ...getCustomUIDisplayValueStyle(entry.valueFontSizeScale, entry.valueAlign), marginLeft: `${headerValueOffset}px` }
: getCustomUIDisplayValueStyle(entry.valueFontSizeScale, entry.valueAlign)"
>
<span v-if="entry.valuePrepend">{{ entry.valuePrepend }}</span>
<template v-if="shouldUseCustomUIValueExpansion(entry.rawLength, entry.longValueMode)">
<v-expansion-panels :value="panelExpanded" class="custom-ui-attribute-value-display__panel">
<v-expansion-panel class="border" @change="onPanelChange">
<v-expansion-panel-header>{{ attributeName }} Value</v-expansion-panel-header>
<v-expansion-panel-content>
<v-tooltip bottom :disabled="!showValueTooltip(entry)">
<template #activator="{ on }">
<span
class="custom-ui-attribute-value-display__text"
:class="{ 'custom-ui-attribute-value-display__text--empty': isEmptyDisplayValue }"
:style="getValueTextStyle(entry)"
v-on="showValueTooltip(entry) ? on : undefined"
>
{{ displayValueText }}
</span>
</template>
<span>{{ entry.tooltip }}</span>
</v-tooltip>
</v-expansion-panel-content>
</v-expansion-panel>
</v-expansion-panels>
</template>
<span
v-else-if="entry.longValueMode === 'scroll'"
class="custom-ui-attribute-value--scroll"
>
<v-tooltip bottom :disabled="!showValueTooltip(entry)">
<template #activator="{ on }">
<span
class="custom-ui-attribute-value-display__text"
:class="{ 'custom-ui-attribute-value-display__text--empty': isEmptyDisplayValue }"
:style="getValueTextStyle(entry)"
v-on="showValueTooltip(entry) ? on : undefined"
>
{{ displayValueText }}
</span>
</template>
<span>{{ entry.tooltip }}</span>
</v-tooltip>
</span>
<v-tooltip v-else bottom :disabled="!showValueTooltip(entry)">
<template #activator="{ on }">
<span
class="custom-ui-attribute-value-display__text"
:class="{ 'custom-ui-attribute-value-display__text--empty': isEmptyDisplayValue }"
:style="getValueTextStyle(entry)"
v-on="showValueTooltip(entry) ? on : undefined"
>
{{ truncatedDisplayValueText }}
</span>
</template>
<span>{{ entry.tooltip }}</span>
</v-tooltip>
<span v-if="entry.valueAppend">{{ entry.valueAppend }}</span>
</div>
</template>

<style scoped lang="scss">
.custom-ui-attribute-value-display {
display: block;
width: 100%;
word-break: break-word;
}

.custom-ui-attribute-value-display--inline {
display: inline-block;
width: auto;
vertical-align: baseline;
}

.custom-ui-attribute-value-display--reserve-space {
min-height: 1.25em;
}

.custom-ui-attribute-value-display--reserve-space.custom-ui-attribute-value-display--scroll {
min-height: 120px;
}

.custom-ui-attribute-value-display__text--empty {
visibility: hidden;
}

.custom-ui-attribute-value-display__panel {
display: inline-block;
vertical-align: top;
width: 100%;
max-width: 100%;
}

.custom-ui-attribute-value--scroll {
display: inline-block;
max-height: 120px;
max-width: 100%;
overflow-y: auto;
white-space: pre-wrap;
word-break: break-word;
vertical-align: top;
}
</style>
Loading
Loading