fix: Render valid urls only in custom attributes (#3921)
This commit is contained in:
parent
047070ad87
commit
9f37a6e2ba
5 changed files with 23 additions and 21 deletions
|
@ -63,7 +63,7 @@
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
class="value"
|
class="value"
|
||||||
>
|
>
|
||||||
{{ value || '---' }}
|
{{ urlValue }}
|
||||||
</a>
|
</a>
|
||||||
<p v-else class="value">
|
<p v-else class="value">
|
||||||
{{ displayValue || '---' }}
|
{{ displayValue || '---' }}
|
||||||
|
@ -119,7 +119,7 @@ import format from 'date-fns/format';
|
||||||
import { required, url } from 'vuelidate/lib/validators';
|
import { required, url } from 'vuelidate/lib/validators';
|
||||||
import { BUS_EVENTS } from 'shared/constants/busEvents';
|
import { BUS_EVENTS } from 'shared/constants/busEvents';
|
||||||
import MultiselectDropdown from 'shared/components/ui/MultiselectDropdown.vue';
|
import MultiselectDropdown from 'shared/components/ui/MultiselectDropdown.vue';
|
||||||
|
import { isValidURL } from '../helper/URLHelper';
|
||||||
const DATE_FORMAT = 'yyyy-MM-dd';
|
const DATE_FORMAT = 'yyyy-MM-dd';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -184,6 +184,9 @@ export default {
|
||||||
isAttributeTypeDate() {
|
isAttributeTypeDate() {
|
||||||
return this.attributeType === 'date';
|
return this.attributeType === 'date';
|
||||||
},
|
},
|
||||||
|
urlValue() {
|
||||||
|
return isValidURL(this.value) ? this.value : '---';
|
||||||
|
},
|
||||||
notAttributeTypeCheckboxAndList() {
|
notAttributeTypeCheckboxAndList() {
|
||||||
return !this.isAttributeTypeCheckbox && !this.isAttributeTypeList;
|
return !this.isAttributeTypeCheckbox && !this.isAttributeTypeList;
|
||||||
},
|
},
|
||||||
|
|
|
@ -37,3 +37,9 @@ export const accountIdFromPathname = pathname => {
|
||||||
const accountId = isScoped ? Number(urlParam) : '';
|
const accountId = isScoped ? Number(urlParam) : '';
|
||||||
return accountId;
|
return accountId;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const isValidURL = value => {
|
||||||
|
/* eslint-disable no-useless-escape */
|
||||||
|
const URL_REGEX = /^https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)$/gm;
|
||||||
|
return URL_REGEX.test(value);
|
||||||
|
};
|
||||||
|
|
|
@ -2,6 +2,7 @@ import {
|
||||||
frontendURL,
|
frontendURL,
|
||||||
conversationUrl,
|
conversationUrl,
|
||||||
accountIdFromPathname,
|
accountIdFromPathname,
|
||||||
|
isValidURL,
|
||||||
} from '../URLHelper';
|
} from '../URLHelper';
|
||||||
|
|
||||||
describe('#URL Helpers', () => {
|
describe('#URL Helpers', () => {
|
||||||
|
@ -48,4 +49,13 @@ describe('#URL Helpers', () => {
|
||||||
expect(accountIdFromPathname('')).toBe('');
|
expect(accountIdFromPathname('')).toBe('');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('isValidURL', () => {
|
||||||
|
it('should return true if valid url is passed', () => {
|
||||||
|
expect(isValidURL('https://chatwoot.com')).toBe(true);
|
||||||
|
});
|
||||||
|
it('should return false if invalid url is passed', () => {
|
||||||
|
expect(isValidURL('alert.window')).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
|
import { isValidURL } from '../helper/URLHelper';
|
||||||
export default {
|
export default {
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({
|
...mapGetters({
|
||||||
|
@ -63,16 +63,11 @@ export default {
|
||||||
Number.isInteger(Number(attributeValue)) && Number(attributeValue) > 0
|
Number.isInteger(Number(attributeValue)) && Number(attributeValue) > 0
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
isAttributeLink(attributeValue) {
|
|
||||||
/* eslint-disable no-useless-escape */
|
|
||||||
const URL_REGEX = /^https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)$/gm;
|
|
||||||
return URL_REGEX.test(attributeValue);
|
|
||||||
},
|
|
||||||
attributeDisplayType(attributeValue) {
|
attributeDisplayType(attributeValue) {
|
||||||
if (this.isAttributeNumber(attributeValue)) {
|
if (this.isAttributeNumber(attributeValue)) {
|
||||||
return 'number';
|
return 'number';
|
||||||
}
|
}
|
||||||
if (this.isAttributeLink(attributeValue)) {
|
if (isValidURL(attributeValue)) {
|
||||||
return 'link';
|
return 'link';
|
||||||
}
|
}
|
||||||
return 'text';
|
return 'text';
|
||||||
|
|
|
@ -92,18 +92,6 @@ describe('attributeMixin', () => {
|
||||||
expect(wrapper.vm.attributeDisplayType(9988)).toBe('number');
|
expect(wrapper.vm.attributeDisplayType(9988)).toBe('number');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('return true if link is passed', () => {
|
|
||||||
const Component = {
|
|
||||||
render() {},
|
|
||||||
title: 'TestComponent',
|
|
||||||
mixins: [attributeMixin],
|
|
||||||
};
|
|
||||||
const wrapper = shallowMount(Component, { store, localVue });
|
|
||||||
expect(wrapper.vm.isAttributeLink('https://www.chatwoot.com/pricing')).toBe(
|
|
||||||
true
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('return true if number is passed', () => {
|
it('return true if number is passed', () => {
|
||||||
const Component = {
|
const Component = {
|
||||||
render() {},
|
render() {},
|
||||||
|
|
Loading…
Reference in a new issue