Skip to content

Commit 152f71d

Browse files
committed
Merge branch '6.0/theme-page-in-htmx'
2 parents 517aa3f + 6fe39ef commit 152f71d

File tree

12 files changed

+74
-603
lines changed

12 files changed

+74
-603
lines changed

devel/third-party/README

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,6 @@ Origin: https://github.com/NicolasCARPi/dropzone
4747
License: MIT
4848
Note that this version is in a new, maintained fork from the original project.
4949

50-
51-
* eyedropper.svg
52-
Description: color picker icon
53-
Origin: http://thenounproject.com/noun/eye-dropper/ (The Noun Project)
54-
Author: The Noun Project
55-
License: CC BY 3.0
56-
5750
* htmx-2.0.3
5851
Description: htmx gives you access to AJAX, CSS Transitions, WebSockets and Server Sent Events directly in HTML, using attributes, so you can build modern user interfaces with the simplicity and power of hypertext
5952
Origin: https://github.com/bigskysoftware/htmx

devel/third-party/eyedropper.svg

Lines changed: 0 additions & 13 deletions
This file was deleted.

lib/RT/Interface/Web/MenuBuilder.pm

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1485,9 +1485,6 @@ sub _BuildAdminTopMenu {
14851485
title => loc('Theme'),
14861486
description => loc('Customize the look of your RT'),
14871487
path => '/Admin/Tools/Theme.html',
1488-
attributes => {
1489-
'hx-boost' => 'false',
1490-
},
14911488
);
14921489
if (RT->Config->Get('StatementLog')
14931490
&& $current_user->HasRight( Right => 'SuperUser', Object => RT->System )) {

share/html/Admin/Tools/Theme.html

Lines changed: 72 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,14 @@
5151
<& /Elements/Tabs &>
5252
<& /Elements/ListActions, actions => \@results &>
5353

54-
<script type="text/javascript" src="<%RT->Config->Get('WebPath')%>/static/js/farbtastic.js"></script>
55-
56-
<div class="row">
54+
<div class="row mt-3">
5755

5856
<div id="simple-customize" class="col-6">
5957
<div id="upload-logo">
60-
<h2>Logo</h2>
61-
<& /Elements/Logo, id => 'logo-theme-editor', ShowName => 0 &>
62-
<button onclick="setLogoSize()" class="button btn btn-primary form-control" id="logo-size"><&|/l&>Full Size</&></button>
63-
58+
<h3>Logo</h3>
59+
<div class="border border-secondary-subtle rounded">
60+
<& /Elements/Logo, id => 'logo-theme-editor', ShowName => 0 &>
61+
</div>
6462
<form method="POST" enctype="multipart/form-data" action="">
6563
<div class="row mt-2">
6664
<div class="col-auto">
@@ -75,14 +73,47 @@ <h2>Logo</h2>
7573
<&|/l&>GD is disabled or not installed. You can upload an image, but you won't get automatic color suggestions.</&>
7674
% }
7775
</div>
78-
<input class="button btn btn-primary" name="reset_logo" value="<&|/l&>Reset to default RT Logo</&>" type="submit" />
79-
<input class="button btn btn-primary" type="submit" value="<&|/l&>Upload</&>" />
76+
<input class="button btn btn-primary mt-1" name="reset_logo" value="<&|/l&>Reset to default RT Logo</&>" type="submit" />
77+
<input class="button btn btn-primary mt-1" type="submit" value="<&|/l&>Upload</&>" />
8078
</form>
8179
</div>
80+
81+
<hr />
82+
83+
<div id="customize-theme" class="">
84+
<h3><&|/l&>Customize the RT theme</&></h3>
85+
<&| /Elements/LabeledValue, Label => loc('Select a section') &>
86+
<select class="form-select selectpicker" id="section" name="section">
87+
% for my $section ( @sections ) {
88+
<option value="<% $section->[0] %>"><% $section->[0] %></option>
89+
% };
90+
</select>
91+
</&>
92+
93+
<&| /Elements/LabeledValue, Label => loc('Select a color for the section') &>
94+
<div class="row">
95+
% if ($colors) {
96+
<div class="col button btn btn-primary primary-colors">
97+
% for (@$colors) {
98+
% my $fg = $_->{l} >= $text_threshold ? 'black' : 'white';
99+
<button type="button" class="button btn btn-primary color-template form-control"
100+
style="background-color: rgb(<% $_->{c} %>); color: <% $fg %>;">
101+
<&|/l&>Text</&>
102+
</button>
103+
% }
104+
</div>
105+
% }
106+
<div class="col">
107+
<input type="color" class="form-control" id="color-picker" />
108+
</div>
109+
</div>
110+
</&>
111+
</div>
112+
82113
</div>
83114

84115
<div id="custom-css" class="col-6">
85-
<h2><&|/l&>Custom CSS (Advanced)</&></h2>
116+
<h3><&|/l&>Custom CSS (Advanced)</&></h3>
86117

87118
<form method="POST" id="custom-css-form" action="">
88119
<textarea class="form-control mb-2" rows="20" id="user_css" name="user_css" wrap="off"><% $user_css %></textarea>
@@ -94,41 +125,6 @@ <h2><&|/l&>Custom CSS (Advanced)</&></h2>
94125
</div>
95126
</div>
96127

97-
<br>
98-
99-
<div class="row">
100-
<div id="customize-theme" class="col-6">
101-
<h2><&|/l&>Customize the RT theme</&></h2>
102-
<ol class="list-group-compact list-group">
103-
<li class="list-group-item">
104-
<label for="section"><&|/l&>Select a section</&>:</label>
105-
<select class="selectpicker" id="section"></select>
106-
</li>
107-
<li class="list-group-item">
108-
<div class="description">
109-
<&|/l&>Select a color for the section</&>:
110-
<div id="logo-picker-hint" style="display: none;">
111-
<&|/l&>You can also click on the logo above to get colors!</&>
112-
</div>
113-
</div>
114-
% if ($colors) {
115-
<div class="button btn btn-primary primary-colors">
116-
% for (@$colors) {
117-
% my $fg = $_->{l} >= $text_threshold ? 'black' : 'white';
118-
<button type="button" class="button btn btn-primary color-template form-control"
119-
style="background-color: rgb(<% $_->{c} %>); color: <% $fg %>;">
120-
<&|/l&>Text</&>
121-
</button>
122-
% }
123-
</div>
124-
% }
125-
<div id="color-picker"></div>
126-
<canvas id="logo-color-picker" title="<&|/l&>Click to choose a color</&>"></canvas>
127-
</li>
128-
</ol>
129-
</div>
130-
</div>
131-
132128
<%ONCE>
133129
my @sections = (
134130
['Page' => ['body', 'div#body']],
@@ -146,25 +142,11 @@ <h2><&|/l&>Customize the RT theme</&></h2>
146142
</%ONCE>
147143
<script type="text/javascript">
148144
var section_css_mapping = <% JSON(\@sections) |n%>;
149-
150145
jQuery(function($) {
151-
152-
jQuery.each(section_css_mapping, function(i,v){
153-
$('select#section').append($("<option/>")
154-
.attr('value', v[0])
155-
.text(v[0]));
156-
});
157-
// Refresh selectpicker so we have a default value, at least for Firefox
158-
$('select#section').val(section_css_mapping[0][0]);
159-
160146
function update_sitecss(text) {
161147
if (!text)
162148
text = $('#user_css').val();
163-
164-
// IE 8 doesn't let us update the innerHTML of <style> tags (with jQuery.text())
165-
// see: http://stackoverflow.com/questions/2692770/style-style-textcss-appendtohead-does-not-work-in-ie/2692861#2692861
166-
$("style#sitecss").remove();
167-
$("<style id='sitecss' type='text/css' media='all'>" + text + "</style>").appendTo('head');
149+
$("style#sitecss").text(text);
168150
}
169151

170152
update_sitecss();
@@ -225,73 +207,43 @@ <h2><&|/l&>Customize the RT theme</&></h2>
225207
update_sitecss(css);
226208
}
227209

228-
$('#color-picker').farbtastic(function(color){ change_color(color, this.hsl[2] > <% $text_threshold %> ? '#000' : '#fff') });
210+
document.querySelector('#color-picker').addEventListener('change', function() {
211+
const red = parseInt('0x' + this.value.substr(1,2));
212+
const green = parseInt('0x' + this.value.substr(3,2));
213+
const blue = parseInt('0x' + this.value.substr(5,2));
214+
const lightness = (Math.max(red, green, blue) + Math.min(red, green, blue))/2/255;
215+
change_color(this.value, lightness > <% $text_threshold %> ? '#000' : '#fff');
216+
});
229217

230218
$('button.color-template').click(function() {
231219
change_color($(this).css('background-color'), $(this).css('color'));
232-
});
233-
234-
});
235-
236-
// Setup the canvas color picker
237-
jQuery(window).on('load',function() {
238-
var $ = jQuery;
239-
var logo = $("#logo-theme-editor img");
240-
var canvas = $("#logo-color-picker");
241-
var el_canvas = canvas.get(0);
220+
});
242221

243-
if (!el_canvas.getContext) return;
244222

245-
setLogoSize();
223+
document.getElementById('section').addEventListener('change', event => {
224+
const section = event.target.value;
225+
const selector = section_css_mapping.filter( a => { return a[0] == section })[0][1][0];
226+
const specials = new RegExp("([.*+?|()\\[\\]{}\\\\])", "g");
227+
const escaped_selector = selector.replace(specials, "\\$1");
228+
const rule = new RegExp('^'+escaped_selector+'\\s*\{\\s*background:\\s*(#\\w+|rgb\\((\\d+),\\s*(\\d+),\\s*(\\d+)\\))', "m");
229+
const css = document.getElementById('user_css').value;
230+
const result = css.match(rule);
231+
if ( result ) {
232+
if ( result[2] ) {
233+
document.getElementById('color-picker').value =
234+
'#' + result.slice(2, 5).map(num => parseInt(num).toString(16).padStart(2, '0')).join('');
235+
}
236+
else {
237+
document.getElementById('color-picker').value = result[1];
238+
}
239+
}
240+
else {
241+
document.getElementById('color-picker').value = '#ffffff';
242+
}
243+
});
244+
document.getElementById('section').dispatchEvent(new Event('change'));
246245
});
247246

248-
function setLogoSize() {
249-
var logo = jQuery("#logo-theme-editor img");
250-
var canvas = jQuery("#logo-color-picker");
251-
var el_canvas = canvas.get(0);
252-
253-
if (!el_canvas.getContext) return;
254-
// Set logo to same size as CSS input
255-
var container = jQuery('#user_css');
256-
257-
var context = el_canvas.getContext("2d");
258-
var button = jQuery('#logo-size');
259-
260-
if ( button.text() == '<&|/l&>Preview</&>' ) {
261-
var ratio = Math.min(container.width() / logo.width(), container.height() / logo.height());
262-
263-
el_canvas.width = logo.width()*ratio;
264-
el_canvas.height = logo.height()*ratio;
265-
266-
// Re-draw our scaled down image
267-
context.drawImage(logo.get(0), 0, 0, logo.width()*ratio, logo.height()*ratio );
268-
269-
button.text( "<&|/l&>Full Size</&>" );
270-
}
271-
else {
272-
el_canvas.width = logo.width();
273-
el_canvas.height = logo.height();
274-
275-
context.drawImage(logo.get(0), 0, 0);
276-
button.text( "<&|/l&>Preview</&>" );
277-
}
278-
279-
logo.hide().after(canvas);
280-
canvas.show().click(function(ev) {
281-
ev.preventDefault();
282-
var R = 0,
283-
G = 1,
284-
B = 2,
285-
A = 3;
286-
var pixel = this.getContext("2d").getImageData(ev.offsetX, ev.offsetY, 1, 1).data;
287-
// Farbtastic expects values in the range of 0..1
288-
var rgba = jQuery.makeArray(pixel).map(function(v,i) { return v / 255 });
289-
var wheel = jQuery.farbtastic("#color-picker");
290-
wheel.setHSL( wheel.RGBToHSL( rgba.slice(R,A) ) );
291-
// XXX TODO factor in the alpha channel too
292-
});
293-
jQuery('#logo-picker-hint').show();
294-
}
295247
</script>
296248
<%INIT>
297249
unless ($session{'CurrentUser'}->HasRight( Object=> RT->System, Right => 'SuperUser')) {

share/html/Elements/Logo

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,11 @@
4949
% if ($user_logo) {
5050
<a href="<%$ARGS{'LogoLinkURL'}||RT->Config->Get('LogoLinkURL')%>"><img
5151
src="<% RT->Config->Get('WebPath') %>/NoAuth/Helpers/CustomLogo/<% $user_logo->Content->{'hash'} %>"
52-
alt="<%loc($ARGS{'LogoAltText'}||RT->Config->Get('LogoAltText'))%>" /></a>
52+
alt="<%loc($ARGS{'LogoAltText'}||RT->Config->Get('LogoAltText'))%>" class="mw-100" /></a>
5353
% } else {
5454
<a href="<%$ARGS{'LogoLinkURL'}||RT->Config->Get('LogoLinkURL')%>"><img
5555
src="<%$ARGS{'LogoURL'}||RT->Config->Get('LogoURL')%>"
56-
alt="<%loc($ARGS{'LogoAltText'}||RT->Config->Get('LogoAltText'))%>" /></a>
56+
alt="<%loc($ARGS{'LogoAltText'}||RT->Config->Get('LogoAltText'))%>" class="mw-100" /></a>
5757
% }
5858
% if ( $ShowName ) {
5959
<span class="rtname"><% $Name || loc("RT for [_1]", RT->Config->Get('rtname')) %></span>

share/static/css/elevator/farbtastic.css

Lines changed: 0 additions & 51 deletions
This file was deleted.

share/static/css/elevator/main.css

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
@import "jquery-ui.css";
22
@import "jquery-ui-timepicker-addon.css";
33
@import "tablesorter.css";
4-
@import "farbtastic.css";
54
@import "bootstrap.css";
65
@import "bootstrap-combobox.css";
76
@import "dropzone.css";
@@ -16,7 +15,6 @@
1615
@import "nav.css";
1716
@import "ticket-form.css";
1817
@import "rights-editor.css";
19-
@import "theme-editor.css";
2018
@import "ticket.css";
2119
@import "accordion.css";
2220
@import "record.css";

0 commit comments

Comments
 (0)