diff --git a/.locker/pom.xml b/.locker/pom.xml index 5bd6767..f8ce982 100644 --- a/.locker/pom.xml +++ b/.locker/pom.xml @@ -5,7 +5,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 io.mvnpm - 3.0.25-SNAPSHOT + 3.0.26-SNAPSHOT mvnpm-locker pom diff --git a/pom.xml b/pom.xml index 6bdedb6..50bad3b 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.mvnpm mvnpm - 3.0.25-SNAPSHOT + 3.0.26-SNAPSHOT mvnpm Maven on NPM https://mvnpm.org/ @@ -184,6 +184,27 @@ codeblock 1.0.6 + + + org.mvnpm + marked + 12.0.0 + runtime + + + + org.mvnpm.at.quarkus-webcomponents + card + 1.0.0 + runtime + + + + org.mvnpm.at.quarkus-webcomponents + badge + 1.0.0 + runtime + io.quarkus diff --git a/src/main/java/io/mvnpm/file/FileUtil.java b/src/main/java/io/mvnpm/file/FileUtil.java index 08cbfea..198962e 100644 --- a/src/main/java/io/mvnpm/file/FileUtil.java +++ b/src/main/java/io/mvnpm/file/FileUtil.java @@ -163,7 +163,7 @@ public static boolean createAsc(Path localFilePath, boolean force) { try { Process process = Runtime.getRuntime().exec(GPG_COMMAND + localFilePath.toString()); // Set a timeout of 10 seconds - long timeout = 10; + long timeout = 20; boolean processFinished = process.waitFor(timeout, TimeUnit.SECONDS); if (!processFinished) { diff --git a/src/main/java/io/mvnpm/npm/NpmRegistryFacade.java b/src/main/java/io/mvnpm/npm/NpmRegistryFacade.java index 7d1f470..cd65394 100644 --- a/src/main/java/io/mvnpm/npm/NpmRegistryFacade.java +++ b/src/main/java/io/mvnpm/npm/NpmRegistryFacade.java @@ -61,7 +61,7 @@ public io.mvnpm.npm.model.Package getPackage(String project, String version) { public SearchResults search(String term, int page) { if (page < 0) page = 1; - Response response = npmRegistryClient.search(term, ITEMS_PER_PAGE, page - 1, 1.0, 0.0, 0.0); + Response response = npmRegistryClient.search(term, ITEMS_PER_PAGE, page - 1, 0.0, 0.0, 1.0); if (response.getStatus() < 300) { return response.readEntity(SearchResults.class); } else { diff --git a/src/main/resources/web/app/mvnpm-home.ts b/src/main/resources/web/app/mvnpm-home.ts index 900540d..d997a31 100644 --- a/src/main/resources/web/app/mvnpm-home.ts +++ b/src/main/resources/web/app/mvnpm-home.ts @@ -1,5 +1,6 @@ import { LitElement, html, css} from 'lit'; import { customElement, state } from 'lit/decorators.js'; +import { unsafeHTML } from 'lit/directives/unsafe-html.js'; import '@vaadin/form-layout'; import '@vaadin/text-field'; import '@vaadin/combo-box'; @@ -13,7 +14,10 @@ import '@vaadin/progress-bar'; import '@vaadin/tabs'; import '@vaadin/tabsheet'; import '@quarkus-webcomponents/codeblock'; +import '@quarkus-webcomponents/card'; +import '@quarkus-webcomponents/badge'; import { Notification } from '@vaadin/notification'; +import { marked } from 'marked'; interface Coordinates { name: string; @@ -102,14 +106,6 @@ export class MvnpmHome extends LitElement { gap: 10px; } - .useBlock{ - display: flex; - flex-direction: column; - padding: 15px; - gap: 10px; - border-left: 1px solid var(--lumo-contrast-10pct); - width: 50%; - } qui-code-block { width: 100%; } @@ -171,6 +167,8 @@ export class MvnpmHome extends LitElement { display: flex; justify-content: space-evenly; width: 100%; + justify-content: center; + gap: 20px; } @media (max-width: 1000px) { .dependencies { @@ -180,10 +178,12 @@ export class MvnpmHome extends LitElement { .copy { width: 20px; cursor: pointer; - align-self: end; + position: absolute; + bottom: 3px; + right: 5px; } .copy:hover { - color:var(--lumo-success-color); + filter: brightness(0.85); } .gaveventlogconsole { @@ -202,6 +202,48 @@ export class MvnpmHome extends LitElement { flex-direction: row; gap: 10px; } + .searchResults { + display: flex; + flex-direction: column; + gap: 20px; + width: 90%; + } + + .searchResultName { + font-size: 20px; + font-weight: bold; + margin-top: 0px; + margin-bottom: 1px; + } + .searchResultCard:hover { + filter: brightness(0.85); + cursor: pointer; + } + .searchResultContent:hover { + cursor: unset; + } + + .searchResultDescription{ + padding-right: 10px; + padding-left: 10px; + } + .searchResultKeywords{ + display: flex; + gap: 5px; + padding: 10px; + } + .searchResultDetails{ + display: flex; + justify-content: space-between; + } + .searchResultLinks{ + padding: 15px; + display: flex; + gap: 15px; + } + .infoCard { + width: 100%; + } `; @state() @@ -231,6 +273,8 @@ export class MvnpmHome extends LitElement { @state() private _loadingIcon = "hidden"; @state() + private _searchResults: string; + @state() private _centralSyncItem?: object; @state() private _gavEventLog?: object; @@ -251,13 +295,15 @@ export class MvnpmHome extends LitElement { if(currentPath.startsWith("/package/")){ this._coordinates.name = currentPath.substring(9); this._showGA(this._coordinates.name); + }else if(currentPath.startsWith("/search/")){ + this._showGA(currentPath.substring(8)); } } render() { return html` ${this._renderCoordinatesPane()} - ${this._renderTabPane()} + ${this._renderMiddlePane()} `; } @@ -295,6 +341,14 @@ export class MvnpmHome extends LitElement { } + _renderMiddlePane(){ + if(this._coordinates.version) { + return this._renderTabPane(); + } else if(this._searchResults){ + return this._renderSearchResults(); + } + } + _renderTabPane(){ if(this._coordinates.version) { return html` @@ -320,6 +374,64 @@ export class MvnpmHome extends LitElement { } } + _renderSearchResults(){ + if(this._searchResults.objects){ + const objects = this._searchResults.objects; + return html`
+ ${objects.map((result) => + html` +
+
+
+ ${unsafeHTML(marked(result.package.description))} + ${this._renderBy(result)} +
+ +
+ ${this._renderSearchKeywords(result.package.keywords)} + +
+
` + )} +
`; + } + } + + _renderBy(result){ + if(result.package.author && result.package.author.name){ + return html` - by ${result.package.author.name}`; + }else if(result.package.publisher){ + if(result.package.publisher.name){ + return html` - by ${result.package.publisher.name}`; + }else if(result.package.publisher.username){ + return html` - by ${result.package.publisher.username}`; + } + } + } + + _selectSearchResult(e){ + this._coordinates.version = null; + this._coordinates.name = e.target.dataset.package; + this._showGA(this._coordinates.name); + } + + _renderSearchKeywords(keywords){ + if(keywords){ + return html`
+ ${keywords.map((keyword) => + html`${keyword}` + )} +
`; + } + } + _showNpmjsLink(){ if(this._centralSyncItem){ var npmUrl = "/api/info/npm/" + this._centralSyncItem.groupId + "/" + this._centralSyncItem.artifactId + "?version=" + this._centralSyncItem.version; @@ -366,34 +478,33 @@ export class MvnpmHome extends LitElement {
- ${this._info.description} + ${unsafeHTML(marked(this._info.description))}
by ${this._info.organizationName}
-
- Pom dependency - - -
- -
- Import map - -
- -
- Dependencies - - + +
+ + +
+
+ +
+ +
+
+ +
+
${this._info.dependencies.map((dependency) => html`` )} -
${dependency}
-
- + +
+
@@ -538,22 +649,46 @@ export class MvnpmHome extends LitElement { groupPath = `org/mvnpm/${groupPath}`; } artifactPath = ga[1].trim(); - } else { - // TODO: This should do a search... this._loadingIcon = "visible"; groupPath = "org/mvnpm"; artifactPath = name.replaceAll('@', 'at/'); } const metadataUrl = `/maven2/${groupPath}/${artifactPath}/maven-metadata.xml`; + fetch(metadataUrl) + .then((response) => { + + + + if(response.ok){ + let contentLength = response.headers.get('Content-Length'); + if (contentLength == null || parseInt(contentLength, 10) > 0) { + this._stopLoading(); + return response.text(); + } + } + throw new Error(); + }) + .then(xmlDoc => new window.DOMParser().parseFromString(xmlDoc, "text/xml")) + .then(metadata => this._inspectMetadata(metadata)) + .catch(error => { + this._search(name); + }); + + } + } + + _search(name){ + var searchUrl = "/api/info/search/" + name; + fetch(searchUrl) .then((response) => { this._stopLoading(); if(response.ok){ - return response.text(); + return response.json(); }else if(response.status === 404){ - const notification = Notification.show(groupPath + '/' + artifactPath + ' not found', { + const notification = Notification.show(name + ' not found', { position: 'top-center', duration: 5000, }); @@ -564,9 +699,11 @@ export class MvnpmHome extends LitElement { }); } }) - .then(xmlDoc => new window.DOMParser().parseFromString(xmlDoc, "text/xml")) - .then(metadata => this._inspectMetadata(metadata)); - } + .then(jsonResult => { + window.history.pushState({/* State */},"", "/search/" + name); + this._coordinates.version = null; + this._searchResults = jsonResult; + }); } _inspectMetadata(metadata){ @@ -702,15 +839,17 @@ export class MvnpmHome extends LitElement { _clearCoordinates(){ this._coordinates = DEFAULT_COORDS; this._info = null; - this._disabled = "disabled"; this._baseUrl = null; this._baseFile = null; this._usePom = null; this._useJson = null; this._versions = null; + this._latestVersion = null; this._codeViewSelection = ".pom"; this._codeViewMode = "xml"; this._loadingIcon = "hidden"; + this._searchResults = null; + this._disabled = "disabled"; } _coordinatesNameChanged(e){ diff --git a/src/main/resources/web/app/mvnpm-nav.ts b/src/main/resources/web/app/mvnpm-nav.ts index 03b592a..ca0ca60 100644 --- a/src/main/resources/web/app/mvnpm-nav.ts +++ b/src/main/resources/web/app/mvnpm-nav.ts @@ -15,6 +15,7 @@ const router = new Router(document.getElementById('outlet')); router.setRoutes([ {path: '/', component: 'mvnpm-home', name: 'Home'}, {path: '/package/:package', component: 'mvnpm-home', name: 'Home'}, + {path: '/search/:name', component: 'mvnpm-home', name: 'Home'}, {path: '/releases', component: 'mvnpm-releases', name: 'Releases'}, {path: '/live', component: 'mvnpm-live', name: 'Live'}, {path: '/about', component: 'mvnpm-about', name: 'About'},