-
-
Notifications
You must be signed in to change notification settings - Fork 554
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
XWIKI-14342: Make Extension Manager use IconThemes #2823
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -576,6 +576,14 @@ $namespace## | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</dd> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#end | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#macro (spinner) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#if ($services.icon.currentIconSetName == 'Font Awesome') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<span class="fa fa-spinner fa-spin"></span> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#else | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<img src="$escapetool.xml($xwiki.getSkinFile('icons/xwiki/spinner.gif'))"/> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#end | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#end | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* NOTE: We explicitly overwrite the $extensionNamespace global variable because we want the dependency status to be | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* determined for the given namespace. See #determineExtensionStatus() macro. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -613,6 +621,29 @@ $namespace## | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#set ($dependencyName = "<a href=""$dependencyURL"" class=""extension-link"">#displayExtensionName($dependencyExtension)</a>") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#end | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<div class="dependency-item extension-item-$dependencyStatus"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#if($!dependencyStatus == 'core' || | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$!dependencyStatus == 'remote-core' || | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$!dependencyStatus == 'remote-core-incompatible') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$services.icon.renderHTML('cog') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#end | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#if($!dependencyStatus == 'installed' || | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$!dependencyStatus == 'remote-installed' || | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$!dependencyStatus == 'installed-invalid' || | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$!dependencyStatus == 'remote-installed-invalid' || | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$!dependencyStatus == 'installed-dependency' || | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$!dependencyStatus == 'remote-installed-dependency' || | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$!dependencyStatus == 'remote-installed-incompatible') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$services.icon.renderHTML('plugin') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#end | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#if($!dependencyStatus == 'remote') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$services.icon.renderHTML('world') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#end | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#if($!dependencyStatus == 'loading') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#spinner() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#end | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#if($!dependencyStatus == 'unknown') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$services.icon.renderHTML('error') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#end | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+624
to
+646
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd rather use a mapping between dependency state and icon:
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<span class="extension-name">${dependencyName}</span><span class="extension-version">$!dependencyVersion</span> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#if ($extensionNamespace.startsWith('wiki:')) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<span class="extension-namespace">$services.localization.render('extensions.info.dependency.wiki', ["#wikiHomePageLink($extensionNamespace)"])</span> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -1038,6 +1069,24 @@ $namespace## | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<div class="extension-header"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<h2 class="extension-title"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#if($!extensionStatus == 'core' || | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't like too much this duplicated logic. @tmortagne do you know if we have velocity services for this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. AFAIK, this concept of status is something @mflorea introduced in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note that the logic is not duplicated, it looks very similar, but e.g. there's also the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd rather use a mapping, as suggested in my previous comment. And the mapping can be shared between extension and dependency icons. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$!extensionStatus == 'remote-core') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$services.icon.renderHTML('cog') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#end | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#if($!extensionStatus == 'installed' || | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$!extensionStatus == 'remote-installed' || | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$!extensionStatus == 'installed-dependency' || | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$!extensionStatus == 'remote-installed-dependency' || | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$!extensionStatus == 'installed-invalid' || | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$!extensionStatus == 'remote-installed-invalid') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$services.icon.renderHTML('plugin') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#end | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#if($!extensionStatus == 'remote') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$services.icon.renderHTML('world') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#end | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#if($!extensionStatus == 'loading') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#spinner() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#end | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<span class="extension-name">#displayExtensionName($extension)</span> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<span class="extension-version">$escapetool.xml($extension.id.version)</span> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#if ($extensionStatusMessage) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -22,7 +22,12 @@ | |||||
border: none; | ||||||
background: none no-repeat scroll 0.2em 0.3em transparent; | ||||||
margin: 0 0 0 -1.8em; | ||||||
padding: 2px 0 2px 1.8em; | ||||||
padding: 2px 0 2px 0; | ||||||
} | ||||||
|
||||||
/* Style the icon at the start of the title. */ | ||||||
.extension-title > *:first-child{ | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
What if the icon is missing? The code you added to |
||||||
margin-right: .8em; | ||||||
} | ||||||
|
||||||
.extension-version, .extension-namespace { | ||||||
|
@@ -170,37 +175,18 @@ ul.dependencies li:hover { | |||||
background: transparent none no-repeat left; | ||||||
border-bottom: 1px dotted #E8E8E8; | ||||||
border-right: 7px solid $theme.pageContentBackgroundColor; | ||||||
padding: 0.3em 0 0.3em 20px; | ||||||
padding: 0.3em 0 0.3em 0; | ||||||
position: relative; | ||||||
} | ||||||
.dependency-item { | ||||||
line-height: 1.4em; | ||||||
} | ||||||
|
||||||
.dependency-item > *:first-child { | ||||||
margin-right: .3em; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above, we need to make sure there's always an icon, otherwise this rule will target a different element. |
||||||
} | ||||||
|
||||||
.dependency-item .extension-status { | ||||||
margin: 0; | ||||||
} | ||||||
.extension-item-core .extension-title, .extension-item-remote-core .extension-title, | ||||||
.dependency-item.extension-item-core, .dependency-item.extension-item-remote-core, .dependency-item.extension-item-remote-core-incompatible { | ||||||
background-image: url("$xwiki.getSkinFile('icons/silk/cog.png')"); | ||||||
} | ||||||
.extension-item-installed .extension-title, .extension-item-remote-installed .extension-title, | ||||||
.extension-item-installed-dependency .extension-title, .extension-item-remote-installed-dependency .extension-title, | ||||||
.extension-item-installed-invalid .extension-title, .extension-item-remote-installed-invalid .extension-title, | ||||||
.dependency-item.extension-item-installed, .dependency-item.extension-item-remote-installed, | ||||||
.dependency-item.extension-item-installed-invalid, .dependency-item.extension-item-remote-installed-invalid, | ||||||
.dependency-item.extension-item-installed-dependency, .dependency-item.extension-item-remote-installed-dependency, | ||||||
.dependency-item.extension-item-remote-installed-incompatible { | ||||||
background-image: url("$xwiki.getSkinFile('icons/silk/plugin.png')"); | ||||||
} | ||||||
.extension-item-remote .extension-title, .dependency-item.extension-item-remote { | ||||||
background-image: url("$xwiki.getSkinFile('icons/silk/world.png')"); | ||||||
} | ||||||
.extension-item-loading .extension-title, .dependency-item.extension-item-loading { | ||||||
background-image: url("$xwiki.getSkinFile('icons/xwiki/spinner.gif')"); | ||||||
} | ||||||
.dependency-item.extension-item-unknown { | ||||||
background-image: url("$xwiki.getSkinFile('icons/silk/plugin_error.png')"); | ||||||
} | ||||||
|
||||||
.extension-item-core, | ||||||
.extension-item-installed-dependency { | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -495,6 +495,12 @@ XWiki.ExtensionBehaviour = Class.create({ | |
parameters : formData, | ||
onCreate : function() { | ||
dependency.removeClassName('extension-item-unknown').addClassName('extension-item-loading'); | ||
// Remove the unknown icon. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not really clear why we need to do all this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
We could make it work with smart CSS relying on logic classes to hide and show icons. I tried to keep the changes to a minimum to avoid making this more complex. Keeping things simple means also that it's less likely to break things in a usecase/customization unknown to me. This code is quite old and large. A complete overhaul would be the best solution quality wise, but it's beyond the goal of this PR.
Before, the icon would swap directly when we swapped the classes. Here, I added a few lines to swap the icon DOM elements at the same time as they did before. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TODO: At least add a comment to explain the HTML manipulations. Should probably add CSS logic to avoid this HTML manipulations. Do leave things like this if extensive testing show that it's not possible to have a simple CSS logic in place... |
||
dependency.removeChild(dependency.childNodes[1]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is too fragile. I'd rather add an icon wrapper ( |
||
// Add the load icon | ||
const loadPath = '$xwiki.getSkinFile("icons/xwiki/spinner.gif")'; | ||
const loadIcon = '<img src="'+ loadPath + '" alt=""/>'; | ||
Comment on lines
+500
to
+502
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This doesn't match the behavior of the spinner Velocity macro. A possible solution is to always output the spinner from |
||
dependency.update(loadIcon + dependency.innerHTML); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd rather use https://developer.mozilla.org/en-US/docs/Web/API/Element/replaceWith to replace the unknown icon with the loading icon. |
||
}, | ||
onSuccess : function(response) { | ||
// Update the dependency if it's still attached to the document. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duplicate of
xwiki-platform/xwiki-platform-core/xwiki-platform-export/xwiki-platform-export-pdf/xwiki-platform-export-pdf-ui/src/main/resources/XWiki/PDFExport/AdminSection.xml
Line 90 in be3b947
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is a common need, it's better to solve the code duplication, and to provide this as an actual API.
Meaning with a documented since version, and mentioned in the release notes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
TODO provide this spinner as a macro in https://github.com/xwiki/xwiki-platform/blob/29111f02b38e529f44ff88aaf4ec67af92fcf3df/xwiki-platform-core/xwiki-platform-web/xwiki-platform-web-templates/src/main/resources/templates/macros.vm (which from my experience is the main place where we provide API-ish velocimacros).