mirror of
https://github.com/datahub-project/datahub.git
synced 2025-11-13 17:59:48 +00:00
refactors email for avatars
This commit is contained in:
parent
026e7a878c
commit
10e8fdec8a
@ -11,7 +11,7 @@ import { IOwner, IOwnerResponse } from 'wherehows-web/typings/api/datasets/owner
|
|||||||
import { getAvatarProps } from 'wherehows-web/constants/avatars/avatars';
|
import { getAvatarProps } from 'wherehows-web/constants/avatars/avatars';
|
||||||
import { confirmedOwners, avatarWithDropDownOption } from 'wherehows-web/constants/datasets/owner';
|
import { confirmedOwners, avatarWithDropDownOption } from 'wherehows-web/constants/datasets/owner';
|
||||||
import { containerDataSource } from 'wherehows-web/utils/components/containers/data-source';
|
import { containerDataSource } from 'wherehows-web/utils/components/containers/data-source';
|
||||||
import { isLiUrn } from 'wherehows-web/utils/validators/urn';
|
import { decodeUrn, isLiUrn } from 'wherehows-web/utils/validators/urn';
|
||||||
import { IAppConfig } from 'wherehows-web/typings/api/configurator/configurator';
|
import { IAppConfig } from 'wherehows-web/typings/api/configurator/configurator';
|
||||||
|
|
||||||
@classNames('dataset-owner-list')
|
@classNames('dataset-owner-list')
|
||||||
@ -59,7 +59,12 @@ export default class DatasetOwnerListContainer extends Component {
|
|||||||
@computed('owners')
|
@computed('owners')
|
||||||
get avatars(): Array<IAvatar> {
|
get avatars(): Array<IAvatar> {
|
||||||
const { avatarEntityProps, owners } = this;
|
const { avatarEntityProps, owners } = this;
|
||||||
return arrayPipe(arrayMap(getAvatarProps(avatarEntityProps)), arrayMap(avatarWithDropDownOption))(owners);
|
const [getAvatarProperties, augmentAvatarsWithDropDownOption] = [
|
||||||
|
arrayMap(getAvatarProps(avatarEntityProps)),
|
||||||
|
arrayMap(avatarWithDropDownOption)
|
||||||
|
];
|
||||||
|
|
||||||
|
return arrayPipe(getAvatarProperties, augmentAvatarsWithDropDownOption)(owners);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -69,7 +74,7 @@ export default class DatasetOwnerListContainer extends Component {
|
|||||||
getOwnersTask = task(function*(this: DatasetOwnerListContainer): IterableIterator<Promise<IOwnerResponse>> {
|
getOwnersTask = task(function*(this: DatasetOwnerListContainer): IterableIterator<Promise<IOwnerResponse>> {
|
||||||
const { urn } = this;
|
const { urn } = this;
|
||||||
|
|
||||||
if (isLiUrn(urn)) {
|
if (isLiUrn(decodeUrn(urn))) {
|
||||||
const { owners = [] }: IOwnerResponse = yield readDatasetOwnersByUrn(urn);
|
const { owners = [] }: IOwnerResponse = yield readDatasetOwnersByUrn(urn);
|
||||||
|
|
||||||
set(this, 'owners', confirmedOwners(owners));
|
set(this, 'owners', confirmedOwners(owners));
|
||||||
|
|||||||
@ -165,7 +165,7 @@ const avatarWithDropDownOption = (avatar: IAvatar): IAvatar & Required<Pick<IAva
|
|||||||
avatarOptions: [
|
avatarOptions: [
|
||||||
{
|
{
|
||||||
// if the owner avatar does not have an email then a null value is returned with no action performed
|
// if the owner avatar does not have an email then a null value is returned with no action performed
|
||||||
value: ({ email = '' }: IAvatar): Window | null =>
|
value: ({ email }: IAvatar): Window | null =>
|
||||||
email ? window.open(buildMailToUrl({ to: email || '' }), '_blank') : null,
|
email ? window.open(buildMailToUrl({ to: email || '' }), '_blank') : null,
|
||||||
label: email
|
label: email
|
||||||
}
|
}
|
||||||
|
|||||||
@ -71,7 +71,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&--trigger {
|
&__trigger {
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,7 +21,7 @@
|
|||||||
renderInPlace=true
|
renderInPlace=true
|
||||||
onSelect=(action "onAvatarOptionSelected" avatar) as |dd|}}
|
onSelect=(action "onAvatarOptionSelected" avatar) as |dd|}}
|
||||||
|
|
||||||
{{#dd.trigger class="avatar-item--trigger"}}
|
{{#dd.trigger class="avatar-item__trigger"}}
|
||||||
{{avatars/avatar-image avatar=avatar
|
{{avatars/avatar-image avatar=avatar
|
||||||
class=(if dd.isExpanded "avatar--stacked avatar--focused" "avatar--stacked")}}
|
class=(if dd.isExpanded "avatar--stacked avatar--focused" "avatar--stacked")}}
|
||||||
{{/dd.trigger}}
|
{{/dd.trigger}}
|
||||||
|
|||||||
@ -9,7 +9,7 @@ type MailerHeaders = 'to' | 'cc' | 'bcc' | 'subject' | 'body';
|
|||||||
* Alias for a string of list of string email header values
|
* Alias for a string of list of string email header values
|
||||||
* @alias
|
* @alias
|
||||||
*/
|
*/
|
||||||
export type MailerHeaderValue = Maybe<string | Array<string>>;
|
export type MailerHeaderValue = Maybe<string>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An optional record of email headers to it's value - MailerHeaderValue
|
* An optional record of email headers to it's value - MailerHeaderValue
|
||||||
|
|||||||
@ -1,18 +1,24 @@
|
|||||||
import { encode, decode } from 'wherehows-web/utils/encode-decode-uri-component-with-space';
|
import { encode, decode } from 'wherehows-web/utils/encode-decode-uri-component-with-space';
|
||||||
import { isBlank } from '@ember/utils';
|
import { isBlank } from '@ember/utils';
|
||||||
|
import { isObject } from 'wherehows-web/utils/object';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a url by appending a query pair (?key=value | &key=value) to a base url and
|
* Construct a url by appending a query pair (?key=value | &key=value) to a base url and
|
||||||
* encoding the query value in the pair
|
* encoding the query value in the pair
|
||||||
* @param {String} baseUrl the base or original url that will be appended with a query string
|
* @param baseUrl the base or original url that will be appended with a query string
|
||||||
* @param {String} queryParam
|
* @param queryParamOrMap a map of query keys to values or a single query param key
|
||||||
* @param {String} queryValue
|
* @param queryValue if a queryParam is supplied, then a queryValue can be expected
|
||||||
|
* @param useEncoding flag indicating if the query values should be encoded
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
function buildUrl(): string;
|
function buildUrl(baseUrl: string, queryParamOrMap?: {}, useEncoding?: boolean): string;
|
||||||
function buildUrl(baseUrl: string, mapParams: Record<string, any>): string;
|
function buildUrl(baseUrl: string, queryParamOrMap?: string, queryValue?: string, useEncoding?: boolean): string;
|
||||||
function buildUrl(baseUrl: string, queryKey: string, queryValue: string): string;
|
function buildUrl(
|
||||||
function buildUrl(baseUrl?: string, queryParamOrMap?: string | Record<string, string>, queryValue?: string): string {
|
baseUrl: string,
|
||||||
|
queryParamOrMap: string | Record<string, any> = {},
|
||||||
|
queryValue?: string | boolean,
|
||||||
|
useEncoding: boolean = true
|
||||||
|
): string {
|
||||||
if (!baseUrl) {
|
if (!baseUrl) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
@ -21,16 +27,24 @@ function buildUrl(baseUrl?: string, queryParamOrMap?: string | Record<string, st
|
|||||||
return baseUrl;
|
return baseUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
let paramMap: { [x: string]: string };
|
let paramMap: Record<string, any> = {};
|
||||||
|
|
||||||
|
// queryParamOrMap is a string then, reify paramMap object with supplied value
|
||||||
if (typeof queryParamOrMap === 'string') {
|
if (typeof queryParamOrMap === 'string') {
|
||||||
paramMap = {
|
paramMap = {
|
||||||
[queryParamOrMap]: queryValue || ''
|
[queryParamOrMap]: queryValue
|
||||||
};
|
};
|
||||||
} else {
|
|
||||||
paramMap = queryParamOrMap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Object.keys(paramMap).reduce((url, paramKey) => {
|
if (isObject(queryParamOrMap)) {
|
||||||
|
paramMap = queryParamOrMap;
|
||||||
|
|
||||||
|
if (typeof queryValue === 'boolean') {
|
||||||
|
useEncoding = queryValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Object.keys(paramMap).reduce((url: string, paramKey: string): string => {
|
||||||
// If the query string already contains the initial question mark append
|
// If the query string already contains the initial question mark append
|
||||||
// kv-pair with ampersand
|
// kv-pair with ampersand
|
||||||
const separator = String(url).includes('?') ? '&' : '?';
|
const separator = String(url).includes('?') ? '&' : '?';
|
||||||
@ -44,13 +58,14 @@ function buildUrl(baseUrl?: string, queryParamOrMap?: string | Record<string, st
|
|||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (useEncoding) {
|
||||||
// Malformed URL will cause decodeURIComponent to throw
|
// Malformed URL will cause decodeURIComponent to throw
|
||||||
// handle and encode queryValue in such instance
|
// handle and encode queryValue in such instance
|
||||||
try {
|
try {
|
||||||
// Check if queryValue is already encoded,
|
// Check if queryValue is already encoded,
|
||||||
// otherwise encode queryValue before composing url
|
// otherwise encode queryValue before composing url
|
||||||
// e.g. if user directly enters query in location bar
|
// e.g. if user directly enters query in location bar
|
||||||
if (decode(paramValue) === queryValue) {
|
if (decode(paramValue) === paramValue) {
|
||||||
paramValue = encode(paramValue);
|
paramValue = encode(paramValue);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -60,6 +75,7 @@ function buildUrl(baseUrl?: string, queryParamOrMap?: string | Record<string, st
|
|||||||
|
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return `${url}${separator}${paramKey}=${paramValue}`;
|
return `${url}${separator}${paramKey}=${paramValue}`;
|
||||||
}, baseUrl);
|
}, baseUrl);
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import { arrayReduce } from 'wherehows-web/utils/array';
|
|
||||||
import buildUrl from 'wherehows-web/utils/build-url';
|
import buildUrl from 'wherehows-web/utils/build-url';
|
||||||
import { IMailHeaderRecord, MailerHeaderValue } from 'wherehows-web/typings/app/helpers/email';
|
import { IMailHeaderRecord } from 'wherehows-web/typings/app/helpers/email';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a `mailto:` address with supplied email headers as query parameters
|
* Constructs a `mailto:` address with supplied email headers as query parameters
|
||||||
@ -9,14 +8,9 @@ import { IMailHeaderRecord, MailerHeaderValue } from 'wherehows-web/typings/app/
|
|||||||
*/
|
*/
|
||||||
const buildMailToUrl = (headers: IMailHeaderRecord = {}): string => {
|
const buildMailToUrl = (headers: IMailHeaderRecord = {}): string => {
|
||||||
const { to = '', ...otherHeaders } = headers;
|
const { to = '', ...otherHeaders } = headers;
|
||||||
const [...otherHeaderPairs] = Object.entries(otherHeaders);
|
const mailTo = `mailto:${encodeURIComponent(to)}`;
|
||||||
const mailTo = `mailto:${to}`;
|
|
||||||
|
|
||||||
return arrayReduce(
|
return buildUrl(mailTo, otherHeaders);
|
||||||
(mailTo: string, [headerName, headerValue = '']: [string, MailerHeaderValue]) =>
|
|
||||||
buildUrl(mailTo, headerName, String(headerValue)),
|
|
||||||
mailTo
|
|
||||||
)([...otherHeaderPairs]);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export { buildMailToUrl };
|
export { buildMailToUrl };
|
||||||
|
|||||||
@ -7,51 +7,47 @@ const base = 'mailto:';
|
|||||||
const mailToEmail = `${base}${emailAddress}`;
|
const mailToEmail = `${base}${emailAddress}`;
|
||||||
const emailMailToAsserts = [
|
const emailMailToAsserts = [
|
||||||
{
|
{
|
||||||
__expected__: base,
|
expected: base,
|
||||||
__args__: void 0,
|
args: void 0,
|
||||||
__assert_msg__: 'it should return a basic mailto: string without an email when no arguments are passed'
|
assertMsg: 'it should return a basic mailto: string without an email when no arguments are passed'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
__expected__: base,
|
expected: base,
|
||||||
__args__: {},
|
args: {},
|
||||||
__assert_msg__: 'it should return a basic mailto: string without an email when an empty object is passed'
|
assertMsg: 'it should return a basic mailto: string without an email when an empty object is passed'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
__expected__: base,
|
expected: base,
|
||||||
__args__: { to: '' },
|
args: { to: '' },
|
||||||
__assert_msg__:
|
assertMsg:
|
||||||
'it should return a basic mailto: string without an email when an object with only an empty string in the `to` field is passed'
|
'it should return a basic mailto: string without an email when an object with only an empty string in the `to` field is passed'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
__expected__: `${mailToEmail}`,
|
expected: `${mailToEmail}`,
|
||||||
__args__: { to: emailAddress },
|
args: { to: emailAddress },
|
||||||
__assert_msg__: 'it should return a mailto: string with an email when an object with only the `to` field is passed'
|
assertMsg: 'it should return a mailto: string with an email when an object with only the `to` field is passed'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
__expected__: `${mailToEmail}?cc=${encodeURIComponent(cc)}`,
|
expected: `${mailToEmail}?cc=${cc}`,
|
||||||
__args__: { to: emailAddress, cc },
|
args: { to: emailAddress, cc },
|
||||||
__assert_msg__: 'it should return a mailto: string with an email and a cc query when to and cc are passed in'
|
assertMsg: 'it should return a mailto: string with an email and a cc query when to and cc are passed in'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
__expected__: `${mailToEmail}?cc=${encodeURIComponent(cc)}&subject=${encodeURIComponent(subject)}`,
|
expected: `${mailToEmail}?cc=${cc}&subject=${subject}`,
|
||||||
__args__: { to: emailAddress, cc, subject },
|
args: { to: emailAddress, cc, subject },
|
||||||
__assert_msg__:
|
assertMsg:
|
||||||
'it should return a mailto: string with an email, subject, and a cc query when to, subject, and cc are passed in'
|
'it should return a mailto: string with an email, subject, and a cc query when to, subject, and cc are passed in'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
__expected__: `${mailToEmail}?cc=${encodeURIComponent(cc)}&subject=${encodeURIComponent(
|
expected: `${mailToEmail}?cc=${cc}&subject=${subject}&bcc=${bcc}`,
|
||||||
subject
|
args: { to: emailAddress, cc, subject, bcc },
|
||||||
)}&bcc=${encodeURIComponent(bcc)}`,
|
assertMsg:
|
||||||
__args__: { to: emailAddress, cc, subject, bcc },
|
|
||||||
__assert_msg__:
|
|
||||||
'it should return a mailto: string with an email, subject, bcc, and a cc query when to, subject, bcc, and cc are passed in'
|
'it should return a mailto: string with an email, subject, bcc, and a cc query when to, subject, bcc, and cc are passed in'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
__expected__: `${mailToEmail}?cc=${encodeURIComponent(cc)}&subject=${encodeURIComponent(
|
expected: `${mailToEmail}?cc=${cc}&subject=${subject}&bcc=${bcc}&body=${body}`,
|
||||||
subject
|
args: { to: emailAddress, cc, subject, bcc, body },
|
||||||
)}&bcc=${encodeURIComponent(bcc)}&body=${encodeURIComponent(body)}`,
|
assertMsg:
|
||||||
__args__: { to: emailAddress, cc, subject, bcc, body },
|
|
||||||
__assert_msg__:
|
|
||||||
'it should return a mailto: string with an email, subject, bcc, body, and a cc query when to, subject, bcc, body, and cc are passed in'
|
'it should return a mailto: string with an email, subject, bcc, body, and a cc query when to, subject, bcc, body, and cc are passed in'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|||||||
@ -3,10 +3,42 @@ import { module, test } from 'qunit';
|
|||||||
|
|
||||||
module('Unit | Utility | build url', function() {
|
module('Unit | Utility | build url', function() {
|
||||||
const baseUrl = 'https://www.linkedin.com';
|
const baseUrl = 'https://www.linkedin.com';
|
||||||
|
const unEncodedString = 'string@string';
|
||||||
|
const encodedString = encodeURIComponent(unEncodedString);
|
||||||
|
|
||||||
test('baseUrl', function(assert) {
|
test('baseUrl', function(assert) {
|
||||||
let result = buildUrl();
|
let result = buildUrl(baseUrl);
|
||||||
assert.equal(result, '', 'returns an empty string when no arguments are passed');
|
assert.equal(result, baseUrl, 'it returns the base url when no other arguments are passed');
|
||||||
|
|
||||||
|
result = buildUrl(baseUrl, {});
|
||||||
|
assert.equal(result, baseUrl, 'it returns the base url when an empty object is supplied as query parameter');
|
||||||
|
|
||||||
|
result = buildUrl(baseUrl, '');
|
||||||
|
assert.equal(result, baseUrl, 'it returns the base url when an empty string is supplied as query parameter');
|
||||||
|
|
||||||
|
result = buildUrl(baseUrl, '', true);
|
||||||
|
assert.equal(
|
||||||
|
result,
|
||||||
|
baseUrl,
|
||||||
|
'it returns the base url when the queryParam is an empty string and the useEncoding is set'
|
||||||
|
);
|
||||||
|
|
||||||
|
result = buildUrl(baseUrl, 'query', true);
|
||||||
|
assert.equal(
|
||||||
|
result,
|
||||||
|
`${baseUrl}?query=true`,
|
||||||
|
'it returns the base url with a query key set to true when true is passed as a query value'
|
||||||
|
);
|
||||||
|
|
||||||
|
result = buildUrl(baseUrl, 'query', unEncodedString, true);
|
||||||
|
assert.equal(
|
||||||
|
result,
|
||||||
|
`${baseUrl}?query=${encodedString}`,
|
||||||
|
'it returns the encoded value when the useEncoding flag is true'
|
||||||
|
);
|
||||||
|
|
||||||
|
result = buildUrl(baseUrl, { query: unEncodedString }, true);
|
||||||
|
assert.equal(result, `${baseUrl}?query=${encodedString}`, 'it returns the encoded string on a queryParams object');
|
||||||
|
|
||||||
result = buildUrl(baseUrl, '', '');
|
result = buildUrl(baseUrl, '', '');
|
||||||
assert.equal(result, baseUrl, 'returns the baseUrl when no query parameter is supplied');
|
assert.equal(result, baseUrl, 'returns the baseUrl when no query parameter is supplied');
|
||||||
|
|||||||
@ -10,8 +10,8 @@ module('Unit | Utility | helpers/email', function(): void {
|
|||||||
test('buildMailToUrl generates expected url values', function(assert): void {
|
test('buildMailToUrl generates expected url values', function(assert): void {
|
||||||
assert.expect(emailMailToAsserts.length);
|
assert.expect(emailMailToAsserts.length);
|
||||||
|
|
||||||
emailMailToAsserts.forEach(({ __expected__, __args__, __assert_msg__ }) => {
|
emailMailToAsserts.forEach(({ expected, args, assertMsg }) => {
|
||||||
assert.equal(buildMailToUrl(__args__), __expected__, __assert_msg__);
|
assert.equal(buildMailToUrl(args), expected, assertMsg);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user