mensa 0.6.8 → 0.6.10

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5cc6a4c7a0cbea3b05559bad2910becc5458e74137015835b0d8a753d1e8012e
4
- data.tar.gz: 65afa4de844a8741a342bbd38e8e717eaa59c35650eef0b4297e8420cd380821
3
+ metadata.gz: 14b28a5dcb74e6d3bfccaa9180f0ba2299b1c5bff0adc6e9bbd2a17ff2d91c19
4
+ data.tar.gz: 552b80421e290566218fe4e7e495785f7208ffa8f397fd88859b4e4ad20d6a21
5
5
  SHA512:
6
- metadata.gz: 3282238437abbc28f4896ff086241eb5a8ff6fb12202691bb7f3f8c85c5cda4677a28406c6f367c582660335853a496c7c7f42ab0ef98518512350d6ef2ff479
7
- data.tar.gz: 82374fe57fdf48bae11d6c784bbcc7f4ad2380fc739565500b70a6df49bfbc2392bb1cfde5dba69e23222a85bf3d33a0c38cd1e35dcd4d5d3b33ba47ba65ccaf
6
+ metadata.gz: 4848da1b5f33354d6dc79a8b6f76ed68e43744706ce34b808910186de399ae19d49e85409a561d11d74376c3a067f411697432664d2274c28a869e83136fdde9
7
+ data.tar.gz: 400e3c6400043dea964f3958a27704ae1b56dd7c475de8ba4f20a16b3b3b4682582e3229589d285b3f62377db326ff56b0ac17160544aa38369a11f6f4cc92ca
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mensa (0.6.7)
4
+ mensa (0.6.9)
5
5
  csv
6
6
  importmap-rails
7
7
  pagy (>= 43)
data/README.md CHANGED
@@ -79,7 +79,7 @@ class UserTable < ApplicationTable
79
79
 
80
80
  # Add system views
81
81
  # Mensa will always create a systemview (:default) with name 'All' showing all records.
82
- # If you want to rename it, for example because you don't show all records in your default scope, add it and give it a name like below.
82
+ # If you want to rename it, for example because you don't show all records in your default scope, or override it with filters, add it and give it a name like below.
83
83
  view :default do
84
84
  name "Default"
85
85
  description "Some descriptive text"
@@ -5,7 +5,7 @@
5
5
  }
6
6
 
7
7
  &__heading {
8
- @apply px-4 pt-2 pb-1 text-xs font-semibold uppercase tracking-wider text-gray-400 dark:text-gray-500;
8
+ @apply px-4 pt-2 pb-1 text-sm font-semibold tracking-wider text-gray-900 dark:text-gray-500;
9
9
  }
10
10
 
11
11
  &__row {
@@ -7,7 +7,7 @@
7
7
  <i class="<%= Mensa.config.icons[:column_customizer_toggle] %>"></i>
8
8
  </button>
9
9
  <div class="mensa-table__column_customizer__popover hidden" data-mensa-column-customizer-target="popover">
10
- <p class="mensa-table__column_customizer__heading">Columns</p>
10
+ <p class="mensa-table__column_customizer__heading"><%= t("mensa.column_customizer.heading") %></p>
11
11
  <ul>
12
12
  <% table.columns.reject(&:internal?).each do |column| %>
13
13
  <li class="mensa-table__column_customizer__row"
@@ -19,6 +19,7 @@
19
19
  &__input {
20
20
  @apply w-full bg-transparent text-xs text-gray-700 dark:text-gray-200 placeholder:text-gray-400;
21
21
  /* Override @tailwindcss/forms — direct CSS beats attribute selector specificity */
22
+ background-color: transparent !important;
22
23
  border: none !important;
23
24
  outline: none !important;
24
25
  box-shadow: none !important;
@@ -160,19 +160,19 @@ export default class FilterPillListComponentController extends ApplicationContro
160
160
  // Called by the search controller when the query is submitted or reset.
161
161
  setQuery(query) {
162
162
  if (query && query.length > 0) this._notifyUnsavedState();
163
- this.applyState({
164
- filters: this.collectFilters(),
163
+ const state = {
165
164
  query,
166
165
  view: this.loadView(),
167
166
  order: this.loadOrder(),
168
167
  page: "",
169
- });
168
+ };
169
+ if (this.hasPersistedFilters()) state.filters = this.loadFilters();
170
+ this.applyState(state);
170
171
  }
171
172
 
172
173
  // Called by the views controller when a view tab is selected.
173
174
  viewSelected(view) {
174
175
  const state = {
175
- filters: {},
176
176
  query: "",
177
177
  view,
178
178
  order: this.loadOrder(),
@@ -267,7 +267,6 @@ export default class FilterPillListComponentController extends ApplicationContro
267
267
  // buildUrl reads column_order/hidden_columns from localStorage — now empty,
268
268
  // so the server receives a completely clean request for the current view.
269
269
  this.requestState({
270
- filters: {},
271
270
  query: "",
272
271
  view,
273
272
  order: {},
@@ -278,6 +277,7 @@ export default class FilterPillListComponentController extends ApplicationContro
278
277
  restoreState() {
279
278
  const table = this.mensaTableOutlet;
280
279
  const filters = this.loadFilters();
280
+ const filtersProvided = this.hasPersistedFilters();
281
281
  const query = this.loadQuery();
282
282
  const view = this.loadView();
283
283
  const page = this.loadPage();
@@ -288,6 +288,7 @@ export default class FilterPillListComponentController extends ApplicationContro
288
288
  // Show save/reset if any persistent state exists (order, column layout, filters, search)
289
289
  if (
290
290
  Object.keys(filters).length > 0 ||
291
+ filtersProvided ||
291
292
  query.length > 0 ||
292
293
  Object.keys(order).length > 0 ||
293
294
  columnOrder.length > 0 ||
@@ -297,7 +298,9 @@ export default class FilterPillListComponentController extends ApplicationContro
297
298
  }
298
299
 
299
300
  const hasFilterOrSearch =
300
- Object.keys(filters).length > 0 || query.length > 0;
301
+ Object.keys(filters).length > 0 ||
302
+ filtersProvided ||
303
+ query.length > 0;
301
304
  const hasState =
302
305
  hasFilterOrSearch ||
303
306
  view.length > 0 ||
@@ -319,7 +322,8 @@ export default class FilterPillListComponentController extends ApplicationContro
319
322
  this.setSearchField(query);
320
323
  this.setViewHighlight(view);
321
324
 
322
- const state = { filters, query, view, page, order };
325
+ const state = { query, view, page, order };
326
+ if (filtersProvided) state.filters = filters;
323
327
 
324
328
  // No need to show/hide the filter bar — it's always visible.
325
329
  // Just apply state and load the frame.
@@ -377,6 +381,12 @@ export default class FilterPillListComponentController extends ApplicationContro
377
381
  url.searchParams.set(`order[${columnName}]`, direction);
378
382
  });
379
383
 
384
+ if (
385
+ Object.prototype.hasOwnProperty.call(state, "filters") &&
386
+ Object.keys(state.filters || {}).length === 0
387
+ ) {
388
+ url.searchParams.set("filters", "");
389
+ }
380
390
  if (state.query) url.searchParams.set("query", state.query);
381
391
  if (state.view) url.searchParams.set("table_view_id", state.view);
382
392
  if (state.page) url.searchParams.set("page", state.page);
@@ -576,7 +586,9 @@ export default class FilterPillListComponentController extends ApplicationContro
576
586
  // --- Persistence ---
577
587
 
578
588
  persistState(state) {
579
- this.persistFilters(state.filters || {});
589
+ if (Object.prototype.hasOwnProperty.call(state, "filters")) {
590
+ this.persistFilters(state.filters || {});
591
+ }
580
592
  this.persistQuery(state.query || "");
581
593
  this.persistView(state.view || "");
582
594
  this.persistPage(state.page || "");
@@ -584,10 +596,7 @@ export default class FilterPillListComponentController extends ApplicationContro
584
596
  }
585
597
 
586
598
  persistFilters(filters) {
587
- this.writeStorage(
588
- this.filtersStorageKey,
589
- Object.keys(filters).length > 0 ? JSON.stringify(filters) : null,
590
- );
599
+ this.writeStorage(this.filtersStorageKey, JSON.stringify(filters));
591
600
  }
592
601
 
593
602
  loadFilters() {
@@ -600,6 +609,10 @@ export default class FilterPillListComponentController extends ApplicationContro
600
609
  }
601
610
  }
602
611
 
612
+ hasPersistedFilters() {
613
+ return this.readStorage(this.filtersStorageKey) !== null;
614
+ }
615
+
603
616
  persistQuery(query) {
604
617
  this.writeStorage(
605
618
  this.searchStorageKey,
@@ -8,7 +8,9 @@
8
8
  The controller and its column-list ul stay in the DOM so the search-input focus
9
9
  handler can still open the column list. */
10
10
  .mensa-table--view-filters-hidden
11
- .mensa-table__search-bar__pills-area:not(:has(.mensa-filter-pill:not([data-view-filter="true"])))
11
+ .mensa-table__search-bar__pills-area:not(
12
+ :has(.mensa-filter-pill:not([data-view-filter="true"]))
13
+ )
12
14
  .mensa-table__add_filter__trigger {
13
15
  display: none;
14
16
  }
@@ -22,6 +24,24 @@
22
24
  @apply flex items-center gap-2 px-2 py-1 border-b border-gray-200 dark:border-gray-600 bg-white dark:bg-gray-800;
23
25
  }
24
26
 
27
+ turbo-frame {
28
+ @apply relative block;
29
+ }
30
+
31
+ turbo-frame[aria-busy] {
32
+ @apply cursor-wait;
33
+ }
34
+
35
+ turbo-frame[aria-busy] > * {
36
+ @apply opacity-50 grayscale pointer-events-none;
37
+ }
38
+
39
+ turbo-frame[aria-busy]::after {
40
+ content: "";
41
+ @apply absolute inset-0 z-10 bg-gray-50/30 dark:bg-gray-900/50;
42
+ pointer-events: all;
43
+ }
44
+
25
45
  &__search-container {
26
46
  @apply flex flex-1 min-w-0 items-stretch h-8 rounded-md bg-white dark:bg-gray-800;
27
47
  }
@@ -41,7 +41,6 @@ export default class TableComponentController extends ApplicationController {
41
41
  clearTimeout(this.frameLoadFallback);
42
42
  this.frameLoadFallback = null;
43
43
  }
44
-
45
44
  }
46
45
 
47
46
  saveDropdownOutsideHandler(event) {
@@ -149,12 +148,13 @@ export default class TableComponentController extends ApplicationController {
149
148
  if (this.hasMensaFilterPillListOutlet) {
150
149
  const outlet = this.mensaFilterPillListOutlet;
151
150
  const state = {
152
- filters: outlet.loadFilters(),
153
151
  query: outlet.loadQuery(),
154
152
  view: outlet.loadView(),
155
153
  order: outlet.loadOrder(),
156
154
  page: outlet.loadPage(),
157
155
  };
156
+ if (outlet.hasPersistedFilters())
157
+ state.filters = outlet.loadFilters();
158
158
  this.turboFrameTarget.setAttribute(
159
159
  "src",
160
160
  outlet.buildUrl(state).toString(),
@@ -25,7 +25,7 @@
25
25
  }
26
26
 
27
27
  .mensa-table {
28
- @apply bg-white dark:bg-gray-500 dark:border-gray-700;
28
+ @apply bg-white dark:bg-gray-800 dark:border-gray-800;
29
29
 
30
30
  .mensa-table__checkbox-col {
31
31
  @apply w-7 min-w-7 pl-1 pr-0 text-center;
@@ -84,7 +84,7 @@
84
84
  @apply min-w-full divide-y divide-gray-50 dark:divide-gray-800 border-0;
85
85
 
86
86
  thead {
87
- @apply bg-gray-100 top-0 dark:bg-gray-700 dark:font-medium dark:text-gray-400 dark:lowercase;
87
+ @apply bg-gray-100 top-0 dark:bg-gray-700 dark:font-medium dark:text-gray-400;
88
88
 
89
89
  /* tr and th moved to header */
90
90
  }
@@ -1,12 +1,12 @@
1
1
  .mensa-table {
2
2
  .paging {
3
- @apply flex items-center justify-between border-t border-gray-100 dark:border-gray-600 bg-white dark:bg-gray-800 px-4 py-3 sm:px-6 text-sm;
3
+ @apply flex items-center justify-between border-t border-gray-100 dark:border-gray-700 bg-white dark:bg-gray-800 px-4 py-3 sm:px-6 text-sm;
4
4
 
5
5
  .pagy {
6
6
  @apply isolate inline-flex -space-x-px text-gray-500 dark:text-gray-400;
7
7
 
8
8
  a:not(.gap) {
9
- @apply relative inline-flex items-center px-4 py-1.5 text-gray-500 dark:text-gray-400 bg-gray-100 dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-700 focus:z-20 no-underline;
9
+ @apply relative inline-flex items-center px-4 py-1.5 text-gray-500 dark:text-gray-400 bg-gray-100 dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 focus:z-20 no-underline;
10
10
 
11
11
  &:first-child {
12
12
  border-top-left-radius: 4px;
@@ -24,7 +24,7 @@
24
24
 
25
25
  &:not([href]) {
26
26
  /* disabled links */
27
- @apply bg-gray-100 dark:bg-gray-600 hover:bg-gray-100 hover:dark:bg-gray-600 text-gray-700 dark:text-gray-100 text-opacity-25 dark:text-opacity-50 cursor-default;
27
+ @apply bg-gray-100 dark:bg-gray-800 hover:bg-gray-100 hover:dark:bg-gray-800 text-gray-700 dark:text-gray-100 text-opacity-25 dark:text-opacity-50 cursor-default;
28
28
  }
29
29
 
30
30
  &.current {
@@ -1,7 +1,9 @@
1
1
  module Mensa
2
2
  class TablesController < ApplicationController
3
3
  def show
4
+ filters_provided = params.key?(:filters)
4
5
  config = params.permit(:format, :query, :id, :page, :table_view_id, :turbo_frame_id, order: {}, column_order: [], hidden_columns: [], params: {}, filters: {}).to_h
6
+ config[:filters] = {} if filters_provided && !config.key?(:filters)
5
7
 
6
8
  @table = Mensa.for_name(params[:id], config)
7
9
 
@@ -1,5 +1,7 @@
1
1
  en:
2
2
  mensa:
3
+ column_customizer:
4
+ heading: Columns
3
5
  tables:
4
6
  filters:
5
7
  show:
@@ -1,5 +1,7 @@
1
1
  nl:
2
2
  mensa:
3
+ column_customizer:
4
+ heading: Kolommen
3
5
  tables:
4
6
  filters:
5
7
  show:
@@ -55,7 +55,7 @@ module Mensa
55
55
  control_bar_export: "fa-solid fa-file-export",
56
56
  empty_state_icon: "fa-solid fa-magnifying-glass",
57
57
  filter_pill_remove: "fa-solid fa-xmark",
58
- filter_pill_list_search: "fa-solid fa-magnifying-glass",
58
+ filter_pill_list_search: "fa-solid fa-sm fa-magnifying-glass",
59
59
  filter_pill_list_clear: "fa-solid fa-xmark",
60
60
  header_order_indicator_asc: "fa-solid fa-sm fa-arrow-up",
61
61
  header_order_indicator_desc: "fa-solid fa-sm fa-arrow-down",
@@ -89,7 +89,7 @@ module Mensa
89
89
  # control_bar_export: "fa-light fa-file-export",
90
90
  # empty_state_icon: "fa-light fa-magnifying-glass",
91
91
  # filter_pill_remove: "fa-light fa-xmark",
92
- # filter_pill_list_search: "fa-light fa-magnifying-glass",
92
+ # filter_pill_list_search: "fa-light fa-sm fa-magnifying-glass",
93
93
  # filter_pill_list_clear: "fa-light fa-xmark",
94
94
  # header_order_indicator_asc: "fa-regular fa-sm fa-arrow-up-short-wide",
95
95
  # header_order_indicator_desc: "fa-regular fa-sm fa-arrow-down-wide-short",
data/lib/mensa/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Mensa
2
- VERSION = "0.6.8"
2
+ VERSION = "0.6.10"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mensa
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.8
4
+ version: 0.6.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom de Grunt