@fleetbase/ember-ui 0.3.12 → 0.3.13

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.
@@ -167,11 +167,17 @@ export default class ActivityLogComponent extends Component {
167
167
 
168
168
  if (c.from !== 'null' && c.from !== undefined && c.from !== '' && c.from !== c.to) {
169
169
  parts.push(
170
- `<span class="activity-change">changed <span class="activity-change-prop highlight-gray ${this.args.activityChangePropClass ?? ''}">${k}</span> from <span class="activity-change-prop highlight-gray ${this.args.activityPreviousValueClass ?? ''}">${this.#code(c.from)}</span> to <span class="activity-change-prop highlight-blue ${this.args.activityNewValueClass ?? ''}">${this.#code(c.to)}</span></span>`
170
+ `<span class="activity-change">changed <span class="activity-change-prop highlight-gray ${
171
+ this.args.activityChangePropClass ?? ''
172
+ }">${k}</span> from <span class="activity-change-prop highlight-gray ${this.args.activityPreviousValueClass ?? ''}">${this.#code(
173
+ c.from
174
+ )}</span> to <span class="activity-change-prop highlight-blue ${this.args.activityNewValueClass ?? ''}">${this.#code(c.to)}</span></span>`
171
175
  );
172
176
  } else {
173
177
  parts.push(
174
- `<span class="activity-change">set <span class="activity-change-prop highlight-gray ${this.args.activityChangePropClass ?? ''}">${k}</span> to <span class="activity-change-prop highlight-blue ${this.args.activityNewValueClass ?? ''}">${this.#code(c.to)}</span></span>`
178
+ `<span class="activity-change">set <span class="activity-change-prop highlight-gray ${
179
+ this.args.activityChangePropClass ?? ''
180
+ }">${k}</span> to <span class="activity-change-prop highlight-blue ${this.args.activityNewValueClass ?? ''}">${this.#code(c.to)}</span></span>`
175
181
  );
176
182
  }
177
183
  }
@@ -1,4 +1,4 @@
1
- <div class="ui-chart relative">
1
+ <div class="ui-chart relative {{@wrapperClass}}">
2
2
  {{#if this.isLoading}}
3
3
  <div class="overloader overloader-opacity-2">
4
4
  <div class="p-8">
@@ -1,4 +1,5 @@
1
1
  <ModelSelect
2
+ @multiple={{true}}
2
3
  @modelName={{@modelName}}
3
4
  @selectedModel={{@selectedModel}}
4
5
  @optionLabel={{@optionLabel}}
@@ -16,8 +17,6 @@
16
17
  @totalPagesParam={{@totalPagesParam}}
17
18
  @onCreate={{@onCreate}}
18
19
  @onChange={{this.change}}
19
- @searchField={{@optionLabel}}
20
- @triggerClass="ember-model-select-multiple-trigger {{@triggerClass}}"
21
20
  @triggerRole={{@triggerRole}}
22
21
  @ariaDescribedBy={{@ariaDescribedBy}}
23
22
  @ariaInvalid={{@ariaInvalid}}
@@ -48,22 +47,25 @@
48
47
  @onKeydown={{this.handleKeydown}}
49
48
  @onOpen={{this.handleOpen}}
50
49
  @options={{@options}}
51
- @optionsComponent={{@optionsComponent}}
50
+ @optionsComponent={{ensure-safe-component @optionsComponent}}
52
51
  @placeholder={{@placeholder}}
53
- @placeholderComponent={{@placeholderComponent}}
52
+ @placeholderComponent={{ensure-safe-component @placeholderComponent}}
54
53
  @preventScroll={{@preventScroll}}
55
54
  @registerAPI={{@registerAPI}}
56
55
  @renderInPlace={{@renderInPlace}}
57
56
  @required={{@required}}
58
57
  @scrollTo={{@scrollTo}}
59
58
  @search={{@search}}
60
- @searchEnabled={{@searchEnabled}}
59
+ @searchEnabled={{if (eq @searchEnabled false) false true}}
60
+ @searchField={{or @optionLabel @searchField}}
61
+ @searchFieldPosition={{or @searchFieldPosition "trigger"}}
61
62
  @searchMessage={{@searchMessage}}
62
63
  @searchPlaceholder={{@searchPlaceholder}}
63
- @selectedItemComponent={{@selectedItemComponent}}
64
+ @selectedItemComponent={{ensure-safe-component @selectedItemComponent}}
64
65
  @eventType={{@eventType}}
65
66
  @title={{@title}}
66
- @triggerComponent={{component (or @triggerComponent "power-select-multiple/trigger") tabindex=@tabindex}}
67
+ @triggerClass="ember-power-select-multiple-trigger {{@triggerClass}}"
68
+ @triggerComponent={{if @triggerComponent (component (ensure-safe-component @triggerComponent) tabindex=@tabindex) (component "power-select-multiple/trigger" tabindex=@tabindex)}}
67
69
  @triggerId={{@triggerId}}
68
70
  @verticalPosition={{@verticalPosition}}
69
71
  @tabindex={{this.computedTabIndex}}
@@ -22,6 +22,7 @@
22
22
  @initiallyOpened={{@initiallyOpened}}
23
23
  @loadingMessage={{@loadingMessage}}
24
24
  @eventType={{@eventType}}
25
+ @multiple={{@multiple}}
25
26
  @matcher={{@matcher}}
26
27
  @matchTriggerWidth={{@matchTriggerWidth}}
27
28
  @noMatchesMessage={{@noMatchesMessage}}
@@ -42,6 +43,7 @@
42
43
  @search={{perform this.searchModels}}
43
44
  @searchEnabled={{get-default-value @searchEnabled true}}
44
45
  @searchField={{@searchField}}
46
+ @searchFieldPosition={{@searchFieldPosition}}
45
47
  @searchMessage={{@searchMessage}}
46
48
  @searchPlaceholder={{@searchPlaceholder}}
47
49
  @selected={{this.selectedModel}}
@@ -16,4 +16,4 @@
16
16
  </span>
17
17
  <Input @type="tel" @value={{@value}} class="form-input flex-1 rounded-l-none" {{did-insert this.autoNumerize}} ...attributes />
18
18
  </div>
19
- </div>
19
+ </div>
@@ -2,7 +2,6 @@ import Component from '@glimmer/component';
2
2
  import { tracked } from '@glimmer/tracking';
3
3
  import { inject as service } from '@ember/service';
4
4
  import { action } from '@ember/object';
5
- import { later } from '@ember/runloop';
6
5
  import { isNone } from '@ember/utils';
7
6
  import numbersOnly from '../utils/numbers-only';
8
7
  import getCurrency from '../utils/get-currency';
@@ -12,7 +11,6 @@ export default class MoneyInputComponent extends Component {
12
11
  @service fetch;
13
12
  @service currentUser;
14
13
  @tracked currencies = getCurrency();
15
- @tracked value;
16
14
  @tracked currency;
17
15
  @tracked currencyData;
18
16
  @tracked autonumeric;
@@ -22,7 +20,6 @@ export default class MoneyInputComponent extends Component {
22
20
 
23
21
  let whois = this.currentUser.getOption('whois');
24
22
 
25
- this.value = this.args.value ?? 0;
26
23
  this.currency = this.args.currency ?? whois?.currency?.code ?? 'USD';
27
24
  this.currencyData = getCurrency(this.currency);
28
25
  }
@@ -30,7 +27,11 @@ export default class MoneyInputComponent extends Component {
30
27
  @action autoNumerize(element) {
31
28
  const { onCurrencyChange } = this.args;
32
29
  let currency = this.currencyData;
33
- let value = numbersOnly(this.value);
30
+ let value = numbersOnly(this.args.value ?? 0);
31
+
32
+ // CRITICAL: Conditional division based on currency precision
33
+ // - Currencies with decimals (precision > 0): divide by 100 (stored in cents)
34
+ // - Currencies without decimals (precision = 0): use as-is (stored in main unit)
34
35
  let amount = !currency.decimalSeparator ? value : value / 100;
35
36
 
36
37
  this.autonumeric = new AutoNumeric(element, amount, this.getCurrencyFormatOptions(currency));
@@ -40,14 +41,27 @@ export default class MoneyInputComponent extends Component {
40
41
  onCurrencyChange(currency.code, currency);
41
42
  }
42
43
 
43
- element.addEventListener('autoNumeric:formatted', this.onFormatCompleted.bind(this));
44
+ // Use rawValueModified for better change detection
45
+ element.addEventListener('autoNumeric:rawValueModified', ({ detail }) => {
46
+ if (typeof this.args.onChange === 'function') {
47
+ // Convert back to storage format
48
+ let rawValue = detail.newRawValue;
49
+ // For precision > 0: multiply by 100 to get cents
50
+ // For precision = 0: use as-is (main unit)
51
+ let storedValue = !currency.decimalSeparator ? rawValue : Math.round(rawValue * 100);
52
+ this.args.onChange(storedValue, detail);
53
+ }
54
+ });
44
55
  }
45
56
 
46
57
  @action setCurrency(currency) {
47
58
  const { onCurrencyChange } = this.args;
48
59
 
49
60
  if (this.autonumeric) {
50
- this.autonumeric.set(numbersOnly(this.value, true), this.getCurrencyFormatOptions(currency));
61
+ let value = this.autonumeric.getNumber();
62
+ this.autonumeric.update(this.getCurrencyFormatOptions(currency));
63
+ // Re-set the value to ensure it's formatted correctly with new currency
64
+ this.autonumeric.set(value);
51
65
  }
52
66
 
53
67
  this.currency = currency.code;
@@ -58,25 +72,6 @@ export default class MoneyInputComponent extends Component {
58
72
  }
59
73
  }
60
74
 
61
- @action onFormatCompleted({ detail }) {
62
- const { onFormatCompleted, onChange } = this.args;
63
-
64
- // 300ms for format to apply to input ?
65
- later(
66
- this,
67
- () => {
68
- if (typeof onFormatCompleted === 'function') {
69
- onFormatCompleted(detail);
70
- }
71
- },
72
- 300
73
- );
74
-
75
- if (typeof onChange === 'function') {
76
- onChange(detail);
77
- }
78
- }
79
-
80
75
  @action getCurrencyFormatOptions(currency) {
81
76
  let options = {
82
77
  currencySymbol: isNone(currency.symbol) ? '$' : currency.symbol,
@@ -40,10 +40,12 @@ body.fleetbase-console .ember-basic-dropdown-content {
40
40
  background-color: transparent;
41
41
  }
42
42
 
43
+ .ember-power-select-multiple-option .hide-from-trigger,
43
44
  .ember-power-select-selected-item .hide-from-trigger {
44
45
  display: none;
45
46
  }
46
47
 
48
+ .ember-power-select-multiple-option div.normalize-in-trigger,
47
49
  .ember-power-select-selected-item div.normalize-in-trigger {
48
50
  font-weight: normal;
49
51
  }
@@ -51,9 +51,23 @@
51
51
  .ember-power-select-trigger-multiple-input,
52
52
  .ember-power-select-trigger-multiple-input[type='search'] {
53
53
  @apply bg-transparent text-sm text-white outline-0 leading-5 px-1;
54
- max-height: 21px;
54
+ height: 26.42px; /** don't ask */
55
+ max-height: 40px;
55
56
  }
56
57
 
57
- .ember-power-select-option[aria-selected="true"] {
58
+ .fleetbase-console.ember-power-select-trigger-multiple-input::placeholder,
59
+ .ember-power-select-trigger-multiple-input .ember-power-select-trigger-multiple-input::placeholder {
60
+ color: #6b7280;
61
+ opacity: 1;
62
+ }
63
+
64
+ .ember-power-select-option[aria-selected='true'] {
58
65
  @apply dark:bg-gray-900 bg-gray-200;
59
- }
66
+ }
67
+
68
+ .ember-model-select-multiple-trigger > .ember-power-select-multiple-options > li.ember-power-select-multiple-option {
69
+ display: flex;
70
+ align-items: center;
71
+ padding: 0.25rem 0.5rem;
72
+ border-radius: 0.45rem;
73
+ }
package/index.js CHANGED
@@ -21,7 +21,7 @@ const postcssOptions = {
21
21
  plugins: [
22
22
  postcssAtRulesVariables,
23
23
  postcssImport({
24
- path: ['node_modules'],
24
+ path: ['node_modules', path.join(__dirname, 'addon/styles')],
25
25
  plugins: [postcssAtRulesVariables, postcssImport],
26
26
  }),
27
27
  postcssMixins,
@@ -55,13 +55,31 @@ module.exports = {
55
55
  postcssOptions,
56
56
  },
57
57
 
58
+ treeForStyles: function () {
59
+ // Only provide styles to the root application, not to engines
60
+ // This prevents engines from trying to compile ember-ui styles
61
+ let parent = this.parent;
62
+ while (parent) {
63
+ const isEngine = parent.lazyLoading === true || (parent.lazyLoading && parent.lazyLoading.enabled === true);
64
+ if (isEngine) {
65
+ // Parent is an engine - don't provide styles
66
+ return null;
67
+ }
68
+ parent = parent.parent;
69
+ }
70
+
71
+ // Parent is the root app - provide styles normally
72
+ return this._super.treeForStyles ? this._super.treeForStyles.apply(this, arguments) : null;
73
+ },
74
+
58
75
  included: function (app) {
59
76
  this._super.included.apply(this, arguments);
60
77
 
61
- // Get Application Host
78
+ // Get Application Host (skips engines, finds root app)
62
79
  app = this.findApplicationHost(app);
63
80
 
64
- // PostCSS Options
81
+ // PostCSS Options - only applied to the root application
82
+ // Engines are excluded by findApplicationHost, so they won't get these options
65
83
  app.options = app.options || {};
66
84
  app.options.postcssOptions = postcssOptions;
67
85
 
@@ -128,11 +146,11 @@ module.exports = {
128
146
  findApplicationHost(app) {
129
147
  let current = this;
130
148
  do {
131
- if (current.lazyLoading === true || (current.lazyLoading && current.lazyLoading.enabled === true)) {
132
- app = current;
133
- break;
149
+ // Skip engines - we want the root application, not an engine
150
+ const isEngine = current.lazyLoading === true || (current.lazyLoading && current.lazyLoading.enabled === true);
151
+ if (!isEngine) {
152
+ app = current.app || app;
134
153
  }
135
- app = current.app || app;
136
154
  } while (current.parent.parent && (current = current.parent));
137
155
 
138
156
  return app;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fleetbase/ember-ui",
3
- "version": "0.3.12",
3
+ "version": "0.3.13",
4
4
  "description": "Fleetbase UI provides all the interface components, helpers, services and utilities for building a Fleetbase extension into the Console.",
5
5
  "keywords": [
6
6
  "fleetbase-ui",
@@ -127,6 +127,7 @@
127
127
  "broccoli-asset-rev": "^3.0.0",
128
128
  "broccoli-funnel": "^3.0.8",
129
129
  "broccoli-merge-trees": "^4.2.0",
130
+ "broccoli-postcss-single": "^5.0.2",
130
131
  "clean-css": "^5.3.2",
131
132
  "concurrently": "^8.2.2",
132
133
  "ember-cli": "~5.4.1",
@@ -4,6 +4,7 @@ module.exports = {
4
4
  content: [
5
5
  './app/**/*.{hbs,js}',
6
6
  './addon/**/*.{hbs,js}',
7
+ './addon/**/*.css',
7
8
  // All Fleetbase packages (both pnpm symlinked and normal installs)
8
9
  './node_modules/@fleetbase+*/**/addon/**/*.{hbs,js}',
9
10
  './node_modules/@fleetbase/**/addon/**/*.{hbs,js}',