plutonium 0.66.0 → 0.67.0

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.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/skills/plutonium-resource/SKILL.md +14 -8
  3. data/.claude/skills/plutonium-ui/SKILL.md +11 -3
  4. data/CHANGELOG.md +22 -0
  5. data/SECURITY.md +1 -1
  6. data/app/assets/plutonium.css +1 -1
  7. data/app/assets/plutonium.js +56 -3
  8. data/app/assets/plutonium.js.map +4 -4
  9. data/app/assets/plutonium.min.js +32 -32
  10. data/app/assets/plutonium.min.js.map +4 -4
  11. data/config/brakeman.ignore +1 -1
  12. data/config/locales/en/js.yml +4 -0
  13. data/config/locales/en/ui.yml +16 -0
  14. data/docs/reference/resource/definition.md +12 -7
  15. data/docs/reference/resource/query.md +11 -1
  16. data/docs/reference/ui/displays.md +19 -2
  17. data/docs/reference/ui/forms.md +54 -4
  18. data/gemfiles/rails_7.gemfile +1 -0
  19. data/gemfiles/rails_7.gemfile.lock +13 -3
  20. data/gemfiles/rails_8.0.gemfile +1 -0
  21. data/gemfiles/rails_8.0.gemfile.lock +10 -1
  22. data/gemfiles/rails_8.1.gemfile +1 -0
  23. data/gemfiles/rails_8.1.gemfile.lock +10 -1
  24. data/lib/plutonium/auth/rodauth.rb +7 -0
  25. data/lib/plutonium/core/controller.rb +0 -2
  26. data/lib/plutonium/helpers/content_helper.rb +0 -3
  27. data/lib/plutonium/query/filter.rb +2 -1
  28. data/lib/plutonium/query/filters/tags.rb +36 -0
  29. data/lib/plutonium/ui/component/resolves_tags.rb +13 -0
  30. data/lib/plutonium/ui/display/base.rb +50 -2
  31. data/lib/plutonium/ui/display/components/badge.rb +1 -1
  32. data/lib/plutonium/ui/display/components/binary.rb +20 -0
  33. data/lib/plutonium/ui/display/components/boolean.rb +1 -1
  34. data/lib/plutonium/ui/display/components/code.rb +23 -0
  35. data/lib/plutonium/ui/display/components/color.rb +14 -6
  36. data/lib/plutonium/ui/display/components/duration.rb +31 -0
  37. data/lib/plutonium/ui/display/components/file_size.rb +22 -0
  38. data/lib/plutonium/ui/display/components/key_value.rb +37 -0
  39. data/lib/plutonium/ui/display/components/list.rb +33 -0
  40. data/lib/plutonium/ui/display/components/number.rb +32 -0
  41. data/lib/plutonium/ui/display/components/progress.rb +36 -0
  42. data/lib/plutonium/ui/display/components/rating.rb +36 -0
  43. data/lib/plutonium/ui/display/components/relative_time.rb +25 -0
  44. data/lib/plutonium/ui/display/components/rich_text.rb +23 -0
  45. data/lib/plutonium/ui/display/components/tags.rb +18 -0
  46. data/lib/plutonium/ui/display/options/inferred_types.rb +13 -0
  47. data/lib/plutonium/ui/display/theme.rb +24 -2
  48. data/lib/plutonium/ui/form/base.rb +30 -1
  49. data/lib/plutonium/ui/form/components/binary.rb +40 -0
  50. data/lib/plutonium/ui/form/components/key_value_store.rb +22 -71
  51. data/lib/plutonium/ui/form/components/list.rb +46 -0
  52. data/lib/plutonium/ui/form/components/rating.rb +51 -0
  53. data/lib/plutonium/ui/form/components/rich_text.rb +20 -0
  54. data/lib/plutonium/ui/form/components/tags.rb +45 -0
  55. data/lib/plutonium/ui/form/components/tags_filter.rb +40 -0
  56. data/lib/plutonium/ui/form/components/uppy.rb +1 -1
  57. data/lib/plutonium/ui/form/options/inferred_types.rb +16 -15
  58. data/lib/plutonium/ui/form/theme.rb +20 -4
  59. data/lib/plutonium/ui/grid/card.rb +13 -1
  60. data/lib/plutonium/ui/layout/base.rb +10 -1
  61. data/lib/plutonium/ui/options/rich_text_field.rb +18 -0
  62. data/lib/plutonium/ui/options/secret_field.rb +32 -0
  63. data/lib/plutonium/ui/options/tags_field.rb +23 -0
  64. data/lib/plutonium/ui/table/components/toolbar.rb +2 -2
  65. data/lib/plutonium/ui/table/components/view_switcher.rb +4 -2
  66. data/lib/plutonium/ui/table/display_theme.rb +30 -2
  67. data/lib/plutonium/version.rb +1 -1
  68. data/package.json +1 -1
  69. data/src/css/components.css +43 -0
  70. data/src/css/flatpickr.css +91 -0
  71. data/src/js/controllers/easymde_controller.js +1 -0
  72. data/src/js/controllers/register_controllers.js +2 -0
  73. data/src/js/controllers/slim_select_controller.js +32 -3
  74. data/src/js/controllers/timeago_controller.js +40 -0
  75. metadata +25 -2
@@ -17178,6 +17178,7 @@ ${text2}</tr>
17178
17178
  #buildOptions() {
17179
17179
  let options2 = {
17180
17180
  element: this.element,
17181
+ autoDownloadFontAwesome: false,
17181
17182
  promptURLs: true,
17182
17183
  spellChecker: false,
17183
17184
  // Override the default preview renderer
@@ -17250,7 +17251,9 @@ ${text2}</tr>
17250
17251
  var slim_select_controller_default = class extends Controller {
17251
17252
  static values = {
17252
17253
  typeaheadUrl: String,
17253
- typeaheadDebounceMs: { type: Number, default: 200 }
17254
+ typeaheadDebounceMs: { type: Number, default: 200 },
17255
+ addable: Boolean,
17256
+ maxSelected: Number
17254
17257
  };
17255
17258
  connect() {
17256
17259
  if (this.slimSelect) return;
@@ -17269,10 +17272,15 @@ ${text2}</tr>
17269
17272
  const settings = {};
17270
17273
  const strings = t("plutonium.js.libraries.slim_select");
17271
17274
  if (strings && typeof strings === "object") {
17272
- const { placeholderText, searchText, searchPlaceholder, searchingText } = strings;
17273
- Object.assign(settings, { placeholderText, searchText, searchPlaceholder, searchingText });
17275
+ const { placeholderText, searchText, searchPlaceholder, searchingText, addableText } = strings;
17276
+ Object.assign(settings, { placeholderText, searchText, searchPlaceholder, searchingText, addableText });
17274
17277
  Object.keys(settings).forEach((k4) => settings[k4] === void 0 && delete settings[k4]);
17275
17278
  }
17279
+ if (this.hasMaxSelectedValue) settings.maxSelected = this.maxSelectedValue;
17280
+ if (this.addableValue) {
17281
+ settings.placeholderText = t("plutonium.js.slim_select.add_placeholder");
17282
+ settings.searchPlaceholder = t("plutonium.js.slim_select.add_search_placeholder");
17283
+ }
17276
17284
  this.modal = this.element.closest('[data-controller="remote-modal"]');
17277
17285
  if (this.modal) {
17278
17286
  settings.contentLocation = this.modal;
@@ -17280,6 +17288,17 @@ ${text2}</tr>
17280
17288
  settings.openPosition = "auto";
17281
17289
  }
17282
17290
  const events = {};
17291
+ if (this.modal) {
17292
+ events.afterOpen = () => {
17293
+ this.modal.style.overflow = "visible";
17294
+ };
17295
+ events.afterClose = () => {
17296
+ this.modal.style.overflow = "";
17297
+ };
17298
+ }
17299
+ if (this.addableValue) {
17300
+ events.addable = (value) => value.trim() || false;
17301
+ }
17283
17302
  if (this.hasTypeaheadUrlValue && this.typeaheadUrlValue) {
17284
17303
  events.search = (search, currentData) => this.#typeaheadFetch(search, currentData);
17285
17304
  }
@@ -17380,6 +17399,7 @@ ${text2}</tr>
17380
17399
  document.removeEventListener("scroll", this.boundModalReposition, true);
17381
17400
  this.boundModalReposition = null;
17382
17401
  }
17402
+ if (this.modal) this.modal.style.overflow = "";
17383
17403
  if (this.slimSelect) {
17384
17404
  this.slimSelect.destroy();
17385
17405
  this.slimSelect = null;
@@ -30112,6 +30132,38 @@ this.ifd0Offset: ${this.ifd0Offset}, file.byteLength: ${e4.byteLength}`), e4.tif
30112
30132
  }
30113
30133
  };
30114
30134
 
30135
+ // src/js/controllers/timeago_controller.js
30136
+ var UNITS = [
30137
+ ["year", 60 * 60 * 24 * 365],
30138
+ ["month", 60 * 60 * 24 * 30],
30139
+ ["week", 60 * 60 * 24 * 7],
30140
+ ["day", 60 * 60 * 24],
30141
+ ["hour", 60 * 60],
30142
+ ["minute", 60],
30143
+ ["second", 1]
30144
+ ];
30145
+ var timeago_controller_default = class extends Controller {
30146
+ static values = {
30147
+ datetime: String,
30148
+ refreshInterval: { type: Number, default: 6e4 }
30149
+ };
30150
+ connect() {
30151
+ this.formatter = new Intl.RelativeTimeFormat(document.documentElement.lang || void 0, { numeric: "auto" });
30152
+ this.render();
30153
+ this.timer = setInterval(() => this.render(), this.refreshIntervalValue);
30154
+ }
30155
+ disconnect() {
30156
+ clearInterval(this.timer);
30157
+ }
30158
+ render() {
30159
+ const date = new Date(this.datetimeValue);
30160
+ if (isNaN(date)) return;
30161
+ const seconds = Math.round((date - Date.now()) / 1e3);
30162
+ const [unit, size] = UNITS.find(([, size2]) => Math.abs(seconds) >= size2) || UNITS[UNITS.length - 1];
30163
+ this.element.textContent = this.formatter.format(Math.round(seconds / size), unit);
30164
+ }
30165
+ };
30166
+
30115
30167
  // src/js/controllers/register_controllers.js
30116
30168
  function register_controllers_default(application2) {
30117
30169
  application2.register("password-visibility", password_visibility_controller_default);
@@ -30158,6 +30210,7 @@ this.ifd0Offset: ${this.ifd0Offset}, file.byteLength: ${e4.byteLength}`), e4.tif
30158
30210
  application2.register("run-progress", run_progress_controller_default);
30159
30211
  application2.register("chart", chart_controller_default);
30160
30212
  application2.register("frame-refresh", frame_refresh_controller_default);
30213
+ application2.register("timeago", timeago_controller_default);
30161
30214
  }
30162
30215
 
30163
30216
  // src/js/turbo/turbo_actions.js