-
-
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?
Conversation
* Removed the Hardcoded silk icons from the CSS * Fixed style to fit actual icon nodes in the same place as they used to be as background. * Added them in the velocity template instead * Fixed the behavior of status switch when loading dependencies.
...orm-web/xwiki-platform-web-war/src/main/webapp/resources/uicomponents/extension/extension.js
Outdated
Show resolved
Hide resolved
@@ -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 comment
The reason will be displayed to describe this comment to others. Learn more.
This is not really clear why we need to do all this.
Also, I don't know this code much but why do you need to manipulate Velocity code from javascript?
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.
Also, I don't know this code much but why do you need to manipulate Velocity code from javascript?
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.
This is not really clear why we need to do all this.
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 comment
The 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...
@@ -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 comment
The 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 comment
The reason will be displayed to describe this comment to others. Learn more.
AFAIK, this concept of status is something @mflorea introduced in #determineExtensionStatus
, and it does not exist on Java side.
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.
Note that the logic is not duplicated, it looks very similar, but e.g. there's also the incompatible
ones for dependencies.
This solution is very similar to what was done in CSS before (see the css removed from extension.css, it wasn't really refined either ^^' ). Instead of having a switch in the rulesets, I pretty much brought it in the template. I'd need to get back to it, but a more elegant solution would be to store the icon mapping in a unified table. This was just a minimal working alternative with icons actually in the HTML template and not only in the CSS.
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.
I'd rather use a mapping, as suggested in my previous comment. And the mapping can be shared between extension and dependency icons.
@@ -576,6 +576,14 @@ $namespace## | |||
</dd> | |||
#end | |||
|
|||
#macro (spinner) |
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.
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).
* Improve code quality Co-authored-by: Manuel Leduc <manuel.leduc@xwiki.com>
#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 |
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.
I'd rather use a mapping between dependency state and icon:
#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 | |
#set ($dependencyIcons = { | |
'core': 'cog', | |
..., | |
'installed': 'plugin', | |
..., | |
'remote': 'world', | |
'unknown': 'error' | |
}) | |
#set ($dependencyIcon = $dependencyIcons.get($dependencyStatus)) | |
#if ($dependencyIcon) | |
$services.icon.renderHTML($dependencyIcon) | |
#elseif ($dependencyStatus == 'loading') | |
#spinner() | |
#end |
@@ -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 comment
The 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.
} | ||
|
||
/* 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 comment
The reason will be displayed to describe this comment to others. Learn more.
.extension-title > *:first-child{ | |
.extension-title > *:first-child { |
What if the icon is missing? The code you added to extension.vm
allows this. We need to either choose a default icon or output some empty DIV when the extension / dependency state is not mapped to an icon. Or, even cleaner, add an icon wrapper (.extension-icon
) and use that in the CSS.
line-height: 1.4em; | ||
} | ||
|
||
.dependency-item > *:first-child { | ||
margin-right: .3em; |
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.
Same as above, we need to make sure there's always an icon, otherwise this rule will target a different element.
@@ -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. | |||
dependency.removeChild(dependency.childNodes[1]); |
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.
This is too fragile. I'd rather add an icon wrapper (.extension-icon
) and look for it.
// Add the load icon | ||
const loadPath = '$xwiki.getSkinFile("icons/xwiki/spinner.gif")'; | ||
const loadIcon = '<img src="'+ loadPath + '" alt=""/>'; | ||
dependency.update(loadIcon + dependency.innerHTML); |
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.
I'd rather use https://developer.mozilla.org/en-US/docs/Web/API/Element/replaceWith to replace the unknown icon with the loading icon.
// Add the load icon | ||
const loadPath = '$xwiki.getSkinFile("icons/xwiki/spinner.gif")'; | ||
const loadIcon = '<img src="'+ loadPath + '" alt=""/>'; |
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.
This doesn't match the behavior of the spinner Velocity macro. A possible solution is to always output the spinner from extension.vm
, but hidden by default. It would be made visible by the extension-item-loading
CSS class, which means no change in needed in this JavaScript file.
Jira URL
https://jira.xwiki.org/browse/XWIKI-14342
Changes
Description
Clarifications
Screenshots & Video
Here is a demo of the changes brought in this PR. In the first part, we can see that the looks with the silk iconTheme are the same as they used to be. However in the second part, we can see that now Font Awesome icons are correctly used when FontAwesome is set as the iconTheme.
Executed Tests
No test executed exept manual tests similar to the one in the demo.
Expected merging strategy