diff --git a/wherehows-web/app/components/dataset-aclaccess.ts b/wherehows-web/app/components/dataset-aclaccess.ts index a29aa37108..ee625aa83c 100644 --- a/wherehows-web/app/components/dataset-aclaccess.ts +++ b/wherehows-web/app/components/dataset-aclaccess.ts @@ -2,12 +2,17 @@ import Component from '@ember/component'; import { get, set } from '@ember/object'; import ComputedProperty, { gte } from '@ember/object/computed'; import { TaskInstance, TaskProperty } from 'ember-concurrency'; -import { action } from '@ember-decorators/object'; +import { action, computed } from '@ember-decorators/object'; import { IAccessControlAccessTypeOption, + IAccessControlEntry, IRequestAccessControlEntry } from 'wherehows-web/typings/api/datasets/aclaccess'; import { getDefaultRequestAccessControlEntry } from 'wherehows-web/utils/datasets/acl-access'; +import { IAvatar } from 'wherehows-web/typings/app/avatars'; +import { arrayMap } from 'wherehows-web/utils/array'; +import { IAppConfig } from 'wherehows-web/typings/api/configurator/configurator'; +import { getAvatarProps } from 'wherehows-web/constants/avatars/avatars'; /** * Returns the number of days in milliseconds, default is 1 day @@ -30,6 +35,19 @@ const minSelectableExpirationDate = new Date(Date.now() + millisecondDays()); const maxSelectableExpirationDate = new Date(Date.now() + millisecondDays(7)); export default class DatasetAclAccess extends Component { + /** + * External component attribute with list of acls + * @type {Array} + */ + acls: Array; + + /** + * External component attribute with properties to construct an acl's avatar image + * @type {(IAppConfig['userEntityProps'] | undefined)} + * @memberof DatasetAclAccess + */ + avatarProperties: IAppConfig['userEntityProps'] | undefined; + /** * Named component argument with a string link reference to more information on acls * @type {string} @@ -109,6 +127,23 @@ export default class DatasetAclAccess extends Component { set(this, 'userAclRequest', getDefaultRequestAccessControlEntry()); } + /** + * Augments each acl in the list with properties for the user avatar + * @readonly + * @type {(Array>)} + * @memberof DatasetAclAccess + */ + @computed('acls') + get aclsWithAvatarProps(): Array> { + const { acls, avatarProperties } = this; + const aclWithAvatar = (acl: IAccessControlEntry): IAccessControlEntry & Record<'avatar', IAvatar> => ({ + ...acl, + avatar: getAvatarProps(avatarProperties!)({ userName: acl.principal }) + }); + + return avatarProperties ? arrayMap(aclWithAvatar)(acls) : []; + } + /** * Invokes external action when the accessType to be requested is modified * @param {IAccessControlAccessTypeOption} arg diff --git a/wherehows-web/app/components/dataset-author.ts b/wherehows-web/app/components/dataset-author.ts index 6c26b71503..ff20d5da09 100644 --- a/wherehows-web/app/components/dataset-author.ts +++ b/wherehows-web/app/components/dataset-author.ts @@ -6,6 +6,7 @@ import { assert } from '@ember/debug'; import { IOwner } from 'wherehows-web/typings/api/datasets/owners'; import { OwnerSource, OwnerType } from 'wherehows-web/utils/api/datasets/owners'; import { action } from '@ember-decorators/object'; +import { OwnerWithAvatarRecord } from 'wherehows-web/typings/app/datasets/owners'; /** * This component renders a single owner record and also provides functionality for interacting with the component @@ -26,10 +27,10 @@ export default class DatasetAuthor extends Component { /** * The owner record being rendered - * @type {IOwner} + * @type {OwnerWithAvatarRecord} * @memberof DatasetAuthor */ - owner: IOwner; + owner: OwnerWithAvatarRecord; /** * List of suggested owners that have been confirmed by a user @@ -73,14 +74,14 @@ export default class DatasetAuthor extends Component { * @type {ComputedProperty} * @memberof DatasetAuthor */ - isOwnerMutable: ComputedProperty = equal('owner.source', OwnerSource.Ui); + isOwnerMutable: ComputedProperty = equal('owner.owner.source', OwnerSource.Ui); /** * Negates the owner attribute flag `isActive`, indicating owner record is considered inactive * @type {ComputedProperty} * @memberOf DatasetAuthor */ - isOwnerInActive: ComputedProperty = not('owner.isActive'); + isOwnerInActive: ComputedProperty = not('owner.owner.isActive'); /** * Determines if the owner record is a system suggested owner and if this record is confirmed by a user @@ -93,7 +94,9 @@ export default class DatasetAuthor extends Component { const { commonOwners, isOwnerMutable, - owner: { userName } + owner: { + owner: { userName } + } } = getProperties(this, ['commonOwners', 'isOwnerMutable', 'owner']); return isOwnerMutable ? false : !!commonOwners.findBy('userName', userName); @@ -123,7 +126,7 @@ export default class DatasetAuthor extends Component { @action onRemoveOwner(): boolean | void | IOwner { const { owner, isOwnerMutable, removeOwner } = getProperties(this, ['owner', 'isOwnerMutable', 'removeOwner']); - return isOwnerMutable && removeOwner(owner); + return isOwnerMutable && removeOwner(owner.owner); } /** @@ -133,7 +136,7 @@ export default class DatasetAuthor extends Component { @action confirmOwner(): Array | void { const { owner, confirmSuggestedOwner } = getProperties(this, ['owner', 'confirmSuggestedOwner']); - return confirmSuggestedOwner(owner); + return confirmSuggestedOwner(owner.owner); } /** @@ -149,6 +152,6 @@ export default class DatasetAuthor extends Component { 'updateOwnerType' ]); - return isOwnerMutable && updateOwnerType(owner, type); + return isOwnerMutable && updateOwnerType(owner.owner, type); } } diff --git a/wherehows-web/app/components/dataset-authors.ts b/wherehows-web/app/components/dataset-authors.ts index 04aec12ab0..c045de4bfa 100644 --- a/wherehows-web/app/components/dataset-authors.ts +++ b/wherehows-web/app/components/dataset-authors.ts @@ -2,7 +2,7 @@ import Component from '@ember/component'; import { set, get, getProperties } from '@ember/object'; import { assert } from '@ember/debug'; import { action, computed } from '@ember-decorators/object'; -import { filter } from '@ember-decorators/object/computed'; +import { filter, map } from '@ember-decorators/object/computed'; import { service } from '@ember-decorators/service'; import { task } from 'ember-concurrency'; @@ -21,6 +21,9 @@ import { import { OwnerSource, OwnerType } from 'wherehows-web/utils/api/datasets/owners'; import Notifications, { NotificationEvent } from 'wherehows-web/services/notifications'; import { noop } from 'wherehows-web/utils/helpers/functions'; +import { IAppConfig } from 'wherehows-web/typings/api/configurator/configurator'; +import { getAvatarProps } from 'wherehows-web/constants/avatars/avatars'; +import { OwnerWithAvatarRecord } from 'wherehows-web/typings/app/datasets/owners'; type Comparator = -1 | 0 | 1; @@ -53,6 +56,13 @@ export default class DatasetAuthors extends Component { */ suggestedOwners: Array; + /** + * Avatar properties used to generate avatar images + * @type {(IAppConfig['userEntityProps'] | undefined)} + * @memberof DatasetAuthors + */ + avatarProperties: IAppConfig['userEntityProps'] | undefined; + /** * Current user service * @type {ComputedProperty} @@ -154,6 +164,35 @@ export default class DatasetAuthors extends Component { @filter('owners', isConfirmedOwner) confirmedOwners: Array; + /** + * Augments an IOwner instance with an IAvatar Record keyed by 'avatar' + * @this {DatasetAuthors} + * @param owner + * @memberof DatasetAuthors + * @returns {OwnerWithAvatarRecord} + */ + datasetAuthorsOwnersAugmentedWithAvatars = (owner: IOwner): OwnerWithAvatarRecord => { + const { avatarProperties } = this; + + return { + owner, + avatar: avatarProperties + ? getAvatarProps(avatarProperties)({ userName: owner.userName }) + : { imageUrl: '', imageUrlFallback: '/assets/assets/images/default_avatar.png' } + }; + }; + + /** + * Augments each confirmedOwner IOwner instance with an avatar Record + * @param {IOwner} owner the IOwner instance + * @returns {OwnerWithAvatarRecord} + * @memberof DatasetAuthors + */ + @map('confirmedOwners') + confirmedOwnersWithAvatars(owner: IOwner): OwnerWithAvatarRecord { + return this.datasetAuthorsOwnersAugmentedWithAvatars(owner); + } + /** * Intersection of confirmed owners and suggested owners * @type {ComputedProperty>} @@ -185,6 +224,17 @@ export default class DatasetAuthors extends Component { return (get(this, 'suggestedOwners') || []).slice(0); } + /** + * Augments each systemGeneratedOwner IOwner instance with an avatar Record + * @param {IOwner} owner the IOwner instance + * @returns {OwnerWithAvatarRecord} + * @memberof DatasetAuthors + */ + @map('systemGeneratedOwners') + systemGeneratedOwnersWithAvatars(owner: IOwner): OwnerWithAvatarRecord { + return this.datasetAuthorsOwnersAugmentedWithAvatars(owner); + } + /** * Invokes the external action as a dropping task * @type {Task>, void>} @@ -216,8 +266,10 @@ export default class DatasetAuthors extends Component { */ @action addOwner(this: DatasetAuthors, newOwner: IOwner): Array | void { - const owners = get(this, 'owners') || []; - const { notify } = get(this, 'notifications'); + const { + owners = [], + notifications: { notify } + } = this; if (ownerAlreadyExists(owners, { userName: newOwner.userName, source: newOwner.source })) { return void notify(NotificationEvent.info, { content: 'Owner has already been added to "confirmed" list' }); diff --git a/wherehows-web/app/components/dataset-compliance.ts b/wherehows-web/app/components/dataset-compliance.ts index 3996661a44..b9b0fd1762 100644 --- a/wherehows-web/app/components/dataset-compliance.ts +++ b/wherehows-web/app/components/dataset-compliance.ts @@ -317,7 +317,7 @@ export default class DatasetCompliance extends Component { ): string { type TagFilterHint = { [K in TagFilter]: string }; - const { fieldReviewOption, foldedChangeSet = [] } = getProperties(this, ['fieldReviewOption', 'foldedChangeSet']); + const { fieldReviewOption, foldedChangeSet = [] } = this; const hint = ({ [TagFilter.showAll]: '', @@ -883,7 +883,7 @@ export default class DatasetCompliance extends Component { * @type {Array} * @memberof DatasetCompliance */ - foldedChangeSet: Array | void; + foldedChangeSet: Array = []; /** * Task to retrieve platform policies and set supported policies for the current platform diff --git a/wherehows-web/app/components/datasets/containers/dataset-acl-access.ts b/wherehows-web/app/components/datasets/containers/dataset-acl-access.ts index 644f6c3892..b09d5901ed 100644 --- a/wherehows-web/app/components/datasets/containers/dataset-acl-access.ts +++ b/wherehows-web/app/components/datasets/containers/dataset-acl-access.ts @@ -21,6 +21,9 @@ import Notifications, { NotificationEvent } from 'wherehows-web/services/notific import { notificationDialogActionFactory } from 'wherehows-web/utils/notifications/notifications'; import { service } from '@ember-decorators/service'; import { equal } from '@ember-decorators/object/computed'; +import { IAppConfig } from 'wherehows-web/typings/api/configurator/configurator'; +import Configurator from 'wherehows-web/services/configurator'; +import { containerDataSource } from 'wherehows-web/utils/components/containers/data-source'; /** * Enumerates the string value for an acl access request @@ -31,6 +34,7 @@ enum AclRequestType { Approval = 'approved' } +@containerDataSource('getContainerDataTask') export default class DatasetAclAccessContainer extends Component { /** * The currently logged in user service @@ -78,9 +82,17 @@ export default class DatasetAclAccessContainer extends Component { /** * Who to contact in case of error + * @type {string} */ jitAclContact: string; + /** + * Avatar properties used to generate the acl's avatar image + * @type {(IAppConfig['userEntityProps'] | undefined)} + * @memberof DatasetAclAccessContainer + */ + avatarProperties: IAppConfig['userEntityProps'] | undefined; + /** * Request object for the current user requesting access control * @type {IRequestAccessControlEntry} @@ -112,14 +124,6 @@ export default class DatasetAclAccessContainer extends Component { */ urn: string; - didInsertElement() { - get(this, 'getContainerDataTask').perform(); - } - - didUpdateAttrs() { - get(this, 'getContainerDataTask').perform(); - } - constructor() { super(...arguments); @@ -189,15 +193,17 @@ export default class DatasetAclAccessContainer extends Component { * @memberof DatasetAclAccessContainer */ getContainerDataTask = task(function*(this: DatasetAclAccessContainer): IterableIterator { - if (get(this, 'isJitAclAccessEnabled')) { - const { getCurrentUserTask, getDatasetAclsTask, checkUserAccessTask } = getProperties(this, [ + if (this.isJitAclAccessEnabled) { + const { getCurrentUserTask, getDatasetAclsTask, checkUserAccessTask, getAvatarProperties } = getProperties(this, [ 'getCurrentUserTask', 'getDatasetAclsTask', - 'checkUserAccessTask' + 'checkUserAccessTask', + 'getAvatarProperties' ]); const user: DatasetAclAccessContainer['user'] = yield getCurrentUserTask.perform(); if (user) { + yield getAvatarProperties.perform(); yield getDatasetAclsTask.perform(); yield checkUserAccessTask.perform(); } @@ -214,6 +220,16 @@ export default class DatasetAclAccessContainer extends Component { return set(this, 'user', currentUser); }); + /** + * Fetches and sets the props used in constructing an acl's avatar + * @memberof DatasetAclAccessContainer + */ + getAvatarProperties = task(function*( + this: DatasetAclAccessContainer + ): IterableIterator { + return set(this, 'avatarProperties', Configurator.getConfig('userEntityProps')); + }); + /** * Fetches the list of acls for this dataset * @memberof DatasetAclAccessContainer diff --git a/wherehows-web/app/components/datasets/containers/dataset-owner-list.ts b/wherehows-web/app/components/datasets/containers/dataset-owner-list.ts index c6c3cbbe0a..c287dee9ec 100644 --- a/wherehows-web/app/components/datasets/containers/dataset-owner-list.ts +++ b/wherehows-web/app/components/datasets/containers/dataset-owner-list.ts @@ -47,7 +47,7 @@ export default class DatasetOwnerListContainer extends Component { * @type {IAppConfig.avatarEntityProps} * @memberof DatasetOwnerListContainer */ - avatarEntityProps!: IAppConfig['avatarEntityProps']; + avatarEntityProps!: IAppConfig['userEntityProps']; /** * Lists the avatar objects based off the dataset owners diff --git a/wherehows-web/app/components/datasets/containers/dataset-ownership.ts b/wherehows-web/app/components/datasets/containers/dataset-ownership.ts index d729bb44da..a77d0ff8fa 100644 --- a/wherehows-web/app/components/datasets/containers/dataset-ownership.ts +++ b/wherehows-web/app/components/datasets/containers/dataset-ownership.ts @@ -13,7 +13,11 @@ import { updateDatasetOwnersByUrn } from 'wherehows-web/utils/api/datasets/owners'; import { service } from '@ember-decorators/service'; +import { IAppConfig } from 'wherehows-web/typings/api/configurator/configurator'; +import Configurator from 'wherehows-web/services/configurator'; +import { containerDataSource } from 'wherehows-web/utils/components/containers/data-source'; +@containerDataSource('getContainerDataTask') export default class DatasetOwnershipContainer extends Component { /** * The urn identifier for the dataset @@ -58,26 +62,42 @@ export default class DatasetOwnershipContainer extends Component { */ upstreamUrn: string; - didInsertElement() { - get(this, 'getContainerDataTask').perform(); - } - - didUpdateAttrs() { - get(this, 'getContainerDataTask').perform(); - } + /** + * Avatar properties used to generate avatar images + * @type {(IAppConfig['userEntityProps'] | undefined)} + * @memberof DatasetOwnershipContainer + */ + avatarProperties: IAppConfig['userEntityProps'] | undefined; /** * An async parent task to group all data tasks for this container component * @type {Task>, (a?: any) => TaskInstance>>>} */ - getContainerDataTask = task(function*(this: DatasetOwnershipContainer): IterableIterator>> { + getContainerDataTask = task(function*( + this: DatasetOwnershipContainer + ): IterableIterator | IAppConfig['userEntityProps']>> { const tasks = Object.values( - getProperties(this, ['getDatasetOwnersTask', 'getSuggestedOwnersTask', 'getDatasetOwnerTypesTask']) + getProperties(this, [ + 'getDatasetOwnersTask', + 'getSuggestedOwnersTask', + 'getDatasetOwnerTypesTask', + 'getAvatarProperties' + ]) ); yield* tasks.map(task => task.perform()); }); + /** + * Fetches & sets avatar props to build owner avatar images + * @memberof DatasetOwnershipContainer + */ + getAvatarProperties = task(function*( + this: DatasetOwnershipContainer + ): IterableIterator { + return set(this, 'avatarProperties', Configurator.getConfig('userEntityProps')); + }); + /** * Reads the owners for this dataset * @type {Task>, (a?: any) => TaskInstance>>} diff --git a/wherehows-web/app/components/datasets/owners/suggested-owners.ts b/wherehows-web/app/components/datasets/owners/suggested-owners.ts index ddcf26ee9e..beb7ddd75c 100644 --- a/wherehows-web/app/components/datasets/owners/suggested-owners.ts +++ b/wherehows-web/app/components/datasets/owners/suggested-owners.ts @@ -1,12 +1,12 @@ import Component from '@ember/component'; -import { IOwner } from 'wherehows-web/typings/api/datasets/owners'; -import { get, set } from '@ember/object'; +import { set } from '@ember/object'; import { computed } from '@ember-decorators/object'; import { empty } from '@ember-decorators/object/computed'; +import { classNames } from '@ember-decorators/component'; +import { OwnerWithAvatarRecord } from 'wherehows-web/typings/app/datasets/owners'; +@classNames('dataset-authors-suggested') export default class DatasetsOwnersSuggestedOwners extends Component { - classNames = ['dataset-authors-suggested']; - constructor() { super(...arguments); @@ -17,17 +17,16 @@ export default class DatasetsOwnersSuggestedOwners extends Component { * Whether or not the component is expanded. If not, users will only see the initial header information * whereas if expanded then users will see the list of all suggested owners * @type {boolean} - * @default false */ isExpanded = false; /** * Passed in value from parent component, `dataset-authors`, a.k.a. systemGeneratedOwners, this list * represents a possible list of owners provided by scanning various systems. - * @type {Array} + * @type {Array} * @default [] */ - owners: Array; + owners: Array; /** * Computed based on the owners array, detects whether this array is empty or not @@ -40,10 +39,10 @@ export default class DatasetsOwnersSuggestedOwners extends Component { * For the facepile in the suggestions window header, we do not need tos how all the faces of all the * possible owners as this could be a large amount. Take only up to the first four to pass into the * template for rendering - * @type {ComputedProperty>} + * @type {ComputedProperty>} */ @computed('owners') - get facepileOwners(this: DatasetsOwnersSuggestedOwners): Array { - return get(this, 'owners').slice(0, 4); + get facepileOwners(this: DatasetsOwnersSuggestedOwners): Array { + return this.owners.slice(0, 4); } } diff --git a/wherehows-web/app/components/hotkeys/global-hotkeys.ts b/wherehows-web/app/components/hotkeys/global-hotkeys.ts index 7bce35cc9d..398e659083 100644 --- a/wherehows-web/app/components/hotkeys/global-hotkeys.ts +++ b/wherehows-web/app/components/hotkeys/global-hotkeys.ts @@ -9,7 +9,7 @@ export default class GlobalHotkeys extends Component { * Sets the class names binded to the html element generated by this component * @type {Array} */ - classNames = ['global-hotkey-binder']; + classNames = ['global-hotkey']; /** * Allows us to bind the tabindex attribute to our element to make it focusable. This will diff --git a/wherehows-web/app/components/user-avatar.ts b/wherehows-web/app/components/user-avatar.ts deleted file mode 100644 index 5d6010fd7d..0000000000 --- a/wherehows-web/app/components/user-avatar.ts +++ /dev/null @@ -1,31 +0,0 @@ -import Component from '@ember/component'; -import ComputedProperty from '@ember/object/computed'; -import { avatar } from 'wherehows-web/constants'; -import { computed, get } from '@ember/object'; - -const { fallbackUrl, url }: { fallbackUrl: string; url: string } = avatar; -const headlessUserName: string = 'wherehows'; - -export default class UserAvatar extends Component { - tagName = 'span'; - - /** - * username for the user, e.g. ldap userName that can be used to construct the url - * @type {string} - */ - userName: string; - - /** - * Ember.ComputedProperty that resolves with the image url for the avatar - * @type {ComputedProperty} - * @memberof UserAvatar - */ - imageUrl: ComputedProperty = computed('userName', function(this: UserAvatar) { - const userName = get(this, 'userName'); - if (userName && userName !== headlessUserName) { - return url.replace('[username]', userName); - } - - return fallbackUrl; - }); -} diff --git a/wherehows-web/app/constants/application.ts b/wherehows-web/app/constants/application.ts index 7cb3bfc143..e81ad17809 100644 --- a/wherehows-web/app/constants/application.ts +++ b/wherehows-web/app/constants/application.ts @@ -4,13 +4,4 @@ */ const feedback = { mail: 'wherehows-dev@linkedin.com', subject: 'WhereHows Feedback', title: 'Provide Feedback' }; -/** - * Defines the properties for the navigation bar avatar - * @type {object} - */ -const avatar = { - url: 'https://cinco.corp.linkedin.com/api/profile/[username]/picture/?access_token=2rzmbzEMGlHsszQktFY-B1TxUic', - fallbackUrl: '/assets/assets/images/default_avatar.png' -}; - -export { feedback, avatar }; +export { feedback }; diff --git a/wherehows-web/app/constants/avatars/avatars.ts b/wherehows-web/app/constants/avatars/avatars.ts index a67412aeab..f46b35c82e 100644 --- a/wherehows-web/app/constants/avatars/avatars.ts +++ b/wherehows-web/app/constants/avatars/avatars.ts @@ -5,23 +5,19 @@ import { IAppConfig } from 'wherehows-web/typings/api/configurator/configurator' /** * Takes a Partial object and builds an IAvatar * @param {Partial} object - * @param {IAppConfig.avatarEntityProps.urlPrimary} urlPrimary - * @param {IAppConfig.avatarEntityProps.urlPrimary} urlFallback + * @param {IAppConfig.userEntityProps.aviUrlPrimary} aviUrlPrimary primary url for avatar image + * @param {IAppConfig.userEntityProps.aviUrlFallback} aviUrlFallback * @return {IAvatar} */ -const getAvatarProps = ({ urlPrimary, urlFallback }: IAppConfig['avatarEntityProps']) => ( +const getAvatarProps = ({ aviUrlPrimary, aviUrlFallback = '' }: IAppConfig['userEntityProps']) => ( object: Partial ): IAvatar => { const props = pick(object, ['email', 'userName', 'name']); - let imageUrl = urlFallback || ''; - - if (props.userName && urlPrimary) { - imageUrl = urlPrimary.replace('[username]', props.userName); - } + const hasRequiredUrlElements = props.userName && aviUrlPrimary; return { - imageUrl, - imageUrlFallback: urlFallback, + imageUrl: hasRequiredUrlElements ? aviUrlPrimary.replace('[username]', props.userName!) : aviUrlFallback, + imageUrlFallback: aviUrlFallback, ...props }; }; diff --git a/wherehows-web/app/controllers/datasets/dataset.ts b/wherehows-web/app/controllers/datasets/dataset.ts index 2ff390f89a..75f59e05c4 100644 --- a/wherehows-web/app/controllers/datasets/dataset.ts +++ b/wherehows-web/app/controllers/datasets/dataset.ts @@ -78,7 +78,7 @@ export default class DatasetController extends Controller { * References a collection of properties for avatar properties * @type {IAppConfig.avatarEntityProps} */ - avatarEntityProps: IAppConfig['avatarEntityProps']; + avatarEntityProps: IAppConfig['userEntityProps']; /** * Flag indicating the dataset policy is derived from an upstream source diff --git a/wherehows-web/app/routes/application.js b/wherehows-web/app/routes/application.js index bc601745d1..4bea3d32be 100644 --- a/wherehows-web/app/routes/application.js +++ b/wherehows-web/app/routes/application.js @@ -5,9 +5,9 @@ import { get } from '@ember/object'; import ApplicationRouteMixin from 'ember-simple-auth/mixins/application-route-mixin'; import { feedback, avatar } from 'wherehows-web/constants'; import Configurator from 'wherehows-web/services/configurator'; +import { getAvatarProps } from 'wherehows-web/constants/avatars/avatars'; const { mail, subject, title } = feedback; -const { url: avatarUrl } = avatar; export default Route.extend(ApplicationRouteMixin, { // Injected Ember#Service for the current user @@ -42,14 +42,13 @@ export default Route.extend(ApplicationRouteMixin, { */ async model() { const { getConfig } = Configurator; - - const [isInternal, showStagingBanner, showLiveDataWarning] = await Promise.all([ - getConfig('isInternal'), + const [showStagingBanner, showLiveDataWarning, avatarEntityProps] = [ getConfig('isStagingBanner', { useDefault: true, default: false }), - getConfig('isLiveDataWarning', { useDefault: true, default: false }) - ]); - - const { userName } = get(this, 'sessionUser.currentUser') || {}; + getConfig('isLiveDataWarning', { useDefault: true, default: false }), + getConfig('userEntityProps') + ]; + const { userName, email, name } = get(this, 'sessionUser.currentUser') || {}; + const avatar = getAvatarProps(avatarEntityProps)({ userName, email, name }); /** * properties for the navigation link to allow a user to provide feedback @@ -61,12 +60,7 @@ export default Route.extend(ApplicationRouteMixin, { target: '_blank' }; - const brand = { - logo: isInternal ? '/assets/assets/images/wherehows-logo.png' : '', - avatarUrl: isInternal ? avatarUrl.replace('[username]', userName) : '/assets/assets/images/default_avatar.png' - }; - - return { feedbackMail, brand, showStagingBanner, showLiveDataWarning }; + return { feedbackMail, showStagingBanner, showLiveDataWarning, avatar }; }, /** diff --git a/wherehows-web/app/routes/datasets/dataset.ts b/wherehows-web/app/routes/datasets/dataset.ts index bc80d393e9..807c8d4463 100644 --- a/wherehows-web/app/routes/datasets/dataset.ts +++ b/wherehows-web/app/routes/datasets/dataset.ts @@ -99,7 +99,7 @@ export default class DatasetRoute extends Route { shouldShowDatasetLineage: getConfig('shouldShowDatasetLineage'), shouldShowDatasetHealth: getConfig('shouldShowDatasetHealth'), wikiLinks: getConfig('wikiLinks'), - avatarEntityProps: getConfig('avatarEntityProps') + avatarEntityProps: getConfig('userEntityProps') }); } diff --git a/wherehows-web/app/styles/components/_all.scss b/wherehows-web/app/styles/components/_all.scss index 03d5fad0c9..c9f66bdd27 100644 --- a/wherehows-web/app/styles/components/_all.scss +++ b/wherehows-web/app/styles/components/_all.scss @@ -27,6 +27,7 @@ @import 'dataset-relationships/all'; @import 'visualization/all'; @import 'dataset-health/all'; +@import 'hotkey/all'; @import 'nacho/nacho-button'; @import 'nacho/nacho-global-search'; diff --git a/wherehows-web/app/styles/components/_navbar.scss b/wherehows-web/app/styles/components/_navbar.scss index f507c487bc..ada1da8ff0 100644 --- a/wherehows-web/app/styles/components/_navbar.scss +++ b/wherehows-web/app/styles/components/_navbar.scss @@ -118,3 +118,12 @@ $navbar-transition-speed: $banner-animation-speed; border-radius: 0; } } + +/** + * Adds styles for navigation bar avatar image + */ +.navbar-avatar-image { + &#{&} { + @include round-image(item-spacing(6)); + } +} diff --git a/wherehows-web/app/styles/components/avatar/_avatar.scss b/wherehows-web/app/styles/components/avatar/_avatar.scss index 6a77a6c1ab..c1890c046d 100644 --- a/wherehows-web/app/styles/components/avatar/_avatar.scss +++ b/wherehows-web/app/styles/components/avatar/_avatar.scss @@ -1,14 +1,8 @@ -$avatar-size: 18px; - /// Shared declaration for avatar rounding proportions @mixin round-avatar { @include round-image(item-spacing(7)); } -.user-avatar { - @include round-image($avatar-size); -} - .avatar-container { display: flex; justify-content: flex-end; diff --git a/wherehows-web/app/styles/components/comments/_comment-item.scss b/wherehows-web/app/styles/components/comments/_comment-item.scss index f2980c2538..6eb1689723 100644 --- a/wherehows-web/app/styles/components/comments/_comment-item.scss +++ b/wherehows-web/app/styles/components/comments/_comment-item.scss @@ -12,12 +12,6 @@ } } - /// Overrides the nested user avatar class - .user-avatar { - width: item-spacing(6); - height: item-spacing(6); - } - &__header { display: flex; align-items: center; diff --git a/wherehows-web/app/styles/components/dataset-author/_suggested-owners.scss b/wherehows-web/app/styles/components/dataset-author/_suggested-owners.scss index 6007baa114..ffb4df7fc5 100644 --- a/wherehows-web/app/styles/components/dataset-author/_suggested-owners.scss +++ b/wherehows-web/app/styles/components/dataset-author/_suggested-owners.scss @@ -6,11 +6,6 @@ overflow: hidden; cursor: default; - .user-avatar { - height: 36px; - width: 36px; - } - &__header { margin: 0; font-weight: 400; diff --git a/wherehows-web/app/styles/components/hotkey/_all.scss b/wherehows-web/app/styles/components/hotkey/_all.scss new file mode 100644 index 0000000000..bfd1edf376 --- /dev/null +++ b/wherehows-web/app/styles/components/hotkey/_all.scss @@ -0,0 +1 @@ +@import 'global-hotkey'; diff --git a/wherehows-web/app/styles/components/hotkey/_global-hotkey.scss b/wherehows-web/app/styles/components/hotkey/_global-hotkey.scss new file mode 100644 index 0000000000..9ad4fafc22 --- /dev/null +++ b/wherehows-web/app/styles/components/hotkey/_global-hotkey.scss @@ -0,0 +1,3 @@ +.global-hotkey { + outline: none; +} diff --git a/wherehows-web/app/templates/components/comment/comment-item.hbs b/wherehows-web/app/templates/components/comment/comment-item.hbs index f4b63fb729..91f9e1dd4c 100644 --- a/wherehows-web/app/templates/components/comment/comment-item.hbs +++ b/wherehows-web/app/templates/components/comment/comment-item.hbs @@ -1,6 +1,4 @@
- {{user-avatar userName=comment.authorUserName}} -
{{comment.authorName}} diff --git a/wherehows-web/app/templates/components/dataset-aclaccess.hbs b/wherehows-web/app/templates/components/dataset-aclaccess.hbs index 700b58a230..11275d87ce 100644 --- a/wherehows-web/app/templates/components/dataset-aclaccess.hbs +++ b/wherehows-web/app/templates/components/dataset-aclaccess.hbs @@ -161,11 +161,11 @@

{{/unless}} - {{#if acls}} + {{#if aclsWithAvatarProps}} {{#dataset-table class="nacho-table nacho-table--stripped" - fields=acls + fields=aclsWithAvatarProps sortColumnWithName=sortColumnWithName filterBy=filterBy as |table| }} @@ -191,7 +191,7 @@ {{#each (sort-by table.sortBy table.data) as |field|}} {{#body.row as |row|}} {{#row.cell}} - {{user-avatar userName=field.principal}} + {{avatars/avatar-image avatar=field.avatar}} {{field.principal}} {{/row.cell}} diff --git a/wherehows-web/app/templates/components/dataset-author.hbs b/wherehows-web/app/templates/components/dataset-author.hbs index 42ff0f8452..c317c791ac 100644 --- a/wherehows-web/app/templates/components/dataset-author.hbs +++ b/wherehows-web/app/templates/components/dataset-author.hbs @@ -1,75 +1,76 @@ - - {{#unless isOwnerInActive}} - {{user-avatar userName=owner.userName}} - {{/unless}} - - {{owner.userName}} - - {{#if isOwnerInActive}} - - - Inactive - - - {{/if}} - - - - {{owner.name}} - - - - {{owner.idType}} - - -{{!-- hides source column for confirmed owners--}} -{{#unless isOwnerMutable}} - +{{#let @owner.owner as |ownerRecord|}} - {{owner.source}} + {{#unless isOwnerInActive}} + {{avatars/avatar-image avatar=@owner.avatar}} + {{/unless}} + + {{ownerRecord.userName}} + + {{#if isOwnerInActive}} + + + Inactive + + + {{/if}} -{{/unless}} + + {{ownerRecord.name}} + - - {{ember-selector - class=(unless isOwnerMutable "nacho-select--hidden-state") - values=ownerTypes - selected=owner.type - disabled=(not isOwnerMutable) - selectionDidChange=(action "changeOwnerType") - }} - + + {{ownerRecord.idType}} + - - {{#if isOwnerMutable}} + {{!-- hides source column for confirmed owners--}} + {{#unless isOwnerMutable}} - + + {{ownerRecord.source}} + - {{else}} + {{/unless}} - {{#if isConfirmedSuggestedOwner}} + + {{ember-selector + class=(unless isOwnerMutable "nacho-select--hidden-state") + values=ownerTypes + selected=ownerRecord.type + disabled=(not isOwnerMutable) + selectionDidChange=(action "changeOwnerType") + }} + - - Added - + + {{#if isOwnerMutable}} + + {{else}} - + {{#if isConfirmedSuggestedOwner}} + + + Added + + + {{else}} + + + + {{/if}} {{/if}} - - {{/if}} - - + +{{/let}} diff --git a/wherehows-web/app/templates/components/dataset-authors.hbs b/wherehows-web/app/templates/components/dataset-authors.hbs index 1a653a2a6a..6df0c5c9eb 100644 --- a/wherehows-web/app/templates/components/dataset-authors.hbs +++ b/wherehows-web/app/templates/components/dataset-authors.hbs @@ -35,17 +35,17 @@ - {{#each confirmedOwners as |confirmedOwner|}} - + + {{#each confirmedOwnersWithAvatars as |confirmedOwnerWithAvatar|}} {{dataset-author - owner=confirmedOwner + owner=confirmedOwnerWithAvatar ownerTypes=ownerTypes removeOwner=(action "removeOwner") confirmSuggestedOwner=(action "confirmSuggestedOwner") updateOwnerType=(action "updateOwnerType") }} - - {{/each}} + {{/each}} + @@ -65,7 +65,7 @@
{{datasets/owners/suggested-owners - owners=systemGeneratedOwners + owners=systemGeneratedOwnersWithAvatars ownerTypes=ownerTypes commonOwners=commonOwners removeOwner=(action "removeOwner") diff --git a/wherehows-web/app/templates/components/datasets/containers/dataset-acl-access.hbs b/wherehows-web/app/templates/components/datasets/containers/dataset-acl-access.hbs index af86faedb0..5823df5e7d 100644 --- a/wherehows-web/app/templates/components/datasets/containers/dataset-acl-access.hbs +++ b/wherehows-web/app/templates/components/datasets/containers/dataset-acl-access.hbs @@ -8,6 +8,7 @@ {{dataset-aclaccess acls=acls aclMoreInfoLink=@aclMoreInfoLink + avatarProperties=avatarProperties jitAclContact=jitAclContact hasValidAclRequest=hasValidAclRequest userAclRequest=userAclRequest diff --git a/wherehows-web/app/templates/components/datasets/containers/dataset-ownership.hbs b/wherehows-web/app/templates/components/datasets/containers/dataset-ownership.hbs index b8a0885838..6ad9edae40 100644 --- a/wherehows-web/app/templates/components/datasets/containers/dataset-ownership.hbs +++ b/wherehows-web/app/templates/components/datasets/containers/dataset-ownership.hbs @@ -33,6 +33,7 @@ {{dataset-authors owners=owners suggestedOwners=suggestedOwners + avatarProperties=avatarProperties ownerTypes=ownerTypes setOwnershipRuleChange=setOwnershipRuleChange save=(action "saveOwnerChanges") diff --git a/wherehows-web/app/templates/components/datasets/owners/suggested-owner-card.hbs b/wherehows-web/app/templates/components/datasets/owners/suggested-owner-card.hbs index 68025a88b7..a0a8eff080 100644 --- a/wherehows-web/app/templates/components/datasets/owners/suggested-owner-card.hbs +++ b/wherehows-web/app/templates/components/datasets/owners/suggested-owner-card.hbs @@ -1,29 +1,30 @@ -
-
- {{user-avatar - class="suggested-owner-card__owner-info__profile__pic" - userName=owner.userName}} -
-
- {{owner.name}} -
-

- {{owner.userName}} -

+{{#let @owner.owner as |ownerRecord|}} +
+
+ {{avatars/avatar-image avatar=@owner.avatar class="suggested-owner-card__owner-info__profile__pic"}} + +
+
+ {{ownerRecord.name}} +
+

+ {{ownerRecord.userName}} +

+
-
-
- {{#if isConfirmedSuggestedOwner}} - {{fa-icon "check-circle-o" title="Added Owner" size="2"}} - Added - {{else}} - - {{/if}} -
-
-
- Source: {{owner.source}} -
\ No newline at end of file +
+ {{#if isConfirmedSuggestedOwner}} + {{fa-icon "check-circle-o" title="Added Owner" size="2"}} + Added + {{else}} + + {{/if}} +
+
+
+ Source: {{ownerRecord.source}} +
+{{/let}} \ No newline at end of file diff --git a/wherehows-web/app/templates/components/datasets/owners/suggested-owners.hbs b/wherehows-web/app/templates/components/datasets/owners/suggested-owners.hbs index 46af287e0b..a04ed57e79 100644 --- a/wherehows-web/app/templates/components/datasets/owners/suggested-owners.hbs +++ b/wherehows-web/app/templates/components/datasets/owners/suggested-owners.hbs @@ -8,7 +8,7 @@
{{#each facepileOwners as |owner|}} - {{user-avatar class="dataset-authors-suggested__info__facepile__avatar" userName=owner.userName}} + {{avatars/avatar-image avatar=owner.avatar class="dataset-authors-suggested__info__facepile__avatar"}} {{/each}}
diff --git a/wherehows-web/app/templates/components/user-avatar.hbs b/wherehows-web/app/templates/components/user-avatar.hbs deleted file mode 100644 index 7e219dd77f..0000000000 --- a/wherehows-web/app/templates/components/user-avatar.hbs +++ /dev/null @@ -1 +0,0 @@ -{{userName}} diff --git a/wherehows-web/app/templates/navbar.hbs b/wherehows-web/app/templates/navbar.hbs index c2c58120a9..59eb98b655 100644 --- a/wherehows-web/app/templates/navbar.hbs +++ b/wherehows-web/app/templates/navbar.hbs @@ -10,7 +10,7 @@ {{#link-to "index" class="navbar-brand"}}
- WhereHows Logo (Beta)
@@ -26,7 +26,7 @@