diff --git a/public/components/views/home/home.js b/public/components/views/home/home.js
index d40ee3a6..5b678b99 100644
--- a/public/components/views/home/home.js
+++ b/public/components/views/home/home.js
@@ -11,7 +11,7 @@ import { EVENTS } from "../../../core/events.js";
import { fetchScorecardData, getScorecardLink } from "../../../common/scorecard.js";
// Import Components
-import { Maintainers } from "./maintainers/maintainers.js";
+import "./maintainers/maintainers.js";
import "./report/report.js";
// CONSTANTS
@@ -332,8 +332,15 @@ export class HomeView {
}
generateMaintainers() {
- new Maintainers(this.secureDataSet, this.nsn)
- .render();
+ const maintainers = document.createElement("nsecure-maintainers");
+ maintainers.secureDataSet = this.secureDataSet;
+ maintainers.nsn = this.nsn;
+ maintainers.theme = this.secureDataSet.theme;
+ maintainers.options = {
+ maximumMaintainers: 5
+ };
+ const pannel = document.getElementById("pannel-right");
+ pannel.prepend(maintainers);
}
generateModuleTypes() {
diff --git a/public/components/views/home/maintainers/maintainers.css b/public/components/views/home/maintainers/maintainers.css
deleted file mode 100644
index 99448906..00000000
--- a/public/components/views/home/maintainers/maintainers.css
+++ /dev/null
@@ -1,85 +0,0 @@
-.home--maintainers {
- display: flex;
- flex-wrap: wrap;
- margin-left: -10px;
- margin-top: -10px;
-}
-
-.home--maintainers>.person {
- height: 65px;
- flex-basis: 330px;
- background: linear-gradient(to bottom, rgb(255 255 255) 0%, rgb(245 252 255) 100%);
- display: flex;
- position: relative;
- box-sizing: border-box;
- border-radius: 4px;
- overflow: hidden;
- margin-left: 10px;
- margin-top: 10px;
- box-shadow: 1px 1px 4px 0 #271e792b;
- color: #546884;
- flex-grow: 1;
-}
-
-body.dark .home--maintainers>.person {
- color: white;
- background: var(--dark-theme-primary-color);
-}
-
-.home--maintainers> .highlighted{
- background: linear-gradient(to bottom, rgb(230 240 250) 0%, rgb(220 235 245) 100%);
-}
-
-body.dark .home--maintainers > .highlighted {
- background: linear-gradient(to right, rgb(11 3 31) 0%, rgb(46 10 10 / 80%) 100%);
-}
-
-.home--maintainers>.person:hover {
- border-color: var(--secondary-darker);
- cursor: pointer;
-}
-
-.home--maintainers>.person>img {
- width: 65px;
- flex-shrink: 0;
-}
-
-.home--maintainers>.person>i {
- margin-right: 10px;
- display: flex;
- align-items: center;
- color: #1976D2;
- font-size: 18px;
-}
-
-.home--maintainers>.person>.whois {
- display: flex;
- flex-direction: column;
- justify-content: center;
- margin-left: 10px;
- font-size: 15px;
- font-family: mononoki;
- flex-grow: 1;
- margin-right: 10px;
-}
-
-.home--maintainers>.person>.whois>span {
- color: var(--secondary-darker);
- font-size: 14px;
- margin-top: 5px;
- font-family: monospace;
-}
-
-.home--maintainers>.person>div.packagescount {
- display: flex;
- align-items: center;
- font-family: mononoki;
- font-size: 18px;
- margin-right: 15px;
- flex-basis: 40px;
- flex-shrink: 0;
-}
-
-.home--maintainers>.person>div.packagescount>i {
- margin-right: 4px;
-}
diff --git a/public/components/views/home/maintainers/maintainers.js b/public/components/views/home/maintainers/maintainers.js
index 4d6f1dd3..2ff6d423 100644
--- a/public/components/views/home/maintainers/maintainers.js
+++ b/public/components/views/home/maintainers/maintainers.js
@@ -2,114 +2,302 @@
import { LitElement, html, css, nothing } from "lit";
import { when } from "lit/directives/when.js";
import { repeat } from "lit/directives/repeat.js";
+import { classMap } from "lit/directives/class-map.js";
// Import Internal Dependencies
import * as utils from "../../../../common/utils.js";
import "../../../expandable/expandable.js";
import { EVENTS } from "../../../../core/events.js";
import "../../../icon/icon.js";
-import avatarURL from "../../../../img/avatar-default.png";
-
-export class Maintainers {
- static whois(name, email) {
- const childs = [
- utils.createDOMElement("p", { text: name })
- ];
- if (typeof email === "string") {
- childs.push(utils.createDOMElement("span", { text: email }));
- }
+import "../../../npm-avatar/npm-avatar.js";
+
+export class Maintainers extends LitElement {
+ static styles = css`
+
+.module {
+ display: flex;
+ flex-direction: column;
+}
+
+.title{
+ height: 34px;
+ display: flex;
+ background: rgb(55 34 175);
+ background: linear-gradient(-45deg, rgb(55 34 175 / 100%) 0%,
+ rgb(55 34 175 / 100%) 48%, rgb(90 68 218 / 100%) 75%, rgb(90 68 218 / 100%) 100%);
+ background: linear-gradient(-45deg, rgb(55 34 175 / 100%) 0%,
+ rgb(55 34 175 / 100%) 48%, rgb(90 68 218 / 100%) 75%, rgb(90 68 218 / 100%) 100%);
+ background: linear-gradient(135deg, rgb(55 34 175 / 100%) 0%,
+ rgb(55 34 175 / 100%) 48%, rgb(90 68 218 / 100%) 75%, rgb(90 68 218 / 100%) 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#3722af', endColorstr='#5a44da', GradientType=1);
+ margin-bottom: 10px;
+ box-sizing: border-box;
+ border-radius: 4px;
+ padding: 0 10px;
+ align-items: center;
+ font-family: mononoki;
+ text-shadow: 1px 1px 10px #05a0ff6b;
+}
- return utils.createDOMElement("div", {
- className: "whois", childs
- });
+ .users {
+ width: fit-content;
+ transform: scale(2);
+ display: flex;
+ padding: 0px;
+ justify-content: center;
+ align-items: center;
+ margin: 0px;
+ margin-right: 6px;
+ margin-left: 15px;
+ margin-top: 18px;
+}
+
+.link {
+ display: flex;
+ align-items: center;
+ margin-right: 10px;
+}
+
+.link nsecure-icon {
+ color: rgb(25, 118, 210);
+}
+
+.count{
+width: 16px;
+ height: 16px;
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: #FDD835;
+ margin-left: 10px;
+ color: #263238;
+ font-size: 12px;
+ font-weight: bold;
+ padding: 4px;
+}
+
+ .home--maintainers {
+ display: flex;
+ flex-wrap: wrap;
+ margin-left: -10px;
+ margin-top: -10px;
+}
+
+.name {
+ margin: 0px;
+}
+
+.home--maintainers>.person {
+ height: 65px;
+ flex-basis: 330px;
+ background: linear-gradient(to bottom, rgb(255 255 255) 0%, rgb(245 252 255) 100%);
+ display: flex;
+ position: relative;
+ box-sizing: border-box;
+ border-radius: 4px;
+ overflow: hidden;
+ margin-left: 10px;
+ margin-top: 10px;
+ box-shadow: 1px 1px 4px 0 #271e792b;
+ color: #546884;
+ flex-grow: 1;
+}
+
+.dark .home--maintainers>.person {
+ color: white;
+ background: var(--dark-theme-primary-color);
+}
+
+.home--maintainers> .highlighted{
+ background: linear-gradient(to bottom, rgb(230 240 250) 0%, rgb(220 235 245) 100%);
+}
+
+.dark .home--maintainers > .highlighted {
+ background: linear-gradient(to right, rgb(11 3 31) 0%, rgb(46 10 10 / 80%) 100%);
+}
+
+.home--maintainers>.person:hover {
+ border-color: var(--secondary-darker);
+ cursor: pointer;
+}
+
+.home--maintainers>.person>nsecure-icon {
+ margin-right: 10px;
+ display: flex;
+ align-items: center;
+ color: #1976D2;
+ font-size: 18px;
+}
+
+.home--maintainers>.person>.whois {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ margin-left: 10px;
+ font-size: 15px;
+ font-family: mononoki;
+ flex-grow: 1;
+ margin-right: 10px;
+}
+
+.home--maintainers>.person>.whois>span {
+ color: var(--secondary-darker);
+ font-size: 14px;
+ margin-top: 5px;
+ font-family: monospace;
+}
+
+.home--maintainers>.person>div.packagescount {
+ display: flex;
+ align-items: center;
+ font-family: mononoki;
+ font-size: 18px;
+ margin-right: 15px;
+ flex-basis: 40px;
+ flex-shrink: 0;
+}
+
+.home--maintainers>.person>div.packagescount>nsecure-icon {
+ margin-right: 4px;
+}
+`;
+
+ static properties = {
+ secureDataSet: { type: Object },
+ nsn: { type: Object },
+ options: { type: Object },
+ isClosed: { type: Boolean },
+ theme: { type: String }
+ };
+
+ constructor() {
+ super();
+ this.isClosed = true;
+ this.settingsChanged = ({ detail: { theme } }) => {
+ if (theme !== this.theme) {
+ this.theme = theme;
+ }
+ };
}
- constructor(secureDataSet, nsn, options = {}) {
- const { maximumMaintainers = 5 } = options;
+ connectedCallback() {
+ super.connectedCallback();
+ window.addEventListener(EVENTS.SETTINGS_SAVED, this.settingsChanged);
+ }
- this.secureDataSet = secureDataSet;
- this.nsn = nsn;
- this.maximumMaintainers = maximumMaintainers;
+ disconnectedCallback() {
+ window.removeEventListener(EVENTS.SETTINGS_SAVED, this.settingsChanged);
+ super.disconnectedCallback();
}
render() {
const authors = this.#highlightContacts([...this.secureDataSet.authors.entries()]
.sort((left, right) => right[1].packages.size - left[1].packages.size));
- document.getElementById("authors-count").innerHTML = authors.length;
- const maintainers = document.querySelector(".home--maintainers");
- this.generate(authors, maintainers);
- }
+ const { maximumMaintainers } = this.options;
- #highlightContacts(authors) {
- const highlightedAuthors = authors
- .filter(([_, contact]) => this.secureDataSet.isHighlighted(contact));
+ const hideItems = authors.length > maximumMaintainers;
- const authorsRest = authors.filter(([_, contact]) => !this.secureDataSet.isHighlighted(contact));
+ const numOfMaintainers = this.isClosed ? maximumMaintainers : authors.length;
- return [...highlightedAuthors, ...authorsRest];
- }
+ const visibleAuthors = hideItems ? authors.slice(0, numOfMaintainers) : authors;
- generate(authors, maintainers) {
- const fragment = document.createDocumentFragment();
- const hideItems = authors.length > this.maximumMaintainers;
+ const i18n = window.i18n[utils.currentLang()];
- for (let id = 0; id < authors.length; id++) {
- const [name, data] = authors[id];
- if (typeof name === "undefined") {
- continue;
- }
- const { packages, email, url = null } = data;
-
- const hasURL = typeof url === "string";
- const person = utils.createDOMElement("div", {
- className: "person",
- childs: [
- utils.createAvatarImageElementForAuthor(data),
- Maintainers.whois(name, email),
- hasURL ? utils.createDOMElement("i", { className: "icon-link" }) : null,
- utils.createDOMElement("div", {
- className: "packagescount",
- childs: [
- utils.createDOMElement("i", { className: "icon-cube" }),
- utils.createDOMElement("p", { text: packages.size })
- ]
- })
- ]
- });
- if (this.secureDataSet.isHighlighted(data)) {
- person.classList.add("highlighted");
- }
- if (hideItems && id >= this.maximumMaintainers) {
- person.classList.add("hidden");
- }
- person.addEventListener("click", () => {
- // TODO: close package info?
- const popupMaintainer = document.createElement("popup-maintainer");
- popupMaintainer.data = data;
- popupMaintainer.theme = this.secureDataSet.theme;
- popupMaintainer.nsn = this.nsn;
- popupMaintainer.name = name;
- window.dispatchEvent(new CustomEvent(EVENTS.MODAL_OPENED, {
- detail: {
- content: popupMaintainer
- }
- }));
- });
+ return html`
+
+
+
+
${i18n.home.maintainers}
+
${authors.length}
+
+
+
+ ${this.#generateMaintainers(visibleAuthors)}
+
+
+ ${when(hideItems,
+ () => html`
{
+ this.isClosed = !this.isClosed;
+ }}>`,
+ () => nothing)}
+
+
+ `;
+ }
- fragment.appendChild(person);
+ #generateMaintainers(authors) {
+ return html`
+ ${repeat(authors.filter(([name]) => typeof name != "undefined"),
+ (author) => author,
+ ([name, data]) => {
+ const { packages, email, url = null, npmAvatar } = data;
+ const personClasses = {
+ person: true,
+ highlighted: this.secureDataSet.isHighlighted(data)
+ };
+
+ return html`
+
{
+ // TODO: close package info?
+ const popupMaintainer = document.createElement("popup-maintainer");
+ popupMaintainer.data = data;
+ popupMaintainer.theme = this.secureDataSet.theme;
+ popupMaintainer.nsn = this.nsn;
+ popupMaintainer.name = name;
+ window.dispatchEvent(new CustomEvent(EVENTS.MODAL_OPENED, {
+ detail: {
+ content: popupMaintainer
+ }
+ }));
+ }}
+ class="${classMap(personClasses)}">
+
+
+
${name}
+ ${when(
+ typeof email === "string",
+ () => html`
${email}`,
+ () => nothing
+ )}
+
+ ${when(
+ typeof url === "string",
+ () => html`
+
+ `
+ )}
+
+
+ `;
+ }
+ )
}
+`;
+ }
- maintainers.appendChild(fragment);
- if (hideItems) {
- const expandableSpan = document.createElement("expandable-span");
- expandableSpan.onToggle = (expandable) => utils.toggle(expandable, maintainers, this.maximumMaintainers);
+ #highlightContacts(authors) {
+ const highlightedAuthors = authors
+ .filter(([_, contact]) => this.secureDataSet.isHighlighted(contact));
- maintainers.appendChild(expandableSpan);
- }
+ const authorsRest = authors.filter(([_, contact]) => !this.secureDataSet.isHighlighted(contact));
+
+ return [...highlightedAuthors, ...authorsRest];
}
}
+customElements.define("nsecure-maintainers", Maintainers);
+
export class PopupMaintainer extends LitElement {
static styles = css`
.maintainers--popup {
@@ -138,10 +326,6 @@ export class PopupMaintainer extends LitElement {
box-shadow: 2px 2px 6px 0 #00000012;
}
-.maintainers--popup>.header>.avatar>img {
- width: 80px;
-}
-
.maintainers--popup>.header>.informations {
display: flex;
flex-direction: column;
@@ -346,18 +530,9 @@ export class PopupMaintainer extends LitElement {