| 
									
										
										
										
											2020-01-29 16:48:24 -08:00
										 |  |  | import Component from '@ember/component'; | 
					
						
							|  |  |  | // @ts-ignore: Ignore import of compiled template
 | 
					
						
							|  |  |  | import template from '../../../templates/components/user/containers/user-main'; | 
					
						
							|  |  |  | import { layout, tagName } from '@ember-decorators/component'; | 
					
						
							|  |  |  | import { task } from 'ember-concurrency'; | 
					
						
							|  |  |  | import { inject as service } from '@ember/service'; | 
					
						
							|  |  |  | import { ETaskPromise } from '@datahub/utils/types/concurrency'; | 
					
						
							|  |  |  | import { PersonEntity } from '@datahub/data-models/entity/person/person-entity'; | 
					
						
							|  |  |  | import DataModelsService from '@datahub/data-models/services/data-models'; | 
					
						
							|  |  |  | import { IPersonEntitySpecificConfigs } from '@datahub/data-models/entity/person/render-props'; | 
					
						
							| 
									
										
										
										
											2020-08-26 15:44:50 -07:00
										 |  |  | import { IEntityRenderProps, ITabProperties } from '@datahub/data-models/types/entity/rendering/entity-render-props'; | 
					
						
							| 
									
										
										
										
											2020-01-29 16:48:24 -08:00
										 |  |  | import { set, computed, action } from '@ember/object'; | 
					
						
							|  |  |  | import { containerDataSource } from '@datahub/utils/api/data-source'; | 
					
						
							|  |  |  | import CurrentUser from '@datahub/shared/services/current-user'; | 
					
						
							|  |  |  | import RouterService from '@ember/routing/router-service'; | 
					
						
							|  |  |  | import { PersonTab, getPersonTabPropertiesFor } from '@datahub/data-models/constants/entity/person/tabs'; | 
					
						
							| 
									
										
										
										
											2020-11-09 12:17:51 -08:00
										 |  |  | import { generateTabId } from '@datahub/entities/utils/tabownership'; | 
					
						
							| 
									
										
										
										
											2020-01-29 16:48:24 -08:00
										 |  |  | import { DataModelEntity } from '@datahub/data-models/constants/entity'; | 
					
						
							|  |  |  | import { capitalize } from '@ember/string'; | 
					
						
							|  |  |  | import { humanize } from 'ember-cli-string-helpers/helpers/humanize'; | 
					
						
							| 
									
										
										
										
											2020-08-26 15:44:50 -07:00
										 |  |  | import { IConfigurator } from '@datahub/shared/types/configurator/configurator'; | 
					
						
							|  |  |  | import { SocialAction } from '@datahub/data-models/constants/entity/person/social-actions'; | 
					
						
							|  |  |  | import { pastTense } from '@datahub/utils/helpers/past-tense'; | 
					
						
							|  |  |  | import { pendingSocialActions } from '@datahub/shared/constants/social/pending-actions'; | 
					
						
							|  |  |  | import { isOwnableEntity } from '@datahub/data-models/utils/ownership'; | 
					
						
							| 
									
										
										
										
											2020-01-29 16:48:24 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | @layout(template) | 
					
						
							|  |  |  | @tagName('') | 
					
						
							|  |  |  | @containerDataSource<UserMainContainer>('getContainerDataTask', ['personUrn']) | 
					
						
							|  |  |  | export default class UserMainContainer extends Component { | 
					
						
							| 
									
										
										
										
											2020-08-26 15:44:50 -07:00
										 |  |  |   /** | 
					
						
							|  |  |  |    * Injection of the configurator service to read relevant user and social action configs | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   @service | 
					
						
							|  |  |  |   configurator!: IConfigurator; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-29 16:48:24 -08:00
										 |  |  |   /** | 
					
						
							|  |  |  |    * Injection of data modeling service to get the current implementation of the user's person | 
					
						
							|  |  |  |    * entity. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   @service('data-models') | 
					
						
							|  |  |  |   dataModels!: DataModelsService; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Injects the current user service to help us inform the rest of our children whether or not the | 
					
						
							|  |  |  |    * person whose context fills this component is the same as the current user logged into our | 
					
						
							|  |  |  |    * application | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   @service('current-user') | 
					
						
							|  |  |  |   currentUser!: CurrentUser; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Inject the router as there are some transitions that we need to do | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   @service | 
					
						
							|  |  |  |   router!: RouterService; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * A given user id or urn from the route's query params | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   personUrn?: string; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * The currently active tab under the user main profile page | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   tabSelected?: string; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Assigned by the data fetching task, is the context of the person entity given to all contained | 
					
						
							|  |  |  |    * components | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   entity?: PersonEntity; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Rendering properties to tell our contained components how to determine what to show and other | 
					
						
							|  |  |  |    * configurable behaviors | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   renderProps?: IPersonEntitySpecificConfigs & IEntityRenderProps; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Calls the person entity model to get the data necessary to populate the entity header | 
					
						
							|  |  |  |    * component on the person entity profile page | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   @(task(function*(this: UserMainContainer): IterableIterator<Promise<PersonEntity | void>> { | 
					
						
							|  |  |  |     const { renderProps, personUrn, dataModels } = this; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const PersonEntityClass = dataModels.getModel(PersonEntity.displayName); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (personUrn) { | 
					
						
							|  |  |  |       const entity = yield dataModels.createInstance(PersonEntity.displayName, personUrn); | 
					
						
							|  |  |  |       set(this, 'entity', entity); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!renderProps) { | 
					
						
							| 
									
										
										
										
											2020-08-26 15:44:50 -07:00
										 |  |  |       set(this, 'renderProps', this.userProfileTabs(PersonEntityClass.allRenderProps)); | 
					
						
							| 
									
										
										
										
											2020-01-29 16:48:24 -08:00
										 |  |  |     } | 
					
						
							|  |  |  |   }).restartable()) | 
					
						
							|  |  |  |   getContainerDataTask!: ETaskPromise<void>; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-26 15:44:50 -07:00
										 |  |  |   /** | 
					
						
							|  |  |  |    * Generate the user profile tabs that are available for this entity | 
					
						
							|  |  |  |    * @param allRenderProps | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   userProfileTabs(allRenderProps: typeof PersonEntity['allRenderProps']): typeof PersonEntity['allRenderProps'] { | 
					
						
							|  |  |  |     return this.appendSocialTabs(this.appendOwnershipTab(allRenderProps)); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-29 16:48:24 -08:00
										 |  |  |   /** | 
					
						
							|  |  |  |    * Will append the dynamically generated ownership tabs to the the renderProps | 
					
						
							|  |  |  |    * @param allRenderProps render props for person | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   appendOwnershipTab(allRenderProps: typeof PersonEntity['allRenderProps']): typeof PersonEntity['allRenderProps'] { | 
					
						
							|  |  |  |     const { dataModels } = this; | 
					
						
							|  |  |  |     const unGuardedEntities = dataModels.guards.unGuardedEntities; | 
					
						
							| 
									
										
										
										
											2020-08-26 15:44:50 -07:00
										 |  |  |     const ownershipEntities = unGuardedEntities.filter(isOwnableEntity).map( | 
					
						
							|  |  |  |       (entity: DataModelEntity): ITabProperties => ({ | 
					
						
							|  |  |  |         id: generateTabId(entity), | 
					
						
							|  |  |  |         title: capitalize(humanize([entity.displayName])), | 
					
						
							|  |  |  |         contentComponent: 'user/containers/tab-content/entity-ownership', | 
					
						
							|  |  |  |         lazyRender: true | 
					
						
							|  |  |  |       }) | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return { | 
					
						
							|  |  |  |       ...allRenderProps, | 
					
						
							|  |  |  |       userProfilePage: { | 
					
						
							|  |  |  |         ...allRenderProps.userProfilePage, | 
					
						
							|  |  |  |         tablistMenuProperties: { | 
					
						
							|  |  |  |           ...allRenderProps.userProfilePage.tablistMenuProperties, | 
					
						
							|  |  |  |           [PersonTab.UserOwnership]: [...ownershipEntities] | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Will dynamically append the number of social action list tabs to the render props based on the | 
					
						
							|  |  |  |    * available social actions (i.e. total number of actions minus those that are currently flag | 
					
						
							|  |  |  |    * guarded in our configs) | 
					
						
							|  |  |  |    * @param allRenderProps render props for person | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   appendSocialTabs(allRenderProps: typeof PersonEntity['allRenderProps']): typeof PersonEntity['allRenderProps'] { | 
					
						
							|  |  |  |     const { configurator } = this; | 
					
						
							|  |  |  |     const showSocialActions = configurator.getConfig('showSocialActions', { useDefault: true, default: false }); | 
					
						
							|  |  |  |     const showPendingSocialActions = configurator.getConfig('showPendingSocialActions', { | 
					
						
							|  |  |  |       useDefault: true, | 
					
						
							|  |  |  |       default: false | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!showSocialActions) { | 
					
						
							|  |  |  |       return allRenderProps; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const socialActions = [SocialAction.LIKE]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const unguardedSocialActions = showPendingSocialActions | 
					
						
							|  |  |  |       ? [...socialActions, ...pendingSocialActions] | 
					
						
							|  |  |  |       : [...socialActions]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const socialActionTabs = unguardedSocialActions.map(action => { | 
					
						
							|  |  |  |       const [baseTabProperties] = getPersonTabPropertiesFor([PersonTab.UserSocialActionList]); | 
					
						
							|  |  |  |       return { | 
					
						
							|  |  |  |         ...baseTabProperties, | 
					
						
							|  |  |  |         id: `${baseTabProperties.id}-${action}`, | 
					
						
							|  |  |  |         title: `${capitalize(pastTense([action]))} Entities` | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2020-01-29 16:48:24 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return { | 
					
						
							|  |  |  |       ...allRenderProps, | 
					
						
							|  |  |  |       userProfilePage: { | 
					
						
							|  |  |  |         ...allRenderProps.userProfilePage, | 
					
						
							|  |  |  |         tablistMenuProperties: { | 
					
						
							|  |  |  |           ...allRenderProps.userProfilePage.tablistMenuProperties, | 
					
						
							| 
									
										
										
										
											2020-08-26 15:44:50 -07:00
										 |  |  |           [PersonTab.UserLists]: [ | 
					
						
							|  |  |  |             ...(allRenderProps.userProfilePage.tablistMenuProperties[PersonTab.UserLists] || []), | 
					
						
							|  |  |  |             ...socialActionTabs | 
					
						
							|  |  |  |           ] | 
					
						
							| 
									
										
										
										
											2020-01-29 16:48:24 -08:00
										 |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Flags whether the currently logged in user is the same as the person whose entity is the | 
					
						
							|  |  |  |    * context given to this container | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2020-08-26 15:44:50 -07:00
										 |  |  |   @computed('entity', 'currentUser.entity') | 
					
						
							| 
									
										
										
										
											2020-01-29 16:48:24 -08:00
										 |  |  |   get isCurrentUser(): boolean { | 
					
						
							|  |  |  |     const { currentUser, entity } = this; | 
					
						
							| 
									
										
										
										
											2020-08-26 15:44:50 -07:00
										 |  |  |     const loggedInUser = currentUser.entity || null; | 
					
						
							| 
									
										
										
										
											2020-01-29 16:48:24 -08:00
										 |  |  |     const contextUser = (entity && entity.username) || ''; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-26 15:44:50 -07:00
										 |  |  |     return !!loggedInUser && loggedInUser.username === contextUser; | 
					
						
							| 
									
										
										
										
											2020-01-29 16:48:24 -08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Handles user generated tab selection action by transitioning to specified route | 
					
						
							|  |  |  |    * @param {Tabs} tabSelected - the newly selected tab | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   @action | 
					
						
							|  |  |  |   tabSelectionChanged(tabSelected: string): void { | 
					
						
							|  |  |  |     // if the tab selection is not same as current, transition
 | 
					
						
							|  |  |  |     if (this.tabSelected !== tabSelected) { | 
					
						
							|  |  |  |       const { router, personUrn } = this; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       router.transitionTo(router.currentRouteName, personUrn || '', tabSelected); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } |