feat: Custom attribute sidebar list UX improvements (#9070)

---------

Co-authored-by: Pranav <pranav@chatwoot.com>
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
This commit is contained in:
Sivin Varghese
2024-04-09 09:30:49 +05:30
committed by GitHub
parent c4e111b554
commit 8fe3c91813
16 changed files with 223 additions and 625 deletions

View File

@@ -2,23 +2,27 @@
<div class="py-3 px-4">
<div class="flex items-center mb-1">
<h4 class="text-sm flex items-center m-0 w-full error">
<div v-if="isAttributeTypeCheckbox" class="checkbox-wrap">
<div v-if="isAttributeTypeCheckbox" class="flex items-center">
<input
v-model="editedValue"
class="checkbox"
class="!my-0 mr-2 ml-0"
type="checkbox"
@change="onUpdate"
/>
</div>
<div class="flex items-center justify-between w-full">
<span
class="attribute-name w-full text-slate-800 dark:text-slate-100 font-medium text-sm mb-0"
:class="{ error: $v.editedValue.$error }"
class="w-full font-medium text-sm mb-0"
:class="
$v.editedValue.$error
? 'text-red-400 dark:text-red-500'
: 'text-slate-800 dark:text-slate-100'
"
>
{{ label }}
</span>
<woot-button
v-if="showActions"
v-if="showCopyAndDeleteButton"
v-tooltip.left="$t('CUSTOM_ATTRIBUTES.ACTIONS.DELETE')"
variant="link"
size="medium"
@@ -31,7 +35,7 @@
</h4>
</div>
<div v-if="notAttributeTypeCheckboxAndList">
<div v-show="isEditing">
<div v-if="isEditing" v-on-clickaway="onClickAway">
<div class="mb-2 w-full flex items-center">
<input
ref="inputfield"
@@ -61,7 +65,7 @@
</div>
<div
v-show="!isEditing"
class="value--view"
class="flex group"
:class="{ 'is-editable': showActions }"
>
<a
@@ -69,35 +73,35 @@
:href="hrefURL"
target="_blank"
rel="noopener noreferrer"
class="value inline-block rounded-sm mb-0 break-all py-0.5 px-1"
class="group-hover:bg-slate-50 group-hover:dark:bg-slate-700 inline-block rounded-sm mb-0 break-all py-0.5 px-1"
>
{{ urlValue }}
</a>
<p
v-else
class="value inline-block rounded-sm mb-0 break-all py-0.5 px-1"
class="group-hover:bg-slate-50 group-hover:dark:bg-slate-700 inline-block rounded-sm mb-0 break-all py-0.5 px-1"
>
{{ displayValue || '---' }}
</p>
<div class="flex max-w-[2rem] gap-1 ml-1 rtl:mr-1 rtl:ml-0">
<woot-button
v-if="showActions"
v-if="showCopyAndDeleteButton"
v-tooltip="$t('CUSTOM_ATTRIBUTES.ACTIONS.COPY')"
variant="link"
size="small"
color-scheme="secondary"
icon="clipboard"
class-names="edit-button"
class-names="hidden group-hover:flex !w-6 flex-shrink-0"
@click="onCopy"
/>
<woot-button
v-if="showActions"
v-if="showEditButton"
v-tooltip.right="$t('CUSTOM_ATTRIBUTES.ACTIONS.EDIT')"
variant="link"
size="small"
color-scheme="secondary"
icon="edit"
class-names="edit-button"
class-names="hidden group-hover:flex !w-6 flex-shrink-0"
@click="onEdit"
/>
</div>
@@ -126,6 +130,7 @@
</template>
<script>
import { mixin as clickaway } from 'vue-clickaway';
import { format, parseISO } from 'date-fns';
import { required, url } from 'vuelidate/lib/validators';
import { BUS_EVENTS } from 'shared/constants/busEvents';
@@ -138,7 +143,7 @@ export default {
components: {
MultiselectDropdown,
},
mixins: [customAttributeMixin],
mixins: [customAttributeMixin, clickaway],
props: {
label: { type: String, required: true },
values: { type: Array, default: () => [] },
@@ -160,11 +165,18 @@ export default {
editedValue: null,
};
},
computed: {
showCopyAndDeleteButton() {
return this.value && this.showActions;
},
showEditButton() {
return !this.value && this.showActions;
},
displayValue() {
if (this.isAttributeTypeDate) {
return new Date(this.value || new Date()).toLocaleDateString();
return this.value
? new Date(this.value || new Date()).toLocaleDateString()
: '';
}
if (this.isAttributeTypeCheckbox) {
return this.value === 'false' ? false : this.value;
@@ -230,6 +242,10 @@ export default {
this.isEditing = false;
this.editedValue = this.formattedValue;
},
contactId() {
// Fix to solve validation not resetting when contactId changes in contact page
this.$v.$reset();
},
},
validations() {
@@ -268,6 +284,10 @@ export default {
this.$refs.inputfield.focus();
}
},
onClickAway() {
this.$v.$reset();
this.isEditing = false;
},
onEdit() {
this.isEditing = true;
this.$nextTick(() => {
@@ -294,6 +314,7 @@ export default {
},
onDelete() {
this.isEditing = false;
this.$v.$reset();
this.$emit('delete', this.attributeKey);
},
onCopy() {
@@ -304,35 +325,6 @@ export default {
</script>
<style lang="scss" scoped>
.checkbox-wrap {
@apply flex items-center;
}
.checkbox {
@apply my-0 mr-2 ml-0;
}
.attribute-name {
&.error {
@apply text-red-400 dark:text-red-500;
}
}
.edit-button {
@apply hidden;
}
.value--view {
@apply flex;
&.is-editable:hover {
.value {
@apply bg-slate-50 dark:bg-slate-700 mb-0;
}
.edit-button {
@apply block;
}
}
}
::v-deep {
.selector-wrap {
@apply m-0 top-1;