working on tabler icons integration

This commit is contained in:
Alexander Meindl 2024-10-05 16:33:56 +02:00
parent 456b9942ff
commit b4e1f2b67d
58 changed files with 1203 additions and 141 deletions

View File

@ -4,6 +4,7 @@
- Maintenance release
- Ruby 3.1 required
- Working on Tabler icons integration
## 3.2.0

View File

@ -650,3 +650,32 @@ Footnotes:
### Contact and Support
For questions or feedback on the plugin functions, [pull requests](https://github.com/alphanodes/additionals/pulls), [issues](https://github.com/alphanodes/additionals/issues) use only the issue system as a communication channel. Thank you.
## License
This plugin is licensed under the terms of GNU/GPL v2.
See LICENSE for details.
## Redmine Copyright
The additionals is a plugin extension for Redmine Project Management Software, whose Copyright follows.
Copyright (C) 2006- Jean-Philippe Lang
Redmine is a flexible project management web application written using Ruby on Rails framework.
More details can be found in the doc directory or on the official website <http://www.redmine.org>
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
## Credits
Thanks to:
* Font Awesome Free Icons (<https://fontawesome.com/license/free>) licenced under - Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License.
Copyright (c) 2018- Fonticons, Inc.
* Tabler Icons - Free and open source icons (<https://tabler.io/icons>) licensed under MIT License.
Copyright (c) 2020- Paweł Kuna

View File

@ -22,7 +22,7 @@ class AdditionalsAssignToMeController < ApplicationController
journal: @issue.current_journal
if !@issue.save || old_user == @issue.assigned_to
flash[:error] = l :error_issues_could_not_be_assigned_to_me
flash[:error] = flash_msg :error_issues_could_not_be_assigned_to_me
return redirect_to(issue_path(@issue))
end

View File

@ -25,8 +25,11 @@ class AdditionalsChangeStatusController < ApplicationController
journal: @issue.current_journal
if !@issue.save || issue_old_status_id == @issue.status_id
messages = @issue.errors.full_messages
flash[:error] = messages.present? ? messages.to_comma_list : l(:error_issue_status_could_not_changed)
if issue_old_status_id == @issue.status_id
flash_msg :error_issue_status_could_not_changed
else
flash_msg :save_error, obj: @issue
end
return redirect_to(issue_path(@issue))
end

View File

@ -85,7 +85,7 @@ class DashboardsController < ApplicationController
if @dashboard.save
respond_to do |format|
format.html do
flash[:notice] = l :notice_successful_create
flash[:notice] = flash_msg :create
redirect_to dashboard_link_path(@project, @dashboard)
end
format.api { render action: :show, status: :created, location: dashboard_url(@dashboard, project_id: @project) }
@ -110,7 +110,7 @@ class DashboardsController < ApplicationController
@project = @dashboard.project if @project && @dashboard.project_id.present? && @dashboard.project != @project
if @dashboard.save
flash[:notice] = l :notice_successful_update
flash[:notice] = flash_msg :update
respond_to do |format|
format.html { redirect_to dashboard_link_path(@project, @dashboard) }
format.api { render_api_ok }
@ -128,13 +128,13 @@ class DashboardsController < ApplicationController
begin
@dashboard.destroy
flash[:notice] = l :notice_successful_delete
flash[:notice] = flash_msg :delete
respond_to do |format|
format.html { redirect_to @project.nil? ? home_path : project_path(@project) }
format.api { render_api_ok }
end
rescue ActiveRecord::RecordNotDestroyed
flash[:error] = l :error_remove_db_entry
flash[:error] = flash_msg :delete_error, obj: @dashboard
redirect_to dashboard_path(@dashboard)
end
end

View File

@ -0,0 +1,79 @@
# frozen_string_literal: true
module AdditionalsIconsHelper
DEFAULT_ICON_SIZE = '18'
def h2_page_icon(icon_name, **options)
svg_icon_tag(icon_name, size: 24, css_class: 'icon-padding', **options)
end
def svg_icon_tag(icon_name,
label: nil,
size: DEFAULT_ICON_SIZE,
css_class: nil,
label_type: :span,
title: nil,
icon_only: false,
wrapper: nil,
wrapper_content: nil,
wrapper_class: 'a-icon',
wrapper_css: nil)
svg_code = svg_sprite_icon(icon_name, size:, title:, css_class:)
content = svg_code.dup
if label
label_classes = ['a-icon-label']
label_classes << 'hidden' if icon_only
content << content_tag(label_type,
label.is_a?(Symbol) ? l(label) : label,
class: label_classes.join(' '))
end
return content unless wrapper
content << wrapper_content if wrapper_content
wrapper_classes = "#{wrapper_class} a-icon-#{icon_name}"
wrapper_classes += " #{wrapper_css}" if wrapper_css
content_tag wrapper, content, class: wrapper_classes
end
def svg_sprite_icon(icon_name, size: DEFAULT_ICON_SIZE, sprite: 'icons', css_class: nil, title: nil)
sprite_path = "#{sprite}.svg"
css_classes = "a-s#{size} a-svg-icon"
css_classes += " #{css_class}" if css_class
content_tag(
:svg,
content_tag(:use,
'',
{ 'href' => "#{additionals_image_path}/#{sprite_path}#icon--#{icon_name}" }),
class: css_classes,
title: title.presence,
aria: { hidden: true }
)
end
def additionals_image_path
return @additionals_image_path if defined? @additionals_image_path
relative_url = Redmine::Utils.relative_url_root
plugin_id = 'additionals'
@additionals_image_path = "#{relative_url}/plugin_assets/#{plugin_id}/images"
end
private
def svg_icon_for_mime_type(mime)
if %w[text-plain text-x-c text-x-csharp text-x-java text-x-php
text-x-ruby text-xml text-css text-html text-css text-html
image-gif image-jpeg image-png image-tiff
application-pdf application-zip application-gzip application-javascript].include?(mime)
mime
else
'file'
end
end
end

View File

@ -295,7 +295,7 @@ module AdditionalsQueriesHelper
def set_flash_from_bulk_save(entries, unsaved_ids, name_plural:)
if unsaved_ids.empty?
flash[:notice] = l :notice_successful_update unless entries.empty?
flash[:notice] = flash_msg :update unless entries.empty?
else
flash[:error] = l :notice_failed_to_save_entity,
name_plural:,

View File

@ -1,7 +1,7 @@
- classes = 'live-search'
- if defined? css_class
- classes << " #{css_class}"
h2#page-title class="#{classes}"
- if defined? css_class
= svg_icon_tag css_class, css_class: 'icon-padding', size: 24
= @query.new_record? ? l(title) : h(@query.name)
= text_field_tag :search,
q,

View File

@ -6,7 +6,7 @@
- if feed[:valid]
- if feed[:items].count.positive?
ul.reporting-list.feed
ul.dashboard-list.feed
- feed[:items].each do |item|
li = link_to_external item[:title], item[:link]
- else

View File

@ -17,7 +17,7 @@ h3 = block_definition[:label]
'
= link_to_function l(:button_cancel), "$('#my_spent_time-settings').toggle()"
ul.reporting-list
ul.dashboard-list
li.today
= l :label_today
' :

View File

@ -4,7 +4,7 @@ h3 = block_definition[:label]
.wiki.project-description
= textilizable @project.description
- if @project.homepage.present? || @project.visible_custom_field_values.any? { |o| o.value.present? }
ul.reporting-list
ul.dashboard-list
- if @project.homepage.present?
li
span.label

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-puzzle"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M4 7h3a1 1 0 0 0 1 -1v-1a2 2 0 0 1 4 0v1a1 1 0 0 0 1 1h3a1 1 0 0 1 1 1v3a1 1 0 0 0 1 1h1a2 2 0 0 1 0 4h-1a1 1 0 0 0 -1 1v3a1 1 0 0 1 -1 1h-3a1 1 0 0 1 -1 -1v-1a2 2 0 0 0 -4 0v1a1 1 0 0 1 -1 1h-3a1 1 0 0 1 -1 -1v-3a1 1 0 0 1 1 -1h1a2 2 0 0 0 0 -4h-1a1 1 0 0 1 -1 -1v-3a1 1 0 0 1 1 -1" /></svg>

After

Width:  |  Height:  |  Size: 609 B

View File

@ -1,11 +0,0 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="gradient" x1="100%" y1="100%">
<stop offset="0%" style="stop-color: #aaa; stop-opacity: 1" />
<stop offset="100%" style="stop-color: #ccc; stop-opacity: 1" />
</linearGradient>
</defs>
<rect width="100%" height="100%" style="fill:url(#gradient)"/>
</svg>

Before

Width:  |  Height:  |  Size: 527 B

812
assets/images/icons.svg Normal file
View File

@ -0,0 +1,812 @@
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" class="icon--sprite">
<defs>
<symbol viewBox="0 0 24 24" id="icon--pdf">
<!-- file-type-pdf -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M14 3v4a1 1 0 0 0 1 1h4" />
<path d="M5 12v-7a2 2 0 0 1 2 -2h7l5 5v4" />
<path d="M5 18h1.5a1.5 1.5 0 0 0 0 -3h-1.5v6" />
<path d="M17 18h2" />
<path d="M20 15h-3v6" />
<path d="M11 15v6h1a2 2 0 0 0 2 -2v-2a2 2 0 0 0 -2 -2h-1z" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--page-up">
<!-- circle-arrow-up -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M17 3.34a10 10 0 1 1 -14.995 8.984l-.005 -.324l.005 -.324a10 10 0 0 1 14.995 -8.336zm-4.98 3.66l-.163 .01l-.086 .016l-.142 .045l-.113 .054l-.07 .043l-.095 .071l-.058 .054l-4 4l-.083 .094a1 1 0 0 0 1.497 1.32l2.293 -2.293v5.586l.007 .117a1 1 0 0 0 1.993 -.117v-5.585l2.293 2.292l.094 .083a1 1 0 0 0 1.32 -1.497l-4 -4l-.082 -.073l-.089 -.064l-.113 -.062l-.081 -.034l-.113 -.034l-.112 -.02l-.098 -.006z" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--euro">
<!-- currency-euro -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M17.2 7a6 7 0 1 0 0 10" />
<path d="M13 10h-8m0 4h8" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--canned-response">
<!-- message-2-share -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M8 9h8" />
<path d="M8 13h6" />
<path d="M12 21l-3 -3h-3a3 3 0 0 1 -3 -3v-8a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v6" />
<path d="M16 22l5 -5" />
<path d="M21 21.5v-4.5h-4.5" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--web">
<!-- world -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0" />
<path d="M3.6 9h16.8" />
<path d="M3.6 15h16.8" />
<path d="M11.5 3a17 17 0 0 0 0 18" />
<path d="M12.5 3a17 17 0 0 1 0 18" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--ticket">
<!-- ticket -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M15 5l0 2" />
<path d="M15 11l0 2" />
<path d="M15 17l0 2" />
<path d="M5 5h14a2 2 0 0 1 2 2v3a2 2 0 0 0 0 4v3a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2v-3a2 2 0 0 0 0 -4v-3a2 2 0 0 1 2 -2" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--phone">
<!-- phone -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M5 4h4l2 5l-2.5 1.5a11 11 0 0 0 5 5l1.5 -2.5l5 2v4a2 2 0 0 1 -2 2a16 16 0 0 1 -15 -15a2 2 0 0 1 2 -2" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--mail">
<!-- mail -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M3 7a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/>
<path d="m3 7l9 6l9-6"/>
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--send-mail">
<!-- send -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M10 14l11 -11" />
<path d="M21 3l-6.5 18a.55 .55 0 0 1 -1 0l-3.5 -7l-7 -3.5a.55 .55 0 0 1 0 -1l18 -6.5" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--mail-sent">
<!-- mail-up -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M12 19h-7a2 2 0 0 1 -2 -2v-10a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v5.5" />
<path d="M19 22v-6" />
<path d="M22 19l-3 -3l-3 3" />
<path d="M3 7l9 6l9 -6" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--mail-received">
<!-- mail-down -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M12 19h-7a2 2 0 0 1 -2 -2v-10a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v5.5" />
<path d="M19 16v6" />
<path d="M22 19l-3 3l-3 -3" />
<path d="M3 7l9 6l9 -6" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--mail-spam">
<!-- ghost -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M5 11a7 7 0 0 1 14 0v7a1.78 1.78 0 0 1 -3.1 1.4a1.65 1.65 0 0 0 -2.6 0a1.65 1.65 0 0 1 -2.6 0a1.65 1.65 0 0 0 -2.6 0a1.78 1.78 0 0 1 -3.1 -1.4v-7" />
<path d="M10 10l.01 0" />
<path d="M14 10l.01 0" />
<path d="M10 14a3.5 3.5 0 0 0 4 0" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--timelog">
<!-- clock-hour-5 -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" />
<path d="M12 12l2 3" />
<path d="M12 7v5" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--versionlist">
<!-- layout-list -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M4 4m0 2a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v2a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2z" />
<path d="M4 14m0 2a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v2a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2z" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--project">
<!-- cube -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M21 16.008v-8.018a1.98 1.98 0 0 0 -1 -1.717l-7 -4.008a2.016 2.016 0 0 0 -2 0l-7 4.008c-.619 .355 -1 1.01 -1 1.718v8.018c0 .709 .381 1.363 1 1.717l7 4.008a2.016 2.016 0 0 0 2 0l7 -4.008c.619 -.355 1 -1.01 1 -1.718z" />
<path d="M12 22v-10" />
<path d="M12 12l8.73 -5.04" />
<path d="M3.27 6.96l8.73 5.04" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--issues">
<!-- list-check -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M3.5 5.5l1.5 1.5l2.5 -2.5" />
<path d="M3.5 11.5l1.5 1.5l2.5 -2.5" />
<path d="M3.5 17.5l1.5 1.5l2.5 -2.5" />
<path d="M11 6l9 0" />
<path d="M11 12l9 0" />
<path d="M11 18l9 0" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--issue-add">
<!-- code-plus -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M9 12h6" />
<path d="M12 9v6" />
<path d="M6 19a2 2 0 0 1 -2 -2v-4l-1 -1l1 -1v-4a2 2 0 0 1 2 -2" />
<path d="M18 19a2 2 0 0 0 2 -2v-4l1 -1l-1 -1v-4a2 2 0 0 0 -2 -2" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--vcard">
<!-- credit-card -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M3 5m0 3a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v8a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3z" />
<path d="M3 10l18 0" />
<path d="M7 15l.01 0" />
<path d="M11 15l2 0" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--contact">
<!-- man -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M10 16v5" />
<path d="M14 16v5" />
<path d="M9 9h6l-1 7h-4z" />
<path d="M5 11c1.333 -1.333 2.667 -2 4 -2" />
<path d="M19 11c-1.333 -1.333 -2.667 -2 -4 -2" />
<path d="M12 4m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--contacts">
<!-- friends -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M7 5m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" />
<path d="M5 22v-5l-1 -1v-4a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4l-1 1v5" />
<path d="M17 5m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" />
<path d="M15 22v-4h-2l2 -6a1 1 0 0 1 1 -1h2a1 1 0 0 1 1 1l2 6h-2v4" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--file">
<!-- file -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M14 3v4a1 1 0 0 0 1 1h4" />
<path d="M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--filelist">
<!-- file-description -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M14 3v4a1 1 0 0 0 1 1h4" />
<path d="M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z" />
<path d="M9 17h6" />
<path d="M9 13h6" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--invoice">
<!-- file-euro -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M14 3v4a1 1 0 0 0 1 1h4" />
<path d="M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z" />
<path d="M12 14h-3" />
<path d="M14 11.172a3 3 0 1 0 0 5.656" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--invoice-add">
<!-- receipt-2 -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M5 21v-16a2 2 0 0 1 2 -2h10a2 2 0 0 1 2 2v16l-3 -2l-2 2l-2 -2l-2 2l-2 -2l-3 2" />
<path d="M14 8h-2.5a1.5 1.5 0 0 0 0 3h1a1.5 1.5 0 0 1 0 3h-2.5m2 0v1.5m0 -9v1.5" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--invoice-payment">
<!-- shopping-cart-dollar -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M4 19a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
<path d="M13 17h-7v-14h-2" />
<path d="M6 5l14 1l-.575 4.022m-4.925 2.978h-8.5" />
<path d="M21 15h-2.5a1.5 1.5 0 0 0 0 3h1a1.5 1.5 0 0 1 0 3h-2.5" />
<path d="M19 21v1m0 -8v1" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--wiki">
<!-- brand-wikipedia -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M3 4.984h2" />
<path d="M8 4.984h2.5" />
<path d="M14.5 4.984h2.5" />
<path d="M22 4.984h-2" />
<path d="M4 4.984l5.455 14.516l6.545 -14.516" />
<path d="M9 4.984l6 14.516l6 -14.516" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--wiki-pages">
<!-- world-latitude -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" />
<path d="M4.6 7l14.8 0" />
<path d="M3 12l18 0" />
<path d="M4.6 17l14.8 0" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--import-data">
<!-- database-import -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M4 6c0 1.657 3.582 3 8 3s8 -1.343 8 -3s-3.582 -3 -8 -3s-8 1.343 -8 3" />
<path d="M4 6v6c0 1.657 3.582 3 8 3c.856 0 1.68 -.05 2.454 -.144m5.546 -2.856v-6" />
<path d="M4 12v6c0 1.657 3.582 3 8 3c.171 0 .341 -.002 .51 -.006" />
<path d="M19 22v-6" />
<path d="M22 19l-3 -3l-3 3" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--merge">
<!-- arrow-merge -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M8 7l4 -4l4 4" />
<path d="M12 3v5.394a6.737 6.737 0 0 1 -3 5.606a6.737 6.737 0 0 0 -3 5.606v1.394" />
<path d="M12 3v5.394a6.737 6.737 0 0 0 3 5.606a6.737 6.737 0 0 1 3 5.606v1.394" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--workflow">
<!-- switch-3 -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M3 17h2.397a5 5 0 0 0 4.096 -2.133l.177 -.253m3.66 -5.227l.177 -.254a5 5 0 0 1 4.096 -2.133h3.397" />
<path d="M18 4l3 3l-3 3" />
<path d="M3 7h2.397a5 5 0 0 1 4.096 2.133l4.014 5.734a5 5 0 0 0 4.096 2.133h3.397" />
<path d="M18 20l3 -3l-3 -3" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--show-source">
<!-- zoom-code -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M10 10m-7 0a7 7 0 1 0 14 0a7 7 0 1 0 -14 0" />
<path d="M21 21l-6 -6" />
<path d="M8 8l-2 2l2 2" />
<path d="M12 8l2 2l-2 2" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--db-entry">
<!-- database -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M12 6m-8 0a8 3 0 1 0 16 0a8 3 0 1 0 -16 0" />
<path d="M4 6v6a8 3 0 0 0 16 0v-6" />
<path d="M4 12v6a8 3 0 0 0 16 0v-6" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--password">
<!-- shield-half -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M11.998 2l.032 .002l.086 .005a1 1 0 0 1 .342 .104l.105 .062l.097 .076l.016 .015l.247 .21a11 11 0 0 0 7.189 2.537l.342 -.01a1 1 0 0 1 1.005 .717a13 13 0 0 1 -9.208 16.25a1 1 0 0 1 -.502 0a13 13 0 0 1 -9.209 -16.25a1 1 0 0 1 1.005 -.717a11 11 0 0 0 7.791 -2.75l.046 -.036l.053 -.041a1 1 0 0 1 .217 -.112l.075 -.023l.036 -.01a1 1 0 0 1 .12 -.022l.086 -.005zm.002 2.296l-.176 .135a13 13 0 0 1 -7.288 2.572l-.264 .006l-.064 .31a11 11 0 0 0 1.064 7.175l.17 .314a11 11 0 0 0 6.49 5.136l.068 .019z" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--confidential">
<!-- shield-lock -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M12 3a12 12 0 0 0 8.5 3a12 12 0 0 1 -8.5 15a12 12 0 0 1 -8.5 -15a12 12 0 0 0 8.5 -3" />
<path d="M12 11m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" />
<path d="M12 12l0 2.5" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--confidential-filled">
<!-- shield-lock -->
<g fill="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M11.998 2l.118 .007l.059 .008l.061 .013l.111 .034a.993 .993 0 0 1 .217 .112l.104 .082l.255 .218a11 11 0 0 0 7.189 2.537l.342 -.01a1 1 0 0 1 1.005 .717a13 13 0 0 1 -9.208 16.25a1 1 0 0 1 -.502 0a13 13 0 0 1 -9.209 -16.25a1 1 0 0 1 1.005 -.717a11 11 0 0 0 7.531 -2.527l.263 -.225l.096 -.075a.993 .993 0 0 1 .217 -.112l.112 -.034a.97 .97 0 0 1 .119 -.021l.115 -.007zm.002 7a2 2 0 0 0 -1.995 1.85l-.005 .15l.005 .15a2 2 0 0 0 .995 1.581v1.769l.007 .117a1 1 0 0 0 1.993 -.117l.001 -1.768a2 2 0 0 0 -1.001 -3.732z" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--fullscreen">
<!-- arrows-maximize -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M16 4l4 0l0 4" />
<path d="M14 10l6 -6" />
<path d="M8 20l-4 0l0 -4" />
<path d="M4 20l6 -6" />
<path d="M16 20l4 0l0 -4" />
<path d="M14 14l6 6" />
<path d="M8 4l-4 0l0 4" />
<path d="M4 4l6 6" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--twitter">
<!-- brand-twitter -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M22 4.01c-1 .49 -1.98 .689 -3 .99c-1.121 -1.265 -2.783 -1.335 -4.38 -.737s-2.643 2.06 -2.62 3.737v1c-3.245 .083 -6.135 -1.395 -8 -4c0 0 -4.182 7.433 4 11c-1.872 1.247 -3.739 2.088 -6 2c3.308 1.803 6.913 2.423 10.034 1.517c3.58 -1.04 6.522 -3.723 7.651 -7.742a13.84 13.84 0 0 0 .497 -3.753c0 -.249 1.51 -2.772 1.818 -4.013z" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--github">
<!-- brand-github -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M9 19c-4.3 1.4 -4.3 -2.5 -6 -3m12 5v-3.5c0 -1 .1 -1.4 -.5 -2c2.8 -.3 5.5 -1.4 5.5 -6a4.6 4.6 0 0 0 -1.3 -3.2a4.2 4.2 0 0 0 -.1 -3.2s-1.1 -.3 -3.5 1.3a12.3 12.3 0 0 0 -6.2 0c-2.4 -1.6 -3.5 -1.3 -3.5 -1.3a4.2 4.2 0 0 0 -.1 3.2a4.6 4.6 0 0 0 -1.3 3.2c0 4.6 2.7 5.7 5.5 6c-.6 .6 -.6 1.2 -.5 2v3.5" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--gitlab">
<!-- brand-gitlab -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M21 14l-9 7l-9 -7l3 -11l3 7h6l3 -7z" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--redmine">
<g fill="none" stroke="#a21408" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="m1.092 15.088c.789.243 4.098 1.005 4.098 1.005.198.061.139.21.139.21-.228 1.798-.178 3.17-.178 3.644 0 .21-.153.18-.153.18h-4.83c-.209 0-.164-.19-.164-.19.04-.599.212-2.303.878-4.746 0 0 .033-.157.21-.103zm21.816 0c-.789.243-4.098 1.005-4.098 1.005-.198.061-.139.21-.139.21.228 1.798.178 3.17.178 3.644 0 .21.153.18.153.18h4.83c.21 0 .164-.19.164-.19-.04-.599-.212-2.303-.878-4.746 0 0-.034-.157-.21-.103zm-1.929-5.354-3.448 1.667c-.164.063-.082.212-.082.212.476 1.134.766 2.091.99 3.251.038.194.169.132.169.132l3.879-1.684s.116-.044.068-.193c-.172-.531-1.05-2.649-1.402-3.341 0 0-.062-.105-.174-.044zm-17.958 0 3.448 1.667c.164.063.082.212.082.212-.476 1.134-.766 2.091-.991 3.251-.037.194-.169.132-.169.132l-3.878-1.684s-.116-.044-.068-.193c.172-.531 1.05-2.649 1.402-3.341 0 0 .062-.105.174-.044zm4.085-4.368 2.302 2.681c.099.128-.032.222-.032.222-.923.498-1.59 1.25-2.161 2.111-.114.17-.236.046-.236.046l-2.917-2.184s-.126-.074-.016-.22c.854-1.134 1.63-1.934 2.871-2.689 0 0 .094-.089.189.033zm9.788 0-2.302 2.681c-.099.128.032.222.032.222.923.498 1.59 1.25 2.161 2.111.114.17.236.046.236.046l2.917-2.184s.126-.074.016-.22c-.854-1.134-1.63-1.934-2.871-2.689 0 0-.094-.089-.189.033zm-4.894 2.295c.388 0 1.105.037 1.444.093.177.03.221-.088.221-.088l1.449-3.028s.097-.114-.106-.188c-1.082-.396-1.657-.578-3.008-.578-1.335 0-1.926.182-3.008.578-.203.074-.106.188-.106.188l1.449 3.028s.044.118.221.088c.339-.056 1.056-.093 1.444-.093z" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--add">
<!-- circle-plus -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0" />
<path d="M9 12h6" />
<path d="M12 9v6" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--smiley-smiley">
<!-- mood-smile -->
<g stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
<path stroke-width="1" d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" />
<path d="M9 10l.01 0" />
<path d="M15 10l.01 0" />
<path d="M9.5 15a3.5 3.5 0 0 0 5 0" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--smiley-smiley2">
<!-- mood-smile-beam -->
<g stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
<path stroke-width="1" d="M12 21a9 9 0 1 1 0 -18a9 9 0 0 1 0 18z" />
<path d="M10 10c-.5 -1 -2.5 -1 -3 0" />
<path d="M17 10c-.5 -1 -2.5 -1 -3 0" />
<path d="M14.5 15a3.5 3.5 0 0 1 -5 0" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--smiley-laughing">
<!-- mood-happy -->
<g stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
<path stroke-width="1" d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" />
<path d="M9 9l.01 0" />
<path d="M15 9l.01 0" />
<path d="M8 13a4 4 0 1 0 8 0h-8" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--smiley-laughing2">
<!-- mood-spark -->
<g stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
<path stroke-width="1" d="M21 12a9 9 0 1 0 -8.994 9" />
<path d="M9 10h.01" />
<path d="M15 10h.01" />
<path d="M9.5 15a3.5 3.5 0 0 0 5 0" />
<path d="M19 22.5a4.75 4.75 0 0 1 3.5 -3.5a4.75 4.75 0 0 1 -3.5 -3.5a4.75 4.75 0 0 1 -3.5 3.5a4.75 4.75 0 0 1 3.5 3.5" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--smiley-crying">
<!-- mood-cry -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" />
<path d="M9 10l.01 0" />
<path d="M15 10l.01 0" />
<path d="M9.5 15.25a3.5 3.5 0 0 1 5 0" />
<path d="M17.566 17.606a2 2 0 1 0 2.897 .03l-1.463 -1.636l-1.434 1.606z" />
<path stroke-width="1" d="M20.865 13.517a8.937 8.937 0 0 0 .135 -1.517a9 9 0 1 0 -9 9c.69 0 1.36 -.076 2 -.222" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--smiley-sad">
<!-- mood-sad -->
<g stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
<path stroke-width="1" d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" />
<path d="M9 10l.01 0" />
<path d="M15 10l.01 0" />
<path d="M9.5 15.25a3.5 3.5 0 0 1 5 0" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--smiley-wink">
<!-- mood-wink -->
<g stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
<path stroke-width="1" d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" />
<path d="M15 10h.01" />
<path d="M9.5 15a3.5 3.5 0 0 0 5 0" />
<path d="M8.5 8.5l1.5 1.5l-1.5 1.5" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--smiley-cheeky">
<!-- mood-tongue-wink -->
<g stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
<path stroke-width="1" d="M12 21a9 9 0 1 1 0 -18a9 9 0 0 1 0 18z" />
<path d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" />
<path d="M9 10h.01" />
<path d="M10 14v2a2 2 0 0 0 4 0v-2" />
<path d="M15.5 14h-7" />
<path d="M17 10c-.5 -1 -2.5 -1 -3 0" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--smiley-shock">
<!-- mood-surprised -->
<g stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
<path stroke-width="1" d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" />
<path d="M9 9l.01 0" />
<path d="M15 9l.01 0" />
<path d="M12 15m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--smiley-annoyed">
<!-- mood-angry -->
<g stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
<path stroke-width="1" d="M12 21a9 9 0 1 1 0 -18a9 9 0 0 1 0 18z" />
<path d="M8 9l2 1" />
<path d="M16 9l-2 1" />
<path d="M14.5 16.05a3.5 3.5 0 0 0 -5 0" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--smiley-confuse">
<!-- mood-unamused -->
<g stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
<path stroke-width="1" d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" />
<path d="M11 16l4 -1.5" />
<path d="M10 10c-.5 -1 -2.5 -1 -3 0" />
<path d="M17 10c-.5 -1 -2.5 -1 -3 0" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--smiley-straight">
<!-- mood-nerd -->
<g stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
<path stroke-width="1" d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" />
<path d="M8 10m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" />
<path d="M16 10m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" />
<path d="M9.5 15a3.5 3.5 0 0 0 5 0" />
<path d="M3.5 9h2.5" />
<path d="M18 9h2.5" />
<path d="M10 9.5c1.333 -1.333 2.667 -1.333 4 0" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--smiley-embarrassed">
<!-- mood-sad-dizzy -->
<g stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
<path stroke-width="1" d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" />
<path d="M14.5 16.05a3.5 3.5 0 0 0 -5 0" />
<path d="M8 9l2 2" />
<path d="M10 9l-2 2" />
<path d="M14 9l2 2" />
<path d="M16 9l-2 2" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--smiley-kiss">
<!-- mood-heart -->
<g stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
<path stroke-width="1" d="M21 12a9 9 0 1 0 -8.012 8.946" />
<path d="M9 10h.01" />
<path d="M15 10h.01" />
<path d="M9.5 15a3.59 3.59 0 0 0 2.774 .99" />
<path d="M18.994 21.5l2.518 -2.58a1.74 1.74 0 0 0 .004 -2.413a1.627 1.627 0 0 0 -2.346 -.005l-.168 .172l-.168 -.172a1.627 1.627 0 0 0 -2.346 -.004a1.74 1.74 0 0 0 -.004 2.412l2.51 2.59z" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--smiley-angel">
<!-- mood-boy -->
<g stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
<path stroke-width="1" d="M17 4.5a9 9 0 0 1 3.864 5.89a2.5 2.5 0 0 1 -.29 4.36a9 9 0 0 1 -17.137 0a2.5 2.5 0 0 1 -.29 -4.36a9 9 0 0 1 3.746 -5.81" />
<path d="M9.5 16a3.5 3.5 0 0 0 5 0" />
<path d="M8.5 2c1.5 1 2.5 3.5 2.5 5" />
<path d="M12.5 2c1.5 2 2 3.5 2 5" />
<path d="M9 12l.01 0" />
<path d="M15 12l.01 0" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--smiley-evil">
<!-- mood-wrrr -->
<g stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
<path stroke-width="1" d="M12 21a9 9 0 1 1 0 -18a9 9 0 0 1 0 18z" />
<path d="M8 16l1 -1l1.5 1l1.5 -1l1.5 1l1.5 -1l1 1" />
<path d="M8.5 11.5l1.5 -1.5l-1.5 -1.5" />s
<path d="M15.5 11.5l-1.5 -1.5l1.5 -1.5" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--smiley-rock">
<!-- hand-love-you -->
<g stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
<path stroke-width="1" d="M11 11.5v-1a1.5 1.5 0 0 1 3 0v1.5" />
<path d="M17 12v-6.5a1.5 1.5 0 0 1 3 0v10.5a6 6 0 0 1 -6 6h-2h.208a6 6 0 0 1 -5.012 -2.7a69.74 69.74 0 0 1 -.196 -.3c-.312 -.479 -1.407 -2.388 -3.286 -5.728a1.5 1.5 0 0 1 .536 -2.022a1.867 1.867 0 0 1 2.28 .28l1.47 1.47" />
<path d="M14 10.5a1.5 1.5 0 0 1 3 0v1.5" />
<path d="M8 13v-8.5a1.5 1.5 0 0 1 3 0v7.5" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--smiley-check">
<!-- check -->
<g fill="none" stroke="#40a154" stroke-linecap="round" stroke-linejoin="round" stroke-width="5">
<path d="M5 12l5 5l10 -10" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--smiley-exclamation">
<!-- exclamation-mark -->
<g fill="#e35000" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" />
<path d="M12 9v4" />
<path d="M12 16v.01" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--smiley-question">
<!-- help-circle -->
<g fill="#34a8eb" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0" />
<path d="M12 16v.01" />
<path d="M12 13a2 2 0 0 0 .914 -3.782a1.98 1.98 0 0 0 -2.414 .483" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--smiley-success">
<!-- circle-check -->
<g fill="#71c45e" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" />
<path d="M9 12l2 2l4 -4" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--smiley-failure">
<!-- circle-x -->
<g fill="#e35000" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" />
<path d="M10 10l4 4m0 -4l-4 4" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--thumb-up">
<!-- thumb-up -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M7 11v8a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1 -1v-7a1 1 0 0 1 1 -1h3a4 4 0 0 0 4 -4v-1a2 2 0 0 1 4 0v5h3a2 2 0 0 1 2 2l-1 5a2 3 0 0 1 -2 2h-7a3 3 0 0 1 -3 -3" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--thumb-down">
<!-- thumb-down -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M7 13v-8a1 1 0 0 0 -1 -1h-2a1 1 0 0 0 -1 1v7a1 1 0 0 0 1 1h3a4 4 0 0 1 4 4v1a2 2 0 0 0 4 0v-5h3a2 2 0 0 0 2 -2l-1 -5a2 3 0 0 0 -2 -2h-7a3 3 0 0 0 -3 3" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--at">
<!-- at -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M12 12m-4 0a4 4 0 1 0 8 0a4 4 0 1 0 -8 0" />
<path d="M16 12v1.5a2.5 2.5 0 0 0 5 0v-1.5a9 9 0 1 0 -5.5 8.28" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--map">
<!-- map-pin -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M9 11a3 3 0 1 0 6 0a3 3 0 0 0 -6 0" />
<path d="M17.657 16.657l-4.243 4.243a2 2 0 0 1 -2.827 0l-4.244 -4.243a8 8 0 1 1 11.314 0z" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--company">
<!-- building-skyscraper -->
<g fill="none" stroke="#b5b1b1" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M3 21l18 0" />
<path d="M5 21v-14l8 -4v18" />
<path d="M19 21v-10l-6 -4" />
<path d="M9 9l0 .01" />
<path d="M9 12l0 .01" />
<path d="M9 15l0 .01" />
<path d="M9 18l0 .01" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--person">
<!-- user-scan -->
<g fill="none" stroke="#b5b1b1" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M10 9a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
<path d="M4 8v-2a2 2 0 0 1 2 -2h2" />
<path d="M4 16v2a2 2 0 0 0 2 2h2" />
<path d="M16 4h2a2 2 0 0 1 2 2v2" />
<path d="M16 20h2a2 2 0 0 0 2 -2v-2" />
<path d="M8 16a2 2 0 0 1 2 -2h4a2 2 0 0 1 2 2" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--unknown-user">
<!-- spy -->
<g fill="none" stroke="#b5b1b1" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M3 11h18" />
<path d="M5 11v-4a3 3 0 0 1 3 -3h8a3 3 0 0 1 3 3v4" />
<path d="M7 17m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0" />
<path d="M17 17m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0" />
<path d="M10 17h4" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--arrow-right">
<!-- arrow-right -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M5 12l14 0" />
<path d="M13 18l6 -6" />
<path d="M13 6l6 6" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--read">
<!-- eye-check -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
<path d="M11.102 17.957c-3.204 -.307 -5.904 -2.294 -8.102 -5.957c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6a19.5 19.5 0 0 1 -.663 1.032" />
<path d="M15 19l2 2l4 -4" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--two-person-rule">
<!-- scan-eye -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M4 8v-2a2 2 0 0 1 2 -2h2" />
<path d="M4 16v2a2 2 0 0 0 2 2h2" />
<path d="M16 4h2a2 2 0 0 1 2 2v2" />
<path d="M16 20h2a2 2 0 0 0 2 -2v-2" />
<path d="M7 12c3.333 -4.667 6.667 -4.667 10 0" />
<path d="M7 12c3.333 4.667 6.667 4.667 10 0" />
<path d="M12 12h-.01" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--checks">
<!-- checks -->
<g fill="none" stroke="#b5b1b1" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M7 12l5 5l10 -10" />
<path d="M2 12l5 5m5 -5l5 -5" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--lock">
<!-- lock -->
<g fill="none" stroke="#b5b1b1" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M5 13a2 2 0 0 1 2 -2h10a2 2 0 0 1 2 2v6a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2v-6z" />
<path d="M11 16a1 1 0 1 0 2 0a1 1 0 0 0 -2 0" />
<path d="M8 11v-4a4 4 0 1 1 8 0v4" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--lock-filled">
<!-- lock -->
<g fill="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M12 2a5 5 0 0 1 5 5v3a3 3 0 0 1 3 3v6a3 3 0 0 1 -3 3h-10a3 3 0 0 1 -3 -3v-6a3 3 0 0 1 3 -3v-3a5 5 0 0 1 5 -5m0 12a2 2 0 0 0 -1.995 1.85l-.005 .15a2 2 0 1 0 2 -2m0 -10a3 3 0 0 0 -3 3v3h6v-3a3 3 0 0 0 -3 -3" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--key">
<!-- key -->
<g fill="none" stroke="#b5b1b1" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M16.555 3.843l3.602 3.602a2.877 2.877 0 0 1 0 4.069l-2.643 2.643a2.877 2.877 0 0 1 -4.069 0l-.301 -.301l-6.558 6.558a2 2 0 0 1 -1.239 .578l-.175 .008h-1.172a1 1 0 0 1 -.993 -.883l-.007 -.117v-1.172a2 2 0 0 1 .467 -1.284l.119 -.13l.414 -.414h2v-2h2v-2l2.144 -2.144l-.301 -.301a2.877 2.877 0 0 1 0 -4.069l2.643 -2.643a2.877 2.877 0 0 1 4.069 0z" />
<path d="M15 9h.01" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--shield">
<!-- shield -->
<g fill="none" stroke="#b5b1b1" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M12 3a12 12 0 0 0 8.5 3a12 12 0 0 1 -8.5 15a12 12 0 0 1 -8.5 -15a12 12 0 0 0 8.5 -3" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--shield-filled">
<!-- shield filled -->
<g fill="none" stroke="#b5b1b1" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M11.884 2.007l.114 -.007l.118 .007l.059 .008l.061 .013l.111 .034a.993 .993 0 0 1 .217 .112l.104 .082l.255 .218a11 11 0 0 0 7.189 2.537l.342 -.01a1 1 0 0 1 1.005 .717a13 13 0 0 1 -9.208 16.25a1 1 0 0 1 -.502 0a13 13 0 0 1 -9.209 -16.25a1 1 0 0 1 1.005 -.717a11 11 0 0 0 7.531 -2.527l.263 -.225l.096 -.075a.993 .993 0 0 1 .217 -.112l.112 -.034a.97 .97 0 0 1 .119 -.021z" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--shield-check">
<!-- shield-check -->
<g fill="none" stroke="#b5b1b1" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M11.46 20.846a12 12 0 0 1 -7.96 -14.846a12 12 0 0 0 8.5 -3a12 12 0 0 0 8.5 3a12 12 0 0 1 -.09 7.06" />
<path d="M15 19l2 2l4 -4" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--shield-check-filled">
<!-- shield-check filled -->
<g fill="none" stroke="#b5b1b1" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M11.998 2l.118 .007l.059 .008l.061 .013l.111 .034a.993 .993 0 0 1 .217 .112l.104 .082l.255 .218a11 11 0 0 0 7.189 2.537l.342 -.01a1 1 0 0 1 1.005 .717a13 13 0 0 1 -9.208 16.25a1 1 0 0 1 -.502 0a13 13 0 0 1 -9.209 -16.25a1 1 0 0 1 1.005 -.717a11 11 0 0 0 7.531 -2.527l.263 -.225l.096 -.075a.993 .993 0 0 1 .217 -.112l.112 -.034a.97 .97 0 0 1 .119 -.021l.115 -.007zm3.71 7.293a1 1 0 0 0 -1.415 0l-3.293 3.292l-1.293 -1.292l-.094 -.083a1 1 0 0 0 -1.32 1.497l2 2l.094 .083a1 1 0 0 0 1.32 -.083l4 -4l.083 -.094a1 1 0 0 0 -.083 -1.32z" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--calendar-work">
<!-- calendar-week -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M4 7a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2v-12z" />
<path d="M16 3v4" />
<path d="M8 3v4" />
<path d="M4 11h16" />
<path d="M8 14v4" />
<path d="M12 14v4" />
<path d="M16 14v4" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--calendar-holiday">
<!-- calendar-smile -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M4 7a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2v-12zm12 -4v4m-8 -4v4m-4 4h16m-9.995 3h.01m3.99 0h.01" />
<path d="M10.005 17a3.5 3.5 0 0 0 4 0" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--member">
<!-- heart-handshake -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M19.5 12.572l-7.5 7.428l-7.5 -7.428a5 5 0 1 1 7.5 -6.566a5 5 0 1 1 7.5 6.572" />
<path d="M12 6l-3.293 3.293a1 1 0 0 0 0 1.414l.543 .543c.69 .69 1.81 .69 2.5 0l1 -1a3.182 3.182 0 0 1 4.5 0l2.25 2.25" />
<path d="M12.5 15.5l2 2" />
<path d="M15 13l2 2" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" id="icon--group">
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M10 13a2 2 0 1 0 4 0a2 2 0 0 0 -4 0"/>
<path d="M8 21v-1a2 2 0 0 1 2 -2h4a2 2 0 0 1 2 2v1"/>
<path d="M15 5a2 2 0 1 0 4 0a2 2 0 0 0 -4 0"/>
<path d="M17 10h2a2 2 0 0 1 2 2v1"/>
<path d="M5 5a2 2 0 1 0 4 0a2 2 0 0 0 -4 0"/>
<path d="M3 13v-1a2 2 0 0 1 2 -2h2"/>
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--calendar-absence">
<!-- calendar-user -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M12 21h-6a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v4.5" />
<path d="M16 3v4" />
<path d="M8 3v4" />
<path d="M4 11h16" />
<path d="M19 17m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" />
<path d="M22 22a2 2 0 0 0 -2 -2h-2a2 2 0 0 0 -2 2" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--user">
<!-- user -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M8 7a4 4 0 1 0 8 0a4 4 0 0 0 -8 0" />
<path d="M6 21v-2a4 4 0 0 1 4 -4h4a4 4 0 0 1 4 4v2" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--attendance">
<!-- exclamation-circle -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" />
<path d="M12 9v4" />
<path d="M12 16v.01" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--hrm">
<!-- user-circle -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" />
<path d="M12 10m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0" />
<path d="M6.168 18.849a4 4 0 0 1 3.832 -2.849h4a4 4 0 0 1 3.834 2.855" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--resources">
<!-- clock -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0" />
<path d="M12 7v5l3 3" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--report">
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M4 20h3" />
<path d="M17 20h3" />
<path d="M10.5 20h3" />
<path d="M4 16h3" />
<path d="M17 16h3" />
<path d="M10.5 16h3" />
<path d="M4 12h3" />
<path d="M17 12h3" />
<path d="M10.5 12h3" />
<path d="M4 8h3" />
<path d="M17 8h3" />
<path d="M4 4h3" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--log">
<!-- book-2 -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M19 4v16h-12a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h12z" />
<path d="M19 16h-12a2 2 0 0 0 -2 2" />
<path d="M9 8h6" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--details">
<!-- info-circle -->
<g fill="currentColor">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M12 2c5.523 0 10 4.477 10 10a10 10 0 0 1 -19.995 .324l-.005 -.324l.004 -.28c.148 -5.393 4.566 -9.72 9.996 -9.72zm0 9h-1l-.117 .007a1 1 0 0 0 0 1.986l.117 .007v3l.007 .117a1 1 0 0 0 .876 .876l.117 .007h1l.117 -.007a1 1 0 0 0 .876 -.876l.007 -.117l-.007 -.117a1 1 0 0 0 -.764 -.857l-.112 -.02l-.117 -.006v-3l-.007 -.117a1 1 0 0 0 -.876 -.876l-.117 -.007zm.01 -3l-.127 .007a1 1 0 0 0 0 1.986l.117 .007l.127 -.007a1 1 0 0 0 0 -1.986l-.117 -.007z" />
</g>
</symbol>
<symbol viewBox="0 0 24 24" id="icon--meeting">
<!-- brand-ubuntu -->
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M12 5m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" />
<path d="M17.723 7.41a7.992 7.992 0 0 0 -3.74 -2.162m-3.971 0a7.993 7.993 0 0 0 -3.789 2.216m-1.881 3.215a8 8 0 0 0 -.342 2.32c0 .738 .1 1.453 .287 2.132m1.96 3.428a7.993 7.993 0 0 0 3.759 2.19m4 0a7.993 7.993 0 0 0 3.747 -2.186m1.962 -3.43a8.008 8.008 0 0 0 .287 -2.131c0 -.764 -.107 -1.503 -.307 -2.203" />
<path d="M5 17m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" />
<path d="M19 17m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" />
</g>
</symbol>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 524 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 317 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 248 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 874 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 759 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 925 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 862 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 790 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 869 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 820 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 856 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 863 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 830 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 890 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 911 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 806 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 832 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 808 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 795 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 840 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 850 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 899 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 933 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

View File

@ -67,7 +67,7 @@ function observeLiveSearchField(fieldId, targetId, target_url) {
var url;
form.find('[name="c[]"] option').each(function(i, elem) {
$(elem).attr('selected', true);
$(elem).prop('selected', true);
});
if (typeof target_url === 'undefined') {
@ -79,7 +79,7 @@ function observeLiveSearchField(fieldId, targetId, target_url) {
}
form.find('[name="c[]"] option').each(function(i, elem) {
$(elem).attr('selected', false);
$(elem).prop('selected', false);
});
$.ajax({

View File

@ -97,10 +97,10 @@ function addOptionTags($select, field, values) {
if ($.isArray(filterValue)) {
option.val(filterValue[1]).text(filterValue[0]);
if ($.inArray(filterValue[1], values) > -1) { option.attr('selected', true); }
if ($.inArray(filterValue[1], values) > -1) { option.prop('selected', true); }
} else {
option.val(filterValue).text(filterValue);
if ($.inArray(filterValue, values) > -1) { option.attr('selected', true); }
if ($.inArray(filterValue, values) > -1) { option.prop('selected', true); }
}
$select.append(option);

View File

@ -36,6 +36,104 @@ fieldset.hide-attachments {
width: 90%;
}
/* Icons */
.external-links a.external,
em.info a.external {
background-image: url('../../../images/external.png');
padding-left: 14px;
background-position: 0% 60%;
background-repeat: no-repeat;
}
.flex-center {
display: flex;
align-items: center;
}
.a-icon,
.a-icon-only {
display: inline-flex;
vertical-align: middle;
}
.a-icon.icon-padding,
.a-svg-icon.icon-padding {
padding-right: 2px;
}
ul.dashboard-list {
padding-left: 20px;
margin-top: 0;
}
#context-menu .a-icon {
padding: 0;
display: inline-flex;
}
.drdn-items a.a-icon {
padding: 2px;
display: flex;
}
span.a-icon-label,
h3.a-icon-label {
margin-left: 4px;
}
svg.a-icon-svg {
stroke: #169;
fill: none;
stroke-width: 1.5;
vertical-align: middle;
}
svg.a-svg-icon.smiley {
fill: #edae40;
stroke-width: 2;
}
svg.a-s64 {
width: 64px;
height: 64px;
}
svg.a-s32 {
width: 32px;
height: 32px;
}
svg.a-s24 {
width: 1.5rem;
height: 1.5rem;
}
svg.a-s20 {
width: 1.25rem;
height: 1.25rem;
}
svg.a-s18 {
width: 1.125rem;
height: 1.125rem;
}
svg.a-s16 {
width: 1rem;
height: 1rem;
}
svg.a-s14 {
width: 0.875rem;
height: 0.875rem;
}
svg.a-s12 {
width: 0.75rem;
height: 0.75rem;
}
/* Mobile menu style FontAwesome icon */
.flyout-is-active #admin-menu li a.additionals {
padding-left: 8px !important;
@ -47,19 +145,9 @@ fieldset.hide-attachments {
/* Go to top link */
.gototop {
display: block;
margin-top: 20px;
padding: 10px 0;
text-align: right;
clear: both;
}
.gototop::before {
font-family: 'Font Awesome 5 Free';
font-weight: 900;
content: '\f139'; /* fas fa-chevron-circle-up */
padding-right: 4px;
opacity: 0.8;
padding: 10px 0;
}
/* Footer */
@ -93,38 +181,6 @@ additionals-emoji {
}
/* stylelint-enable selector-type-no-unknown */
/* Legacy smilie classes */
.smiley {
background-repeat: no-repeat;
display: inline-block;
width: 16px;
height: 16px;
}
.smiley-smiley { background-image: url('../images/smileys/smiley.png'); }
.smiley-smiley2 { background-image: url('../images/smileys/smiley2.png'); }
.smiley-laughing { background-image: url('../images/smileys/smiley-grin.png'); }
.smiley-laughing2 { background-image: url('../images/smileys/smiley-laughing2.png'); }
.smiley-crying { background-image: url('../images/smileys/smiley-cry.png'); }
.smiley-sad { background-image: url('../images/smileys/smiley-sad.png'); }
.smiley-wink { background-image: url('../images/smileys/smiley-wink.png'); }
.smiley-cheeky { background-image: url('../images/smileys/smiley-razz.png'); }
.smiley-shock { background-image: url('../images/smileys/smiley-eek.png'); }
.smiley-annoyed { background-image: url('../images/smileys/smiley-annoyed.png'); }
.smiley-confuse { background-image: url('../images/smileys/smiley-confuse.png'); }
.smiley-straight { background-image: url('../images/smileys/smiley-neutral.png'); }
.smiley-embarrassed { background-image: url('../images/smileys/smiley-red.png'); }
.smiley-kiss { background-image: url('../images/smileys/smiley-kiss.png'); }
.smiley-angel { background-image: url('../images/smileys/smiley-angel.png'); }
.smiley-evil { background-image: url('../images/smileys/smiley-evil.png'); }
.smiley-rock { background-image: url('../images/smileys/smiley-cool.png'); }
.smiley-check { background-image: url('../images/smileys/check.png'); }
.smiley-exclamation { background-image: url('../images/smileys/exclamation-red-frame.png'); }
.smiley-question { background-image: url('../images/smileys/question-frame.png'); }
.smiley-success { background-image: url('../images/smileys/success-frame.png'); }
.smiley-failure { background-image: url('../images/smileys/failure-frame.png'); }
div.clear-both { clear: both; }
/* fix problem with tabs */
@ -147,15 +203,28 @@ div.clear-both { clear: both; }
img.additionals-avatar { margin-right: 0.25em; }
h2#page-title {
display: inline-flex;
padding-left: 0;
}
h2#page-title input {
font-size: 16px;
}
h2#page-title::before {
font-family: 'Font Awesome 5 Free';
padding-right: 5px;
text-shadow: 0 2px 0 #efefef;
font-size: 90%;
.with-list-seperator::after {
padding-left: 0.5rem;
padding-right: 0.5rem;
content: '»';
}
h2#page-title.live-search input {
margin-left: 5px;
}
h2#page-title.import::before {
font-weight: 900;
content: '\f093'; /* fas fa-upload */
}
/* Tooltips */
@ -169,23 +238,6 @@ h2#page-title::before {
box-shadow: 0 0 6px #888;
}
/* Live search */
h2#page-title.live-search input {
margin-left: 5px;
}
h2#page-title.import::before {
font-weight: 900;
content: '\f093'; /* fas fa-upload */
}
a.external.redmine-link {
background-image: url('../images/redmine-link.png');
background-position: 0% 40%;
padding-left: 13px;
background-repeat: no-repeat;
}
div.macro-box {
margin-bottom: 15px;
}
@ -299,7 +351,7 @@ table.table-of-values caption {
/* stylelint-disable selector-class-pattern */
.jstb_macros {
background-image: url('../images/jstoolbar/bt_macros.png');
background-image: url('../images/bt_macros.svg');
}
/* stylelint-enable selector-class-pattern */

View File

@ -216,3 +216,7 @@ de:
wiki_pdf_remove_attachments_info: Wenn aktiv, werden die an der Wiki Seite angehängten Dateien nicht in der PDF Ansicht angezeigt.
wiki_pdf_remove_title_info: Wenn aktiv, wird der Wiki Titel nicht in der PDF Ansicht angezeigt.
label_default_sort_by: Standard-Sortierreihenfolge
notice_unsuccessful_save: Konnte nicht gespeichert werden
notice_save_error_with_messages: "Speichern nicht erfolgreich. Folgende Fehler sind aufgetreten: %{errors}"
notice_unsuccessful_delete: Konnte nicht gelöscht werden
notice_delete_error_with_messages: "Löschen nicht erfolgreich. Folgende Fehler sind aufgetreten: %{errors}"

View File

@ -216,3 +216,7 @@ en:
wiki_pdf_remove_attachments_info: "When active the attached Wiki files will not be displayed in PDF view."
wiki_pdf_remove_title_info: "When active the Wiki title info will not be displayed in PDF view."
label_default_sort_by: Default sort by
notice_unsuccessful_save: Save problems
notice_save_error_with_messages: "Save problems with following errors: %{errors}"
notice_unsuccessful_delete: Delete problems
notice_delete_error_with_messages: "Delete problems with following errors: %{errors}"

View File

@ -132,6 +132,7 @@ module Additionals
loader.add_patch [{ target: Redmine::Views::LabelledFormBuilder, patch: 'LabelledFormBuilder' }]
loader.add_global_helper [Additionals::Helpers,
AdditionalsIconsHelper,
AdditionalsFontawesomeHelper,
AdditionalsMenuHelper,
AdditionalsSelect2Helper]

View File

@ -25,6 +25,8 @@ module Additionals
'success' => '[\[(]v[\])]', # (v)
'failure' => '[\[(]x[\])]' }.freeze # (x)
NON_SMILEY_COLOR = %w[exclamation question check success failure].freeze
def render_inline_smileys(text)
return text if text.blank?
@ -40,7 +42,13 @@ module Additionals
esc = Regexp.last_match 2
smiley = Regexp.last_match 3
if esc.nil?
leading.to_s + ActionController::Base.helpers.tag.span(class: "additionals smiley smiley-#{name}",
css_class = NON_SMILEY_COLOR.exclude?(name) ? 'smiley' : 'info-smiley'
svg_code = ActionController::Base.helpers.svg_sprite_icon "smiley-#{name}",
css_class:,
title: smiley
leading.to_s + ActionController::Base.helpers.tag.span(svg_code,
class: "additionals smiley a-icon smiley-#{name}",
title: smiley)
else
leading.to_s + smiley

View File

@ -2,23 +2,39 @@
module Additionals
module Helpers
def entry_page_title(name:, obj: nil, obj_link: nil, query: nil)
title = []
def render_breadcrumb(items)
cnt = items.length
titles = items.each_with_index.map do |item, index|
css_classes = +'breadcrumb-item'
css_classes << ' with-list-seperator' if index < cnt - 1
tag.span item, class: css_classes
end
safe_join titles
end
def entry_page_title(name, obj: nil, obj_link: nil, query: nil, icon_name: nil)
items = []
case obj
when Issue
title << link_to(h("#{obj.subject} ##{obj.id}"),
items << link_to(h("#{obj.subject} ##{obj.id}"),
issue_path(obj),
class: obj.css_classes)
when User
title << user_with_avatar(obj, no_link: true, size: 50)
items << user_with_avatar(obj, no_link: true, size: 50)
else
title << obj_link if obj_link
items << obj_link if obj_link
end
title << name if name
title << h(query.name) if query && !query.new_record?
items << (name.is_a?(Symbol) ? l(name) : name)
items << h(query.name) if query && !query.new_record?
safe_join title, Additionals::LIST_SEPARATOR
page_title = []
page_title << svg_icon_tag(icon_name, css_class: 'icon-padding', size: 24) if icon_name
page_title << render_breadcrumb(items)
safe_join page_title
end
def label_with_count(label, info, only_positive: false)

View File

@ -5,6 +5,7 @@ module Additionals
class ViewHook < Redmine::Hook::ViewListener
include IssuesHelper
include AdditionalsIssuesHelper
include AdditionalsIconsHelper
render_on :view_layouts_base_html_head, partial: 'additionals/html_head'
render_on :view_layouts_base_body_top, partial: 'additionals/body_top'
@ -44,7 +45,8 @@ module Additionals
controller_name == 'account' && action_name == 'lost_password' ||
!Additionals.setting?(:add_go_to_top)
link_to l(:label_go_to_top), '#gototop', class: 'gototop'
tag.div link_to(svg_icon_tag('page-up', label: :label_go_to_top), '#gototop', class: 'a-icon icon-page-up'),
class: 'gototop'
end
end
end

View File

@ -11,6 +11,56 @@ module Additionals
end
module InstanceMethods
def render_flash_mail(mail, name = nil)
content = "#{name} <span class=\"icon icon-email\">#{mail}</span>"
return content if name.blank?
"#{name} #{content}"
end
def flash_msg(msg, value: nil, code: nil, mail: nil, errors: nil, obj: nil, field: :id)
return msg unless msg.is_a? Symbol
skip_field_info = false
message = case msg
when :save_error
if obj.present? && obj.errors.full_messages.present?
skip_field_info = true
l :notice_save_error_with_messages, errors: errors.full_messages.to_comma_list
else
l :notice_unsuccessful_save
end
when :delete_error
if obj.present? && obj.errors.full_messages.present?
skip_field_info = true
l :notice_delete_error_with_messages, errors: errors.full_messages.to_comma_list
else
l :notice_unsuccessful_delete
end
when :create
l :notice_successful_create
when :update
l :notice_successful_update
when :delete
l :notice_successful_delete
else
if mail.present?
l msg, render_flash_mail(mail)
elsif value.present?
l msg, value
elsif code.present?
l msg, "<em>#{value}</em>"
else
l msg
end
end
message << " (#{obj.send field})" if !skip_field_info && obj
message
end
def enable_smileys
return if !Additionals.setting?(:legacy_smiley_support) ||
Redmine::WikiFormatting::Textile::Formatter::RULES.include?(:inline_smileys)

View File

@ -7,6 +7,7 @@ module Additionals
included do
include AdditionalsQueriesHelper
include AdditionalsIconsHelper
include InstanceMethods
before_action :find_search_term

View File

@ -55,7 +55,7 @@ module Additionals
link_options = { class: 'redmine-link' }
link_options[:title] = options[:title].presence || l(:label_redmine_org_issue)
link_to_external "##{link_name}", link, **link_options
link_to_external svg_icon_tag('redmine', label: "##{link_name}", size: 12), link, **link_options
end
end
end

View File

@ -50,7 +50,7 @@ module Additionals
link_options = { class: 'external redmine-link' }
link_options[:title] = options[:title].presence || l(:label_redmine_org_wiki)
link_to options[:name], link, link_options
link_to svg_icon_tag('redmine', label: options[:name], size: 12), link, link_options
end
end
end

View File

@ -173,6 +173,22 @@ module Additionals
assert_select "table.list.#{table_css}.sort-by-#{column_css}.sort-desc"
end
def assert_locales_validness(plugin:, file_cnt:, locales:, control_string:, control_english:)
lang_files_count = Rails.root.glob("plugins/#{plugin}/config/locales/*.yml").size
assert_equal file_cnt, lang_files_count
valid_languages.each do |lang|
assert set_language_if_valid(lang)
if lang.to_s == 'en'
assert_equal control_english, l(control_string)
elsif locales.include? lang.to_s
assert_not l(control_string) == control_english, lang
end
end
set_language_if_valid 'en'
end
def assert_dashboard_query_blocks(blocks = [])
blocks.each do |block_def|
block_def[:user_id]

View File

@ -37,8 +37,17 @@ module Additionals
end
end
def smiley_test_span(text)
"<span class=\"additionals smiley a-icon smiley-smiley\" title=\":)\">#{text}</span>"
end
def svg_test_icon
'<svg class="a-s18 a-svg-icon smiley" title=":)" aria-hidden="true">' \
'<use href="/plugin_assets/additionals/images/icons.svg#icon--smiley-smiley"></use></svg>'
end
def emoji_heart_tag
'<additionals-emoji title="heavy black heart" data-name="heart" data-unicode-version="1.1">❤</additionals-emoji>'
'<additionals-emoji title="red heart" data-name="red_heart" data-unicode-version="6.0">❤️</additionals-emoji>'
end
end

View File

@ -20,21 +20,10 @@ class I18nTest < Additionals::TestCase
end
def test_locales_validness
lang_files_count = Rails.root.glob('plugins/additionals/config/locales/*.yml').size
assert_equal 13, lang_files_count
valid_languages.each do |lang|
assert set_language_if_valid(lang)
case lang.to_s
when 'en'
assert_equal 'Open external URLs', l(:label_open_external_urls)
when 'pt-BR', 'cs', 'de', 'es', 'fr', 'it', 'ja', 'ko', 'po', 'ru', 'zh-TW', 'zh'
assert_not l(:label_open_external_urls) == 'Open external URLs', lang
end
end
set_language_if_valid 'en'
assert_locales_validness plugin: 'additionals',
file_cnt: 13,
locales: %w[pt-BR cs de es fr it ja ko po ru zh-TW zh],
control_string: :label_open_external_urls,
control_english: 'Open external URLs'
end
end

View File

@ -10,14 +10,14 @@ module WikiFormatting
@options = {}
end
def test_smilies
def test_smileys
with_plugin_settings 'additionals', legacy_smiley_support: 1,
emoji_support: 0 do
input = <<~HTML
A small test :) with an smiley
HTML
expected = <<~HTML
A small test <span class="additionals smiley smiley-smiley" title=":)"></span> with an smiley
A small test #{smiley_test_span svg_test_icon} with an smiley
HTML
assert_equal expected, smiley_filter(input)
end

View File

@ -12,12 +12,12 @@ module WikiFormatting
@formatter = Redmine::WikiFormatting::Markdown::Formatter
end
def test_smilies
def test_smileys
with_plugin_settings 'additionals', legacy_smiley_support: 1,
emoji_support: 0 do
text = 'A small test :) with an smilie'
assert_equal '<p>A small test <span class="additionals smiley smiley-smiley" title=":)"></span> with an smilie</p>',
assert_equal "<p>A small test #{smiley_test_span svg_test_icon} with an smilie</p>",
@formatter.new(text).to_html.strip
end
end
@ -32,19 +32,17 @@ module WikiFormatting
end
end
def test_smilies_and_emojies
def test_smileys_and_emojies
with_plugin_settings 'additionals', legacy_smiley_support: 1,
emoji_support: 1 do
text = ':heart: and :)'
assert_equal "<p>#{emoji_heart_tag}" \
' and <span class="additionals smiley smiley-smiley" title=":)"></span></p>',
assert_equal "<p>#{emoji_heart_tag} and #{smiley_test_span svg_test_icon}</p>",
@formatter.new(text).to_html.strip
text = ' :) and :heart:'
assert_equal '<p><span class="additionals smiley smiley-smiley" title=":)"></span> and' \
" #{emoji_heart_tag}</p>",
assert_equal "<p>#{smiley_test_span svg_test_icon} and #{emoji_heart_tag}</p>",
@formatter.new(text).to_html.strip
end
end

View File

@ -12,15 +12,15 @@ module WikiFormatting
@to_test = {}
end
def test_smilies
def test_smileys
with_plugin_settings 'additionals', legacy_smiley_support: 1,
emoji_support: 0 do
# this is required, because inline_smileys are activated with controller action
@formatter::RULES << :inline_smileys
@to_test['A test with a :) smiley'] = 'A test with a <span class="additionals smiley smiley-smiley" title=":)"></span> smiley'
@to_test[':) :)'] = '<span class="additionals smiley smiley-smiley" title=":)"></span>' \
' <span class="additionals smiley smiley-smiley" title=":)"></span>'
@to_test['A test with a :) smiley'] =
"A test with a #{smiley_test_span svg_test_icon} smiley"
@to_test[':) :)'] = "#{smiley_test_span svg_test_icon} #{smiley_test_span svg_test_icon}"
assert_html_output @to_test
end
@ -38,16 +38,14 @@ module WikiFormatting
end
end
def test_smilies_and_emojies
def test_smileys_and_emojies
with_plugin_settings 'additionals', legacy_smiley_support: 1,
emoji_support: 1 do
# this is required, because inline_smileys are activated with controller action
@formatter::RULES << :inline_smileys
@to_test[':heart: and :)'] = "#{emoji_heart_tag}" \
' and <span class="additionals smiley smiley-smiley" title=":)"></span>'
@to_test[':) and :heart:'] = '<span class="additionals smiley smiley-smiley" title=":)"></span> and' \
" #{emoji_heart_tag}"
@to_test[':heart: and :)'] = "#{emoji_heart_tag} and #{smiley_test_span svg_test_icon}"
@to_test[':) and :heart:'] = "#{smiley_test_span svg_test_icon} and #{emoji_heart_tag}"
assert_html_output @to_test
end