blob: 8e5be27142b56a050ca329daa34a499b604bc775 [file] [log] [blame]
Copybara854996b2021-09-07 19:36:02 +00001// Copyright 2019 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import {LitElement, html, css} from 'lit-element';
6
7import {connectStore} from 'reducers/base.js';
8import * as issueV0 from 'reducers/issueV0.js';
9import {EMPTY_FIELD_VALUE} from 'shared/issue-fields.js';
10import {SHARED_STYLES} from 'shared/shared-styles.js';
11
12
13const NULL_DISPLAY_NAME_VALUES = [EMPTY_FIELD_VALUE, 'a_deleted_user'];
14
15/**
16 * `<mr-user-link>`
17 *
18 * Displays a link to a user profile.
19 *
20 */
21export class MrUserLink extends connectStore(LitElement) {
22 /** @override */
23 static get styles() {
24 return [
25 SHARED_STYLES,
26 css`
27 :host {
28 display: inline-block;
29 white-space: nowrap;
30 }
31 i.inline-icon {
32 font-size: var(--chops-icon-font-size);
33 color: #B71C1C;
34 vertical-align: bottom;
35 cursor: pointer;
36 }
37 i.inline-icon-unseen {
38 color: var(--chops-purple-700);
39 }
40 i.material-icons[hidden] {
41 display: none;
42 }
43 .availability-notice {
44 color: #B71C1C;
45 font-weight: bold;
46 }
47 `,
48 ];
49 }
50
51 /** @override */
52 static get properties() {
53 return {
54 referencedUsers: {
55 type: Object,
56 },
57 showAvailabilityIcon: {
58 type: Boolean,
59 },
60 showAvailabilityText: {
61 type: Boolean,
62 },
63 userRef: {
64 type: Object,
65 attribute: 'userref',
66 },
67 };
68 }
69
70 /** @override */
71 constructor() {
72 super();
73 this.userRef = {};
74 this.referencedUsers = new Map();
75 this.showAvailabilityIcon = false;
76 this.showAvailabilityText = false;
77 }
78
79 /** @override */
80 stateChanged(state) {
81 this.referencedUsers = issueV0.referencedUsers(state);
82 }
83
84 /** @override */
85 render() {
86 const availability = this._getAvailability();
87 const userLink = this._getUserLink();
88 const user = this.referencedUsers.get(this.userRef.displayName) || {};
89 return html`
90 <link href="https://fonts.googleapis.com/icon?family=Material+Icons"
91 rel="stylesheet">
92 <i
93 id="availability-icon"
Adrià Vilanova Martínezac4a6442022-05-15 19:05:13 +020094 class=${"material-icons inline-icon ${user.last_visit_timestamp ? '': 'inline-icon-unseen'}"}
Copybara854996b2021-09-07 19:36:02 +000095 title="${availability}"
96 ?hidden="${!(this.showAvailabilityIcon && availability)}"
97 >schedule</i>
98 <a
99 id="user-link"
100 href="${userLink}"
101 title="${this.userRef.displayName}"
102 ?hidden="${!userLink}"
103 >${this.userRef.displayName}</a>
104 <span
105 id="user-text"
106 ?hidden="${userLink}"
107 >${this.userRef.displayName}</span>
108 <div
109 id="availability-text"
110 class="availability-notice"
111 title="${availability}"
112 ?hidden="${!(this.showAvailabilityText && availability)}"
113 >${availability}</div>
114 `;
115 }
116
117 _getAvailability() {
118 if (!this.userRef || !this.referencedUsers) return '';
119 const user = this.referencedUsers.get(this.userRef.displayName) || {};
120 return user.availability;
121 }
122
123 _getUserLink() {
124 if (!this.userRef || !this.userRef.displayName ||
125 NULL_DISPLAY_NAME_VALUES.includes(this.userRef.displayName)) return '';
126 return `/u/${this.userRef.userId || this.userRef.displayName}`;
127 }
128}
129customElements.define('mr-user-link', MrUserLink);