diff --git a/srv/static/css/specifics.css b/srv/static/css/specifics.css index 62250b4..3059a5a 100644 --- a/srv/static/css/specifics.css +++ b/srv/static/css/specifics.css @@ -208,6 +208,9 @@ .icon-download { background-image: url(../img/icon/download.svg); } +.icon-graph { + background-image: url(../img/icon/graph.svg); +} /* actions shown on top-right corner of build actions and build action details */ .heading-actions { diff --git a/srv/static/img/icon/graph.svg b/srv/static/img/icon/graph.svg new file mode 100644 index 0000000..0272ad2 --- /dev/null +++ b/srv/static/img/icon/graph.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/srv/static/index.html b/srv/static/index.html index 5682638..ae82e6f 100644 --- a/srv/static/index.html +++ b/srv/static/index.html @@ -115,7 +115,7 @@
-

Package details

+

Package details

No package selected. Use the "Search" to find and select a package.

diff --git a/srv/static/js/buildactionspage.js b/srv/static/js/buildactionspage.js index 9179bd5..d7ee518 100644 --- a/srv/static/js/buildactionspage.js +++ b/srv/static/js/buildactionspage.js @@ -623,7 +623,7 @@ function renderBuildActionDetailsTable(buildActionDetails) displayLabels: ['Missing dependencies', 'Missing libraries'], fieldAccessors: ['deps', 'libs'], customRenderer: { - deps: PackageRendering.renderDependency, + deps: PackageRendering.renderDependency.bind(undefined, 'provides'), }, }); default: diff --git a/srv/static/js/genericrendering.js b/srv/static/js/genericrendering.js index b7c9509..20fe66d 100644 --- a/srv/static/js/genericrendering.js +++ b/srv/static/js/genericrendering.js @@ -168,6 +168,9 @@ export function renderLink(value, row, handler, tooltip, href, middleClickHref) if (tooltip !== undefined) { linkElement.title = tooltip; } + if (handler === undefined) { + return linkElement; + } linkElement.onclick = function () { handler(value, row); return false; diff --git a/srv/static/js/packagerendering.js b/srv/static/js/packagerendering.js index 3d5eba8..fa1916a 100644 --- a/srv/static/js/packagerendering.js +++ b/srv/static/js/packagerendering.js @@ -4,10 +4,44 @@ import * as CustomRendering from './customrendering.js'; import * as SinglePageHelper from './singlepage.js'; import * as Utils from './utils.js'; -/// \brief Renders a dependency object. -export function renderDependency(value) +export function renderPackageDetailsLink(row) { - if (value.length < 1) { + return GenericRendering.renderLink(row.name, row, queryPackageDetails, 'Show package details', undefined, + '#package-details-section?' + encodeURIComponent(row.db + (row.dbArch ? '@' + row.dbArch : '') + '/' + row.name)); +} + +const modeTooltip = {provides: 'dependency', requires: 'dependency', libprovides: 'library', librequires: 'library'}; + +export function renderPackageSearchLink(name, mode, text) +{ + const tooltip = 'Search for ' + (mode !== undefined ? modeTooltip[mode] : 'package'); + if (mode === undefined) { + mode = 'name'; + } + const params = '#package-search-section?name=' + encodeURIComponent(name) + '&mode=' + encodeURIComponent(mode); + return GenericRendering.renderLink(text || name, undefined, undefined, tooltip, undefined, params); +} + +/// \brief Renders library names. +export function renderLibraries(mode, value) +{ + if (!Array.isArray(value) || value.length < 1) { + return GenericRendering.renderArrayAsCommaSeparatedString(value); + } + const containerElement = document.createElement('span'); + value.forEach(function (libraryName) { + if (containerElement.firstChild) { + containerElement.appendChild(document.createTextNode(' ')); + } + containerElement.appendChild(renderPackageSearchLink(libraryName, mode)); + }); + return containerElement; +} + +/// \brief Renders a dependency object. +export function renderDependency(mode, value) +{ + if (!Array.isArray(value) || value.length < 1) { return GenericRendering.renderArrayAsCommaSeparatedString(value); } const list = document.createElement('ul'); @@ -22,7 +56,7 @@ export function renderDependency(value) res += mode + dependency.version; } } - item.appendChild(document.createTextNode(res)); + item.appendChild(renderPackageSearchLink(res, mode || 'provides')); if (dependency.description) { const descriptionSpan = document.createElement('span'); descriptionSpan.appendChild(document.createTextNode(' - ' + dependency.description)); @@ -61,15 +95,15 @@ export function renderPackage(packageObj, withoutBasics) }, licenses: GenericRendering.renderArrayAsCommaSeparatedString, groups: GenericRendering.renderArrayAsCommaSeparatedString, - dependencies: renderDependency, - optionalDependencies: renderDependency, - provides: renderDependency, - replaces: renderDependency, - conflicts: renderDependency, - libprovides: GenericRendering.renderArrayAsCommaSeparatedString, - libdepends: GenericRendering.renderArrayAsCommaSeparatedString, - 'sourceInfo.makeDependencies': renderDependency, - 'sourceInfo.checkDependencies': renderDependency, + dependencies: renderDependency.bind(undefined, 'provides'), + optionalDependencies: renderDependency.bind(undefined, 'provides'), + provides: renderDependency.bind(undefined, 'depends'), + replaces: renderDependency.bind(undefined, 'provides'), + conflicts: renderDependency.bind(undefined, 'provides'), + libprovides: renderLibraries.bind(undefined, 'libdepends'), + libdepends: renderLibraries.bind(undefined, 'libprovides'), + 'sourceInfo.makeDependencies': renderDependency.bind(undefined, 'provides'), + 'sourceInfo.checkDependencies': renderDependency.bind(undefined, 'provides'), 'packageInfo.arch': function(value, row) { const sourceInfo = row.sourceInfo; const sourceArchs = sourceInfo !== undefined ? sourceInfo.archs : undefined; @@ -87,12 +121,6 @@ export function renderPackage(packageObj, withoutBasics) return table; } -export function renderPackageDetailsLink(row) -{ - return GenericRendering.renderLink(row.name, row, queryPackageDetails, 'Show package details', undefined, - '#package-details-section?' + encodeURIComponent(row.db + (row.dbArch ? '@' + row.dbArch : '') + '/' + row.name)); -} - function makePackageID(row) { return row.db + (row.dbArch ? '@' + row.dbArch : '') + '/' + row.name; @@ -111,6 +139,18 @@ function switchToPackageDetails(packageID) SinglePageHelper.updateHashPreventingSectionInitializer('#package-details-section?' + encodeURIComponent(packageID)); } +function renderPackageActions(pkg) +{ + const container = document.createElement('span'); + container.appendChild(CustomRendering.renderIconLink('graph', undefined, undefined, 'Show dependend packages', + undefined, '#package-search-section?name=' + encodeURIComponent(pkg.name) + '&mode=depends')); + container.appendChild(CustomRendering.renderIconLink('table-refresh', undefined, function() { + queryPackageDetails(undefined, pkg); + return false; + }, 'Refresh package details', undefined, '#package-details-section?' + encodeURIComponent(makePackageID(pkg)))); + return container; +} + export function showPackageDetails(ajaxRequest, row) { const packageID = makePackageID(row); @@ -133,6 +173,8 @@ export function showPackageDetails(ajaxRequest, row) packageObj.db = row.db; packageObj.dbArch = row.dbArch; packageDetailsContainer.appendChild(renderPackage(packageObj, true)); + const packageActions = Utils.getAndEmptyElement('package-details-actions'); + packageActions.appendChild(renderPackageActions(packageObj)); switchToPackageDetails(packageID); }