Skip to content

Commit

Permalink
Change users selectors from select2 to tom-select
Browse files Browse the repository at this point in the history
  • Loading branch information
alexrlpz committed Feb 12, 2025
1 parent f1ba807 commit 1a828fa
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 185 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ class ConversationsController < Admin::ApplicationController
def index
enforce_permission_to :index, :config

@users = Author.for(current_component).map { |user| OpenStruct.new(text: format_user_name(user), id: user.decidim_user_id) }
@note_takers = Author.for(current_component).note_takers.map { |user| OpenStruct.new(text: format_user_name(user), id: user.decidim_user_id) }
@users = Author.for(current_component).map(&:decidim_user_id)
@note_takers = Author.for(current_component).note_takers.map(&:decidim_user_id)
@form = form(NotifyConfigForm).from_params(current_component.attributes["settings"]["global"])
end

Expand Down
1 change: 0 additions & 1 deletion app/packs/entrypoints/decidim_notify_component.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import "src/decidim/notify/notify.js"
import "src/decidim/notify/notify_selects"
import "src/decidim/notify/notify_channel"
import "select2"

// Images
require.context("../images", true)
Expand Down
117 changes: 17 additions & 100 deletions app/packs/src/decidim/notify/notify_selects.js
Original file line number Diff line number Diff line change
@@ -1,103 +1,20 @@
// I haven't found a way to include jquery plugins without making webpack repeat jQuery itself
// the workaround is to use CDN providers and include them via standard <script> before any javascript_pack_tag
// require("select2/src/js/jquery.select2.js")
import TomSelect from "tom-select/dist/cjs/tom-select.popular";

$(() => {
$("select.multiusers-select").each(function() {
const url = $(this).attr("data-url");
$(this).select2({
ajax: {
url: url,
delay: 100,
dataType: "json",
processResults: (data) => {
return {
results: data
}
}
},
escapeMarkup: (markup) => markup,
templateSelection: (item) => `${item.text}`,
minimumInputLength: 1,
theme: "foundation"
});
});
document.addEventListener("DOMContentLoaded", () => {
const tagContainers = document.querySelectorAll("#users_list");

Check failure on line 4 in app/packs/src/decidim/notify/notify_selects.js

View workflow job for this annotation

GitHub Actions / Lint

Expected indentation of 2 spaces but found 4
tagContainers.forEach((container) => {
const { tmName, tmItems, tmNoResults } = container.dataset
const config = {
plugins: ["remove_button", "dropdown_input"],
allowEmptyOption: true,
items: JSON.parse(tmItems),
render: {
item: (data, escape) => `<div>${escape(data.text)}<input type="hidden" name="${tmName}[]" value="${data.value}" /></div>`,
// eslint-disable-next-line camelcase
...(tmNoResults && { no_results: () => `<div class="no-results">${tmNoResults}</div>` })
}
};

$("select.user-select").each(function() {
const url = $(this).attr("data-url");
const placeholder = $(this).attr("placeholder");
$(this).select2({
ajax: {
url: url,
delay: 100,
dataType: "json",
processResults: (data) => {
return {
results: data
}
}
},
minimumInputLength: 1,
placeholder: placeholder,
theme: "foundation",
allowClear: true,
selectOnClose: true,
escapeMarkup: (markup) => markup,
templateSelection: (item) => `<b>${item.id}</b> - ${item.text}`,
templateResult: (item) => {
console.log(item)
return `<div class="select2-result-repository">
<div class="select2-result-repository__avatar" style="background-image:url(${item.avatar || window.Notify.defaultAvatar})">
<div class="hex1"></div><div class="hex2"></div>
</div>
<div class="select2-result-repository__meta">
<b>${item.id}</b> - ${item.text}
</div>
</div>`;
}
});

$(this).on("select2:open", () => $(".select2-search__field").select());
$(this).on("select2:close", () => $("#note_body").select());
$(this).on("select2:clear", function () {
$(this).on("select2:opening.cancelOpen", function (evt) {
evt.preventDefault();

$(this).off("select2:opening.cancelOpen");
});
});
});

$("select.chapter-select").each(function() {
const placeholder = $(this).attr("placeholder");

$(this).select2({
selectOnClose: true,
tags: true,
allowClear: true,
theme: "foundation",
placeholder: placeholder,
createTag: function (params) {
let term = $.trim(params.term);

if (term === "") {
return null;
}
let n = {
id: term,
text: term
}
return n;
}
});

$(this).on("select2:close", () => $("#note_body").select());
$(this).on("select2:clear", function () {
$(this).on("select2:opening.cancelOpen", function (evt) {
evt.preventDefault();

$(this).off("select2:opening.cancelOpen");
});
});
});
return new TomSelect(container, config)
})
});
52 changes: 1 addition & 51 deletions app/packs/stylesheets/decidim/notify/notify.scss
Original file line number Diff line number Diff line change
@@ -1,63 +1,13 @@
// From Decidicim core
@import "stylesheets/decidim/legacy/variables";
// From npm package
// @import "select2/dist/css/select2.css";
@import "select2-foundation-theme";
@import "tom-select/dist/scss/tom-select";
@import "hexagon";

// we need to hide the original select otherwise focus is lost
.select2-hidden-accessible {
display: none;
}

.button--double{
width: fit-content;
}

.select2-container--foundation {
width: 100% !important;
.select2-dropdown {
border-radius: 4px;
}
.select2-search--dropdown .select2-search__field {
border-radius: 4px;
&:focus {
border-color:#333;
}
}
.select2-selection {
border-radius: 4px;
}
.select2-results__option--highlighted[aria-selected] {
background-color: rgba(var(--secondary-rgb), 0.5);
}
.select2-result-repository {
display: flex;
&__avatar {
@include responsive_hexagon();
}
&__meta {
flex: 1;
align-self: center;
margin-left: 1rem;
color: black;
font-weight: bold;
word-wrap: break-word;
line-height: 1.1;
margin-bottom: 4px;
}
}
.select2-selection--single .select2-selection__clear,
.selection .select2-selection--single .select2-selection__clear {
margin-right: 20px;
background: #ddd;
border-radius: 50%;
line-height: 1;
height: 20px;
width: 20px;
}
}

.notify-announcement {
background-color: rgba(255, 255, 255, 1);
}
Expand Down
34 changes: 27 additions & 7 deletions app/views/decidim/notify/admin/conversations/_form.html.erb
Original file line number Diff line number Diff line change
@@ -1,10 +1,30 @@
<div class="row column">
<%= form.select :users, options_from_collection_for_select(@users, :id, :text, proc { true }), { include_blank: false }, { class: "multiusers-select", multiple: true, data: { url: users_path } } %>
</div>
<label for="users_list">
<%= t("users", scope: "activemodel.attributes.notify_config") %>
<select id="users_list"
placeholder="<%= t("users_picker.choose_users", scope: "decidim.notify.admin.conversations") %>"
data-tm-name="users"
data-tm-items="<%= @users.to_json %>"
data-tm-no-results="No users"
class="mt-4" multiple>
<% current_organization.users.pluck(:id, :name).each do |id, name| %>
<option value="<%= id %>"><%= name %> </option>
<% end %>
</select>
</label>

<div class="row column">
<%= form.select :note_takers, options_from_collection_for_select(@note_takers, :id, :text, proc { true }), { include_blank: false }, { class: "multiusers-select", multiple: true, data: { url: users_path } } %>
</div>
<label for="users_list">
<%= t("note_takers", scope: "activemodel.attributes.notify_config") %>
<select id="users_list"
placeholder="<%= t("users_picker.choose_users", scope: "decidim.notify.admin.conversations") %>"
data-tm-name="note_takers"
data-tm-items="<%= @note_takers.to_json %>"
data-tm-no-results="No users"
class="mt-4" multiple>
<% current_organization.users.pluck(:id, :name).each do |id, name| %>
<option value="<%= id %>"><%= name %> </option>
<% end %>
</select>
</label>

<div class="row column">
<div class="switch tiny switch-with-label restricted">
Expand All @@ -16,7 +36,7 @@
</div>
</div>

<div class="row column">
<div class="row column pb-4">
<div class="switch tiny switch-with-label private">
<%= form.label :private do %>
<%= form.check_box :private, label: false, class: "switch-input" %>
Expand Down
16 changes: 6 additions & 10 deletions app/views/decidim/notify/admin/conversations/index.html.erb
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
<div class="card">
<div class="card-divider">
<h2 class="card-title">
<div class="item_show__header">
<h1 class="item_show__header-title">
<%= t(".title") %>
<div class="button--title">
<%= link_to t("actions.configure", scope: "decidim.admin"), Decidim::EngineRouter.admin_proxy(current_component.participatory_space).edit_component_path(current_component.id), class: "button tiny button--simple" %>
</div>
<div class="button--title">
<%= link_to t(".chapters"), chapters_path, class: "button tiny button--simple" %>
</div>
</h2>
<%= link_to t(".chapters"), chapters_path, class: "button button__sm button__secondary" %>
<%= render partial: "decidim/admin/components/resource_action" %>
</h1>
</div>

<div class="card-section multiusers-select-container">
Expand All @@ -17,7 +13,7 @@

<%= render partial: "form", object: f %>

<div class="button--double form-conversations-submit">
<div class="button button__sm button__secondary">
<%= f.submit t(".save") %>
</div>
<% end %>
Expand Down
13 changes: 1 addition & 12 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@
"dependencies": {
"@decidim/browserslist-config": "^0.28.4",
"@decidim/webpacker": "^0.28.4",
"@rails/actioncable": "6.1.7",
"select2": "^4.1.0-rc.0"
"@rails/actioncable": "6.1.7"
},
"browserslist": ["extends @decidim/browserslist-config"]
}

0 comments on commit 1a828fa

Please sign in to comment.