advanced_select 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +3 -2
- data/app/javascript/advanced_select/advanced_select_controller.js +56 -0
- data/app/views/advanced_select/_options.html.erb +5 -3
- data/app/views/advanced_select/_select.html.erb +3 -1
- data/config/locales/en.yml +1 -0
- data/config/locales/tr.yml +1 -0
- data/lib/advanced_select/helper.rb +60 -2
- data/lib/advanced_select/version.rb +1 -1
- data/lib/generators/advanced_select/install/templates/advanced_select_controller.js +74 -2
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 254f883547b3f323b98150becc0db7f8ff76f609a9a7186a5d1eb8903a0afb7f
|
|
4
|
+
data.tar.gz: 56b4d1866feaad22d4c4ed00bb2ab573240dbedda3d2f7cc6a1759c7da53b571
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f6a74b01aed5465044972b7f89d75148a9192120d8bba05e7a212899a11715198a3a4743092e329e1dc8ae4ccb0c86c2ab21ccafb48b88fa52059212b6d4acc3
|
|
7
|
+
data.tar.gz: 9df6c7b80f331cdc57fabaddce592f1f899728fe643d73ac3c98149acdb6b9f4c7a559e2fd87113655338ece19695fcfed7fbb6b570808bf02395f44c568301b
|
data/README.md
CHANGED
|
@@ -316,11 +316,12 @@ Use local options when the complete option list is already available while rende
|
|
|
316
316
|
id: "record_item_id",
|
|
317
317
|
selected: selected_option,
|
|
318
318
|
options: options,
|
|
319
|
-
placeholder: t(".item_placeholder")
|
|
320
|
-
searchable: false
|
|
319
|
+
placeholder: t(".item_placeholder")
|
|
321
320
|
) %>
|
|
322
321
|
```
|
|
323
322
|
|
|
323
|
+
Local selects are searchable by default. Set `searchable: false` when the option list should open without a search field.
|
|
324
|
+
|
|
324
325
|
Options are hashes:
|
|
325
326
|
|
|
326
327
|
```ruby
|
|
@@ -7,6 +7,7 @@ export default class extends Controller {
|
|
|
7
7
|
addMode: Boolean,
|
|
8
8
|
delay: { type: Number, default: 200 },
|
|
9
9
|
dependentFields: Object,
|
|
10
|
+
emptyText: String,
|
|
10
11
|
errorText: String,
|
|
11
12
|
includeHidden: { type: Boolean, default: true },
|
|
12
13
|
inputId: String,
|
|
@@ -29,6 +30,7 @@ export default class extends Controller {
|
|
|
29
30
|
this.tokenClass = this.element.dataset.advancedSelectTokenClass || "ui-advanced-select-token"
|
|
30
31
|
this.loadingClass = this.element.dataset.advancedSelectLoadingClass || "ui-advanced-select-loading"
|
|
31
32
|
this.errorClass = this.element.dataset.advancedSelectErrorClass || "ui-advanced-select-error"
|
|
33
|
+
this.emptyClass = this.element.dataset.advancedSelectEmptyClass || "ui-advanced-select-empty"
|
|
32
34
|
this.optionActiveClasses = this.classList(this.element.dataset.advancedSelectOptionActiveClass || "ui-advanced-select-option-active")
|
|
33
35
|
this.addOptionActiveClasses = this.classList(this.element.dataset.advancedSelectAddOptionActiveClass || "")
|
|
34
36
|
this.optionSelectedClasses = this.classList(this.element.dataset.advancedSelectOptionSelectedClass || "")
|
|
@@ -81,6 +83,12 @@ export default class extends Controller {
|
|
|
81
83
|
}
|
|
82
84
|
|
|
83
85
|
search() {
|
|
86
|
+
if (!this.urlValue) {
|
|
87
|
+
this.filterOptions()
|
|
88
|
+
this.activate(-1)
|
|
89
|
+
return
|
|
90
|
+
}
|
|
91
|
+
|
|
84
92
|
window.clearTimeout(this.timer)
|
|
85
93
|
this.renderLoading()
|
|
86
94
|
this.activate(-1)
|
|
@@ -127,9 +135,57 @@ export default class extends Controller {
|
|
|
127
135
|
clearSearch() {
|
|
128
136
|
if (this.searchableValue) {
|
|
129
137
|
this.searchTarget.value = ""
|
|
138
|
+
|
|
139
|
+
if (!this.urlValue) {
|
|
140
|
+
this.filterOptions()
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
filterOptions() {
|
|
146
|
+
const query = this.normalize(this.searchTarget.value)
|
|
147
|
+
const container = this.currentOptionsTarget
|
|
148
|
+
let visibleCount = 0
|
|
149
|
+
let currentGroup = null
|
|
150
|
+
let groupHasMatch = false
|
|
151
|
+
|
|
152
|
+
Array.from(container.children).forEach((child) => {
|
|
153
|
+
if (child.hasAttribute("data-advanced-select-group-label")) {
|
|
154
|
+
if (currentGroup) currentGroup.classList.toggle("hidden", !groupHasMatch)
|
|
155
|
+
currentGroup = child
|
|
156
|
+
groupHasMatch = false
|
|
157
|
+
} else if (child.hasAttribute("data-advanced-select-option")) {
|
|
158
|
+
const match = this.normalize(child.dataset.advancedSelectLabelParam).includes(query)
|
|
159
|
+
child.classList.toggle("hidden", !match)
|
|
160
|
+
if (match) {
|
|
161
|
+
visibleCount += 1
|
|
162
|
+
groupHasMatch = true
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
if (currentGroup) currentGroup.classList.toggle("hidden", !groupHasMatch)
|
|
168
|
+
|
|
169
|
+
this.toggleEmptyState(visibleCount === 0)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
toggleEmptyState(empty) {
|
|
173
|
+
const container = this.currentOptionsTarget
|
|
174
|
+
let emptyState = container.querySelector("[data-advanced-select-empty-state]")
|
|
175
|
+
|
|
176
|
+
if (empty && !emptyState) {
|
|
177
|
+
emptyState = this.textElement("div", this.emptyClass, this.emptyTextValue)
|
|
178
|
+
emptyState.setAttribute("data-advanced-select-empty-state", "")
|
|
179
|
+
container.appendChild(emptyState)
|
|
180
|
+
} else if (!empty && emptyState) {
|
|
181
|
+
emptyState.remove()
|
|
130
182
|
}
|
|
131
183
|
}
|
|
132
184
|
|
|
185
|
+
normalize(text) {
|
|
186
|
+
return (text || "").trim().toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "")
|
|
187
|
+
}
|
|
188
|
+
|
|
133
189
|
fetchOptions({ selected = false } = {}) {
|
|
134
190
|
if (!this.urlValue) {
|
|
135
191
|
return
|
|
@@ -4,13 +4,15 @@
|
|
|
4
4
|
aria-busy="false"
|
|
5
5
|
<% if local_assigns[:multiple] %>aria-multiselectable="true"<% end %>
|
|
6
6
|
role="listbox">
|
|
7
|
+
<% selected_option_ids = advanced_select_selected_option_ids(selected_options) %>
|
|
8
|
+
|
|
7
9
|
<% advanced_select_option_groups(options).each do |group| %>
|
|
8
10
|
<% if group[:label].present? %>
|
|
9
|
-
<div class="<%= advanced_select_class(class_map, :group_label) %>"><%= group.fetch(:label) %></div>
|
|
11
|
+
<div class="<%= advanced_select_class(class_map, :group_label) %>" data-advanced-select-group-label><%= group.fetch(:label) %></div>
|
|
10
12
|
<% end %>
|
|
11
13
|
|
|
12
14
|
<% group.fetch(:options).each do |option| %>
|
|
13
|
-
<%=
|
|
15
|
+
<%= advanced_select_option_tag(option, selected_options, option_content_partial, class_map, selected_option_ids: selected_option_ids) %>
|
|
14
16
|
<% end %>
|
|
15
17
|
<% end %>
|
|
16
18
|
|
|
@@ -26,6 +28,6 @@
|
|
|
26
28
|
<%= t("shared.advanced_select.add_option", query: query) %>
|
|
27
29
|
</button>
|
|
28
30
|
<% elsif advanced_select_options_empty?(options) %>
|
|
29
|
-
<div class="<%= advanced_select_class(class_map, :empty) %>"><%= t("shared.advanced_select.empty") %></div>
|
|
31
|
+
<div class="<%= advanced_select_class(class_map, :empty) %>" data-advanced-select-empty-state><%= t("shared.advanced_select.empty") %></div>
|
|
30
32
|
<% end %>
|
|
31
33
|
</div>
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
data-advanced-select-name-value="<%= name %>"
|
|
6
6
|
data-advanced-select-input-id-value="<%= id %>"
|
|
7
7
|
data-advanced-select-placeholder-value="<%= placeholder %>"
|
|
8
|
+
data-advanced-select-empty-text-value="<%= t("shared.advanced_select.empty") %>"
|
|
8
9
|
data-advanced-select-loading-text-value="<%= t("shared.advanced_select.loading") %>"
|
|
9
10
|
data-advanced-select-error-text-value="<%= t("shared.advanced_select.error") %>"
|
|
10
11
|
data-advanced-select-dependent-fields-value="<%= dependent_fields.to_json %>"
|
|
@@ -15,6 +16,7 @@
|
|
|
15
16
|
data-advanced-select-placeholder-class="<%= advanced_select_class(class_map, :placeholder) %>"
|
|
16
17
|
data-advanced-select-value-class="<%= advanced_select_class(class_map, :value) %>"
|
|
17
18
|
data-advanced-select-token-class="<%= advanced_select_class(class_map, :token) %>"
|
|
19
|
+
data-advanced-select-empty-class="<%= advanced_select_class(class_map, :empty) %>"
|
|
18
20
|
data-advanced-select-loading-class="<%= advanced_select_class(class_map, :loading) %>"
|
|
19
21
|
data-advanced-select-error-class="<%= advanced_select_class(class_map, :error) %>"
|
|
20
22
|
data-advanced-select-option-active-class="<%= advanced_select_state_class(class_map, :option_active) %>"
|
|
@@ -56,7 +58,7 @@
|
|
|
56
58
|
<%= tag.input type: "search",
|
|
57
59
|
id: "#{id}_search",
|
|
58
60
|
autocomplete: "off",
|
|
59
|
-
placeholder:
|
|
61
|
+
placeholder: t("shared.advanced_select.search_placeholder"),
|
|
60
62
|
class: advanced_select_class(class_map, :search),
|
|
61
63
|
data: {
|
|
62
64
|
advanced_select_target: "search",
|
data/config/locales/en.yml
CHANGED
data/config/locales/tr.yml
CHANGED
|
@@ -12,7 +12,7 @@ module AdvancedSelect
|
|
|
12
12
|
options: options,
|
|
13
13
|
placeholder: placeholder,
|
|
14
14
|
multiple: multiple,
|
|
15
|
-
searchable: searchable
|
|
15
|
+
searchable: searchable,
|
|
16
16
|
add_mode: add_mode,
|
|
17
17
|
dependent_fields: dependent_fields,
|
|
18
18
|
include_hidden: include_hidden,
|
|
@@ -60,6 +60,56 @@ module AdvancedSelect
|
|
|
60
60
|
end.to_json
|
|
61
61
|
end
|
|
62
62
|
|
|
63
|
+
def advanced_select_option_tag(option, selected_options, option_content_partial, class_map, selected_option_ids: nil)
|
|
64
|
+
selected = advanced_select_option_selected?(option, selected_options, selected_option_ids)
|
|
65
|
+
|
|
66
|
+
tag.button(
|
|
67
|
+
type: "button",
|
|
68
|
+
class: advanced_select_class(class_map, :option, (:option_selected if selected)),
|
|
69
|
+
role: "option",
|
|
70
|
+
aria: { selected: selected },
|
|
71
|
+
data: {
|
|
72
|
+
advanced_select_option: "",
|
|
73
|
+
action: "mouseenter->advanced-select#activateOption mousedown->advanced-select#choose",
|
|
74
|
+
advanced_select_value_param: option.fetch(:id),
|
|
75
|
+
advanced_select_submit_value_param: advanced_select_option_value(option),
|
|
76
|
+
advanced_select_label_param: advanced_select_option_label(option),
|
|
77
|
+
advanced_select_display_label_param: advanced_select_option_display_label(option)
|
|
78
|
+
}
|
|
79
|
+
) do
|
|
80
|
+
safe_join([
|
|
81
|
+
tag.span(
|
|
82
|
+
(selected ? "\u2713" : ""),
|
|
83
|
+
class: advanced_select_class(class_map, :option_check),
|
|
84
|
+
data: { advanced_select_option_check: "" }
|
|
85
|
+
),
|
|
86
|
+
advanced_select_option_content_tag(option, option_content_partial, class_map)
|
|
87
|
+
])
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def advanced_select_option_content_tag(option, option_content_partial, class_map)
|
|
92
|
+
if option_content_partial.present?
|
|
93
|
+
render partial: option_content_partial, locals: { option: option }
|
|
94
|
+
else
|
|
95
|
+
advanced_select_default_option_content_tag(option, class_map)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def advanced_select_default_option_content_tag(option, class_map)
|
|
100
|
+
description = advanced_select_option_description(option)
|
|
101
|
+
content = [tag.span(advanced_select_option_label(option))]
|
|
102
|
+
|
|
103
|
+
if description.present?
|
|
104
|
+
content << tag.span(
|
|
105
|
+
description,
|
|
106
|
+
class: advanced_select_class(class_map, :option_description)
|
|
107
|
+
)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
tag.span(safe_join(content), class: advanced_select_class(class_map, :option_content))
|
|
111
|
+
end
|
|
112
|
+
|
|
63
113
|
def advanced_select_options_for_render(options, selected_options, searchable)
|
|
64
114
|
searchable ? selected_options.presence || options : options
|
|
65
115
|
end
|
|
@@ -83,7 +133,15 @@ module AdvancedSelect
|
|
|
83
133
|
end
|
|
84
134
|
end
|
|
85
135
|
|
|
86
|
-
def
|
|
136
|
+
def advanced_select_selected_option_ids(selected_options)
|
|
137
|
+
selected_options.each_with_object({}) do |selected_option, selected_option_ids|
|
|
138
|
+
selected_option_ids[selected_option.fetch(:id).to_s] = true
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def advanced_select_option_selected?(option, selected_options, selected_option_ids = nil)
|
|
143
|
+
return selected_option_ids.key?(option.fetch(:id).to_s) if selected_option_ids
|
|
144
|
+
|
|
87
145
|
selected_options.any? { |selected_option| selected_option.fetch(:id).to_s == option.fetch(:id).to_s }
|
|
88
146
|
end
|
|
89
147
|
|
|
@@ -7,7 +7,9 @@ export default class extends Controller {
|
|
|
7
7
|
addMode: Boolean,
|
|
8
8
|
delay: { type: Number, default: 200 },
|
|
9
9
|
dependentFields: Object,
|
|
10
|
+
emptyText: String,
|
|
10
11
|
errorText: String,
|
|
12
|
+
includeHidden: { type: Boolean, default: true },
|
|
11
13
|
inputId: String,
|
|
12
14
|
loadingText: String,
|
|
13
15
|
multiple: Boolean,
|
|
@@ -28,6 +30,7 @@ export default class extends Controller {
|
|
|
28
30
|
this.tokenClass = this.element.dataset.advancedSelectTokenClass || "ui-advanced-select-token"
|
|
29
31
|
this.loadingClass = this.element.dataset.advancedSelectLoadingClass || "ui-advanced-select-loading"
|
|
30
32
|
this.errorClass = this.element.dataset.advancedSelectErrorClass || "ui-advanced-select-error"
|
|
33
|
+
this.emptyClass = this.element.dataset.advancedSelectEmptyClass || "ui-advanced-select-empty"
|
|
31
34
|
this.optionActiveClasses = this.classList(this.element.dataset.advancedSelectOptionActiveClass || "ui-advanced-select-option-active")
|
|
32
35
|
this.addOptionActiveClasses = this.classList(this.element.dataset.advancedSelectAddOptionActiveClass || "")
|
|
33
36
|
this.optionSelectedClasses = this.classList(this.element.dataset.advancedSelectOptionSelectedClass || "")
|
|
@@ -37,6 +40,7 @@ export default class extends Controller {
|
|
|
37
40
|
displayLabel: option.displayLabel || option.label
|
|
38
41
|
}))
|
|
39
42
|
this.close = this.close.bind(this)
|
|
43
|
+
this.renderOptionsState()
|
|
40
44
|
}
|
|
41
45
|
|
|
42
46
|
disconnect() {
|
|
@@ -79,6 +83,12 @@ export default class extends Controller {
|
|
|
79
83
|
}
|
|
80
84
|
|
|
81
85
|
search() {
|
|
86
|
+
if (!this.urlValue) {
|
|
87
|
+
this.filterOptions()
|
|
88
|
+
this.activate(-1)
|
|
89
|
+
return
|
|
90
|
+
}
|
|
91
|
+
|
|
82
92
|
window.clearTimeout(this.timer)
|
|
83
93
|
this.renderLoading()
|
|
84
94
|
this.activate(-1)
|
|
@@ -125,9 +135,57 @@ export default class extends Controller {
|
|
|
125
135
|
clearSearch() {
|
|
126
136
|
if (this.searchableValue) {
|
|
127
137
|
this.searchTarget.value = ""
|
|
138
|
+
|
|
139
|
+
if (!this.urlValue) {
|
|
140
|
+
this.filterOptions()
|
|
141
|
+
}
|
|
128
142
|
}
|
|
129
143
|
}
|
|
130
144
|
|
|
145
|
+
filterOptions() {
|
|
146
|
+
const query = this.normalize(this.searchTarget.value)
|
|
147
|
+
const container = this.currentOptionsTarget
|
|
148
|
+
let visibleCount = 0
|
|
149
|
+
let currentGroup = null
|
|
150
|
+
let groupHasMatch = false
|
|
151
|
+
|
|
152
|
+
Array.from(container.children).forEach((child) => {
|
|
153
|
+
if (child.hasAttribute("data-advanced-select-group-label")) {
|
|
154
|
+
if (currentGroup) currentGroup.classList.toggle("hidden", !groupHasMatch)
|
|
155
|
+
currentGroup = child
|
|
156
|
+
groupHasMatch = false
|
|
157
|
+
} else if (child.hasAttribute("data-advanced-select-option")) {
|
|
158
|
+
const match = this.normalize(child.dataset.advancedSelectLabelParam).includes(query)
|
|
159
|
+
child.classList.toggle("hidden", !match)
|
|
160
|
+
if (match) {
|
|
161
|
+
visibleCount += 1
|
|
162
|
+
groupHasMatch = true
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
if (currentGroup) currentGroup.classList.toggle("hidden", !groupHasMatch)
|
|
168
|
+
|
|
169
|
+
this.toggleEmptyState(visibleCount === 0)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
toggleEmptyState(empty) {
|
|
173
|
+
const container = this.currentOptionsTarget
|
|
174
|
+
let emptyState = container.querySelector("[data-advanced-select-empty-state]")
|
|
175
|
+
|
|
176
|
+
if (empty && !emptyState) {
|
|
177
|
+
emptyState = this.textElement("div", this.emptyClass, this.emptyTextValue)
|
|
178
|
+
emptyState.setAttribute("data-advanced-select-empty-state", "")
|
|
179
|
+
container.appendChild(emptyState)
|
|
180
|
+
} else if (!empty && emptyState) {
|
|
181
|
+
emptyState.remove()
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
normalize(text) {
|
|
186
|
+
return (text || "").trim().toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "")
|
|
187
|
+
}
|
|
188
|
+
|
|
131
189
|
fetchOptions({ selected = false } = {}) {
|
|
132
190
|
if (!this.urlValue) {
|
|
133
191
|
return
|
|
@@ -214,7 +272,7 @@ export default class extends Controller {
|
|
|
214
272
|
if (this.selectedValue.some((option) => option.id === value)) {
|
|
215
273
|
this.selectedValue = this.selectedValue.filter((option) => option.id !== value)
|
|
216
274
|
} else {
|
|
217
|
-
this.selectedValue =
|
|
275
|
+
this.selectedValue = [{ id: value, value: submitValue, label, displayLabel }, ...this.selectedValue]
|
|
218
276
|
}
|
|
219
277
|
} else {
|
|
220
278
|
this.selectedValue = [{ id: value, value: submitValue, label, displayLabel }]
|
|
@@ -240,6 +298,7 @@ export default class extends Controller {
|
|
|
240
298
|
|
|
241
299
|
renderOptionsState() {
|
|
242
300
|
const selectedIds = new Set(this.selectedValue.map((option) => option.id))
|
|
301
|
+
const container = this.currentOptionsTarget
|
|
243
302
|
|
|
244
303
|
this.optionElements.forEach((option) => {
|
|
245
304
|
const selected = selectedIds.has(option.dataset.advancedSelectValueParam)
|
|
@@ -251,6 +310,13 @@ export default class extends Controller {
|
|
|
251
310
|
check.textContent = selected ? "\u2713" : ""
|
|
252
311
|
}
|
|
253
312
|
})
|
|
313
|
+
|
|
314
|
+
for (let i = this.selectedValue.length - 1; i >= 0; i--) {
|
|
315
|
+
const option = container.querySelector(
|
|
316
|
+
`[data-advanced-select-option][data-advanced-select-value-param="${this.selectedValue[i].id}"]`
|
|
317
|
+
)
|
|
318
|
+
if (option) container.prepend(option)
|
|
319
|
+
}
|
|
254
320
|
}
|
|
255
321
|
|
|
256
322
|
chooseActiveOption() {
|
|
@@ -303,7 +369,13 @@ export default class extends Controller {
|
|
|
303
369
|
}
|
|
304
370
|
|
|
305
371
|
get hiddenFieldElements() {
|
|
306
|
-
|
|
372
|
+
let options
|
|
373
|
+
|
|
374
|
+
if (this.multipleValue) {
|
|
375
|
+
options = this.includeHiddenValue ? [null, ...this.selectedValue] : this.selectedValue
|
|
376
|
+
} else {
|
|
377
|
+
options = [this.selectedValue[0]]
|
|
378
|
+
}
|
|
307
379
|
|
|
308
380
|
return options.map((option) => {
|
|
309
381
|
const input = document.createElement("input")
|
metadata
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: advanced_select
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mehmet Celik
|
|
8
8
|
- Tankut Ozbeyendir
|
|
9
|
+
- Emre ULUSOY
|
|
9
10
|
bindir: bin
|
|
10
11
|
cert_chain: []
|
|
11
12
|
date: 1980-01-01 00:00:00.000000000 Z
|
|
@@ -86,6 +87,7 @@ description: AdvancedSelect provides helper-rendered Rails partials, Stimulus dr
|
|
|
86
87
|
email:
|
|
87
88
|
- mehmetcelik4@gmail.com
|
|
88
89
|
- tankutozbeyendir@gmail.com
|
|
90
|
+
- ulsyemr@gmail.com
|
|
89
91
|
executables: []
|
|
90
92
|
extensions: []
|
|
91
93
|
extra_rdoc_files: []
|