@fleetbase/ember-ui 0.3.4 → 0.3.6
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.
- package/addon/components/activity-log.hbs +137 -0
- package/addon/components/activity-log.js +310 -0
- package/addon/components/badge.hbs +1 -1
- package/addon/components/bulk-search-dropdown.hbs +14 -0
- package/addon/components/bulk-search-dropdown.js +26 -0
- package/addon/components/button.hbs +5 -1
- package/addon/components/comment-thread/comment.hbs +7 -7
- package/addon/components/comment-thread.hbs +2 -2
- package/addon/components/content-panel.hbs +104 -31
- package/addon/components/content-panel.js +10 -1
- package/addon/components/coordinates-input.hbs +17 -2
- package/addon/components/country-select.hbs +1 -1
- package/addon/components/country-select.js +3 -2
- package/addon/components/custom-field/form.hbs +77 -0
- package/addon/components/custom-field/form.js +103 -0
- package/addon/components/custom-field/input.hbs +93 -0
- package/addon/components/custom-field/input.js +151 -0
- package/addon/components/custom-field/options-input.hbs +17 -0
- package/addon/components/custom-field/options-input.js +123 -0
- package/addon/components/custom-field/value.hbs +10 -0
- package/addon/components/custom-field/value.js +23 -0
- package/addon/components/custom-field/yield.hbs +30 -0
- package/addon/components/custom-field/yield.js +107 -0
- package/addon/components/custom-fields-manager.hbs +103 -0
- package/addon/components/custom-fields-manager.js +231 -0
- package/addon/components/dashboard/create.hbs +13 -10
- package/addon/components/dashboard/widget-panel.hbs +5 -3
- package/addon/components/dashboard/widget-panel.js +0 -1
- package/addon/components/dashboard.hbs +35 -39
- package/addon/components/dashboard.js +6 -2
- package/addon/components/date-picker.js +17 -5
- package/addon/components/drawer.js +12 -16
- package/addon/components/dropdown-button.hbs +25 -1
- package/addon/components/fetch-select.js +22 -18
- package/addon/components/file.hbs +2 -2
- package/addon/components/filter/multi-option.hbs +1 -1
- package/addon/components/filter/multi-option.js +16 -23
- package/addon/components/filter/select.js +17 -22
- package/addon/components/filters-picker/button.hbs +9 -1
- package/addon/components/filters-picker.hbs +11 -8
- package/addon/components/full-calendar/draggable.hbs +8 -1
- package/addon/components/info-block.hbs +1 -1
- package/addon/components/kanban/card.hbs +23 -0
- package/addon/components/kanban/card.js +94 -0
- package/addon/components/kanban/column.hbs +83 -0
- package/addon/components/kanban/column.js +165 -0
- package/addon/components/kanban.hbs +56 -11
- package/addon/components/kanban.js +136 -1
- package/addon/components/layout/resource/card/body.hbs +3 -0
- package/addon/components/layout/resource/card/body.js +12 -0
- package/addon/components/layout/resource/card/footer.hbs +3 -0
- package/addon/components/layout/resource/card/footer.js +12 -0
- package/addon/components/layout/resource/card/header.hbs +3 -0
- package/addon/components/layout/resource/card/header.js +12 -0
- package/addon/components/layout/resource/card.hbs +11 -0
- package/addon/components/layout/resource/card.js +31 -0
- package/addon/components/layout/resource/cards-grid.hbs +28 -0
- package/addon/components/layout/resource/cards-grid.js +52 -0
- package/addon/components/layout/resource/panel/header-actions.hbs +115 -0
- package/addon/components/layout/resource/panel/header-actions.js +16 -0
- package/addon/components/layout/resource/panel/header.hbs +23 -0
- package/addon/components/layout/resource/panel/header.js +16 -0
- package/addon/components/layout/resource/panel.hbs +56 -0
- package/addon/components/layout/resource/panel.js +111 -0
- package/addon/components/layout/resource/tabular-actions.hbs +122 -0
- package/addon/components/layout/resource/tabular-actions.js +6 -0
- package/addon/components/layout/resource/tabular.hbs +138 -0
- package/addon/components/layout/resource/tabular.js +22 -0
- package/addon/components/layout/section/header.hbs +19 -13
- package/addon/components/layout/sidebar/item.hbs +2 -1
- package/addon/components/layout/sidebar/panel.hbs +2 -0
- package/addon/components/layout/sidebar.js +6 -1
- package/addon/components/layout/yield-sidebar.hbs +3 -0
- package/addon/components/metadata-editor.hbs +121 -0
- package/addon/components/metadata-editor.js +263 -0
- package/addon/components/metadata-viewer.hbs +46 -0
- package/addon/components/metadata-viewer.js +16 -0
- package/addon/components/modal/default.hbs +14 -3
- package/addon/components/modal/default.js +7 -0
- package/addon/components/modal/title-with-buttons.hbs +8 -1
- package/addon/components/modal.hbs +7 -4
- package/addon/components/modal.js +56 -16
- package/addon/components/modals/custom-field-group-form.hbs +5 -0
- package/addon/components/modals/edit-metadata.hbs +3 -0
- package/addon/components/modals/export-report.hbs +46 -0
- package/addon/components/modals/import-form.hbs +1 -1
- package/addon/components/modals/resource.hbs +9 -0
- package/addon/components/modals/save-report.hbs +38 -0
- package/addon/components/modals/verify-by-sms.hbs +1 -1
- package/addon/components/modals/view-metadata.hbs +3 -0
- package/addon/components/modals/view-raw-metadata.hbs +7 -0
- package/addon/components/modals-container.hbs +9 -7
- package/addon/components/modals-container.js +4 -4
- package/addon/components/model-coordinates-input.hbs +8 -0
- package/addon/components/model-coordinates-input.js +71 -0
- package/addon/components/model-multi-file-upload.hbs +67 -0
- package/addon/components/model-multi-file-upload.js +122 -0
- package/addon/components/model-select-multiple.hbs +0 -6
- package/addon/components/model-select.js +1 -1
- package/addon/components/model-tag-input.hbs +15 -0
- package/addon/components/model-tag-input.js +31 -0
- package/addon/components/money-input.hbs +1 -1
- package/addon/components/money-input.js +4 -0
- package/addon/components/overlay/header.hbs +99 -24
- package/addon/components/overlay.hbs +1 -0
- package/addon/components/overlay.js +19 -15
- package/addon/components/query-builder/actions.hbs +19 -0
- package/addon/components/query-builder/actions.js +22 -0
- package/addon/components/query-builder/column-select.hbs +85 -0
- package/addon/components/query-builder/column-select.js +77 -0
- package/addon/components/query-builder/conditions.hbs +242 -0
- package/addon/components/query-builder/conditions.js +496 -0
- package/addon/components/query-builder/group-by.hbs +174 -0
- package/addon/components/query-builder/group-by.js +183 -0
- package/addon/components/query-builder/joins.hbs +142 -0
- package/addon/components/query-builder/joins.js +283 -0
- package/addon/components/query-builder/limit.hbs +74 -0
- package/addon/components/query-builder/limit.js +50 -0
- package/addon/components/query-builder/sort-by.hbs +153 -0
- package/addon/components/query-builder/sort-by.js +175 -0
- package/addon/components/query-builder/table-select.hbs +45 -0
- package/addon/components/query-builder/table-select.js +19 -0
- package/addon/components/query-builder.hbs +79 -0
- package/addon/components/query-builder.js +205 -0
- package/addon/components/report/data.hbs +34 -0
- package/addon/components/report/details.hbs +32 -0
- package/addon/components/report/details.js +3 -0
- package/addon/components/report/form.hbs +3 -0
- package/addon/components/report/form.js +3 -0
- package/addon/components/report-builder/condition-value.hbs +11 -0
- package/addon/components/report-builder/condition-value.js +29 -0
- package/addon/components/report-builder/export-options.hbs +15 -0
- package/addon/components/report-builder/export-options.js +21 -0
- package/addon/components/report-builder/query-builder.hbs +38 -0
- package/addon/components/report-builder/query-builder.js +6 -0
- package/addon/components/report-builder/results-table.hbs +73 -0
- package/addon/components/report-builder/results-table.js +28 -0
- package/addon/components/report-builder.hbs +92 -0
- package/addon/components/report-builder.js +107 -0
- package/addon/components/resource-context-panel.hbs +74 -0
- package/addon/components/resource-context-panel.js +232 -0
- package/addon/components/rules-builder.js +3 -0
- package/addon/components/select.hbs +7 -3
- package/addon/components/spinner.hbs +1 -1
- package/addon/components/spinner.js +38 -1
- package/addon/components/tab-navigation.hbs +120 -0
- package/addon/components/tab-navigation.js +113 -0
- package/addon/components/table/cell/base.hbs +6 -2
- package/addon/components/table.js +8 -0
- package/addon/components/toggle.js +4 -62
- package/addon/components/upload-button.hbs +5 -0
- package/addon/components/view-raw-metadata.hbs +1 -0
- package/addon/components/visible-column-picker.hbs +4 -3
- package/addon/components/with-record.hbs +1 -0
- package/addon/components/with-record.js +40 -0
- package/addon/helpers/can-action.js +27 -0
- package/addon/helpers/can-delete.js +26 -0
- package/addon/helpers/can-write.js +27 -0
- package/addon/helpers/cannot-action.js +24 -0
- package/addon/helpers/cannot-delete.js +23 -0
- package/addon/helpers/cannot-write.js +23 -0
- package/addon/helpers/cfg-edit-buttons.js +21 -0
- package/addon/helpers/component-resolvable.js +13 -4
- package/addon/helpers/format-date-fns.js +63 -0
- package/addon/helpers/get-file-url.js +50 -0
- package/addon/helpers/get-model-name.js +25 -0
- package/addon/helpers/get-write-permission.js +6 -0
- package/addon/helpers/is-model.js +6 -0
- package/addon/helpers/is-url.js +12 -0
- package/addon/helpers/is-uuid.js +6 -0
- package/addon/helpers/join-column-list.js +17 -0
- package/addon/helpers/json-stringify.js +33 -0
- package/addon/helpers/resolve-component.js +23 -0
- package/addon/helpers/resource-context-panel-save-disabled.js +21 -0
- package/addon/helpers/set-has-item.js +5 -0
- package/addon/helpers/set-model-attr.js +23 -0
- package/addon/modifiers/set-height.js +5 -2
- package/addon/modifiers/set-z-index.js +5 -0
- package/addon/modifiers/translate-x.js +5 -0
- package/addon/services/dashboard.js +16 -0
- package/addon/services/modals-manager.js +245 -66
- package/addon/services/resource-context-panel.js +500 -0
- package/addon/services/sidebar.js +39 -0
- package/addon/styles/addon.css +6 -0
- package/addon/styles/components/activity-log.css +31 -0
- package/addon/styles/components/badge.css +41 -1
- package/addon/styles/components/basic-dropdown.css +17 -0
- package/addon/styles/components/button.css +6 -1
- package/addon/styles/components/card-grid.css +53 -0
- package/addon/styles/components/dashboard.css +7 -0
- package/addon/styles/components/ember-power-select.css +10 -0
- package/addon/styles/components/input.css +15 -1
- package/addon/styles/components/kanban.css +170 -25
- package/addon/styles/components/modal.css +14 -2
- package/addon/styles/components/overlay.css +1 -1
- package/addon/styles/components/panel.css +12 -27
- package/addon/styles/components/query-builder.css +387 -0
- package/addon/styles/components/report-builder.css +37 -0
- package/addon/styles/components/resource-context-panel.css +59 -0
- package/addon/styles/components/tab-navigation.css +275 -0
- package/addon/styles/layout/legacy.css +0 -15
- package/addon/styles/layout/next.css +283 -41
- package/addon/styles/layout/utilities.css +19 -2
- package/addon/utils/dom.js +65 -7
- package/addon/utils/get-custom-field-type-map.js +37 -0
- package/addon/utils/options.js +3 -0
- package/addon/utils/permission-check.js +97 -0
- package/addon/utils/remove-nullish.js +4 -0
- package/addon/utils/report-builder.js +63 -0
- package/addon/utils/to-power-select-groups.js +74 -0
- package/app/components/activity-log.js +1 -0
- package/app/components/bulk-search-dropdown.js +1 -0
- package/app/components/custom-field/form.js +1 -0
- package/app/components/custom-field/input.js +1 -0
- package/app/components/custom-field/options-input.js +1 -0
- package/app/components/custom-field/value.js +1 -0
- package/app/components/custom-field/yield.js +1 -0
- package/app/components/custom-fields-manager.js +1 -0
- package/app/components/kanban/card.js +1 -0
- package/app/components/kanban/column.js +1 -0
- package/app/components/layout/resource/card/body.js +1 -0
- package/app/components/layout/resource/card/footer.js +1 -0
- package/app/components/layout/resource/card/header.js +1 -0
- package/app/components/layout/resource/card.js +1 -0
- package/app/components/layout/resource/cards-grid.js +1 -0
- package/app/components/layout/resource/panel/header-actions.js +1 -0
- package/app/components/layout/resource/panel/header.js +1 -0
- package/app/components/layout/resource/panel.js +1 -0
- package/app/components/layout/resource/tabular-actions.js +1 -0
- package/app/components/layout/resource/tabular.js +1 -0
- package/app/components/layout/yield-sidebar.js +1 -0
- package/app/components/metadata-editor.js +1 -0
- package/app/components/metadata-viewer.js +1 -0
- package/app/components/modals/custom-field-group-form.js +1 -0
- package/app/components/modals/edit-metadata.js +1 -0
- package/app/components/modals/export-report.js +1 -0
- package/app/components/modals/resource.js +1 -0
- package/app/components/modals/save-report.js +1 -0
- package/app/components/modals/view-metadata.js +1 -0
- package/app/components/modals/view-raw-metadata.js +1 -0
- package/app/components/model-coordinates-input.js +1 -0
- package/app/components/model-multi-file-upload.js +1 -0
- package/app/components/model-tag-input.js +1 -0
- package/app/components/query-builder/actions.js +1 -0
- package/app/components/query-builder/column-select.js +1 -0
- package/app/components/query-builder/conditions.js +1 -0
- package/app/components/query-builder/group-by.js +1 -0
- package/app/components/query-builder/joins.js +1 -0
- package/app/components/query-builder/limit.js +1 -0
- package/app/components/query-builder/sort-by.js +1 -0
- package/app/components/query-builder/table-select.js +1 -0
- package/app/components/query-builder.js +1 -0
- package/app/components/report/data.js +1 -0
- package/app/components/report/details.js +1 -0
- package/app/components/report/form.js +1 -0
- package/app/components/report-builder/condition-value.js +1 -0
- package/app/components/report-builder/export-options.js +1 -0
- package/app/components/report-builder/query-builder.js +1 -0
- package/app/components/report-builder/results-table.js +1 -0
- package/app/components/report-builder.js +1 -0
- package/app/components/resource-context-panel.js +1 -0
- package/app/components/rules-builder.js +1 -0
- package/app/components/tab-navigation.js +1 -0
- package/app/components/view-raw-metadata.js +1 -0
- package/app/components/with-record.js +1 -0
- package/app/helpers/can-action.js +1 -0
- package/app/helpers/can-delete.js +1 -0
- package/app/helpers/can-write.js +1 -0
- package/app/helpers/cannot-action.js +1 -0
- package/app/helpers/cannot-delete.js +1 -0
- package/app/helpers/cannot-write.js +1 -0
- package/app/helpers/cfg-edit-buttons.js +1 -0
- package/app/helpers/{format-date.js → format-date-fns.js} +1 -1
- package/app/helpers/get-file-url.js +1 -0
- package/app/helpers/get-model-name.js +1 -0
- package/app/helpers/get-write-permission.js +1 -0
- package/app/helpers/is-model.js +1 -0
- package/app/helpers/is-url.js +1 -0
- package/app/helpers/is-uuid.js +1 -0
- package/app/helpers/join-column-list.js +1 -0
- package/app/helpers/json-stringify.js +1 -0
- package/app/helpers/resolve-component.js +1 -0
- package/app/helpers/resource-context-panel-save-disabled.js +1 -0
- package/app/helpers/set-has-item.js +1 -0
- package/app/helpers/set-model-attr.js +1 -0
- package/app/modifiers/set-z-index.js +1 -0
- package/app/modifiers/translate-x.js +1 -0
- package/app/services/resource-context-panel.js +1 -0
- package/app/services/sidebar.js +1 -0
- package/app/utils/get-custom-field-type-map.js +1 -0
- package/app/utils/options.js +1 -0
- package/app/utils/permission-check.js +1 -0
- package/app/utils/remove-nullish.js +1 -0
- package/app/utils/report-builder.js +1 -0
- package/app/utils/to-power-select-groups.js +1 -0
- package/index.js +1 -2
- package/package.json +3 -1
- package/addon/components/kanban/item.js +0 -3
- package/addon/helpers/format-date.js +0 -17
- package/app/components/kanban/item.js +0 -1
- /package/addon/components/{kanban/item.hbs → rules-builder.hbs} +0 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
<div class="activity-log w-full space-y-4" ...attributes>
|
|
2
|
+
<div class="flex items-center justify-between {{@headerWrapperClass}}">
|
|
3
|
+
<div class="text-sm font-semibold tracking-wider uppercase text-gray-500 dark:text-gray-400">{{t "common.activity"}}</div>
|
|
4
|
+
<div class="flex flex-row items-center space-x-2">
|
|
5
|
+
<div>
|
|
6
|
+
{{yield to="filters"}}
|
|
7
|
+
<DatePicker
|
|
8
|
+
@value={{this.dateFilter}}
|
|
9
|
+
@onSelect={{this.setDateFilter}}
|
|
10
|
+
@placeholder={{t "common.filter-by-field" field=(t "common.date")}}
|
|
11
|
+
@range={{true}}
|
|
12
|
+
@toggleSelected={{@toggleSelected}}
|
|
13
|
+
@autoClose={{@autoClose}}
|
|
14
|
+
@buttons={{@dateFilterButtons}}
|
|
15
|
+
class="filter-date-input form-input-sm w-44"
|
|
16
|
+
/>
|
|
17
|
+
</div>
|
|
18
|
+
<Button @size="sm" @icon="refresh" @helpText={{t "common.refresh"}} @isLoading={{this.loadActivities.isRunning}} @onClick={{this.reload}} />
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
{{#each this.groups as |group|}}
|
|
23
|
+
<section class={{@groupClass}}>
|
|
24
|
+
<header class="mb-3 flex items-center gap-3">
|
|
25
|
+
<div class="text-[10px] {{@groupLabelClass}} font-semibold tracking-wider uppercase text-gray-500 dark:text-gray-400">
|
|
26
|
+
{{group.dateLabel}}
|
|
27
|
+
</div>
|
|
28
|
+
<div class="flex-1 border-t border-gray-200 dark:border-gray-800"></div>
|
|
29
|
+
</header>
|
|
30
|
+
|
|
31
|
+
<ol class="relative ml-3 pl-6">
|
|
32
|
+
<span class="absolute left-0 top-0 h-full w-px bg-gray-200 dark:bg-gray-800"></span>
|
|
33
|
+
|
|
34
|
+
{{#each group.items as |item|}}
|
|
35
|
+
<li class="relative mb-4 {{@itemClass}}" data-key={{item.key}}>
|
|
36
|
+
<span class="activity-log-knob"></span>
|
|
37
|
+
|
|
38
|
+
<div class="rounded-xl border border-gray-100 bg-white/90 dark:bg-[#0b0c10] dark:border-gray-800 px-3 py-2 shadow-sm">
|
|
39
|
+
<div class="flex items-start gap-3">
|
|
40
|
+
{{#if this.showAvatars}}
|
|
41
|
+
<img
|
|
42
|
+
src={{or item.actor.avatarUrl "/assets/images/avatar-placeholder.png"}}
|
|
43
|
+
alt={{item.actor.name}}
|
|
44
|
+
class="h-8 w-8 rounded-full ring-1 ring-gray-200 dark:ring-gray-700 object-cover"
|
|
45
|
+
referrerpolicy="no-referrer"
|
|
46
|
+
/>
|
|
47
|
+
{{/if}}
|
|
48
|
+
|
|
49
|
+
<div class="min-w-0 flex-1 {{@itemDetailsClass}}">
|
|
50
|
+
<div class="flex flex-wrap items-center gap-x-2 gap-y-1">
|
|
51
|
+
<span class="text-sm {{@itemSentenceClass}} font-medium text-gray-900 dark:text-gray-100">
|
|
52
|
+
{{item.sentence}}
|
|
53
|
+
</span>
|
|
54
|
+
|
|
55
|
+
{{#if this.showBadges}}
|
|
56
|
+
<span class="{{@itemBadgeClass}} pl-1.5 inline-flex items-center rounded-md px-2 py-0.5 text-xs ring-1 {{item.badge.class}}">
|
|
57
|
+
{{item.badge.text}}
|
|
58
|
+
</span>
|
|
59
|
+
{{/if}}
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
{{#if item.inlineSummary}}
|
|
63
|
+
<div class="{{@itemSummaryClass}} mt-1 text-sm leading-6 text-gray-700 dark:text-gray-300">
|
|
64
|
+
{{item.inlineSummary}}
|
|
65
|
+
</div>
|
|
66
|
+
{{/if}}
|
|
67
|
+
|
|
68
|
+
<div class="{{@itemRelativeTimestampClass}} mt-1 text-xs text-gray-400 dark:text-gray-500">
|
|
69
|
+
<time title={{item.timestamp.exactLocal}} datetime={{item.timestamp.iso}}>
|
|
70
|
+
{{item.timestamp.relative}}
|
|
71
|
+
</time>
|
|
72
|
+
</div>
|
|
73
|
+
|
|
74
|
+
{{#if item.advancedChanges.length}}
|
|
75
|
+
<div class="mt-1">
|
|
76
|
+
<button
|
|
77
|
+
type="button"
|
|
78
|
+
class="text-xs inline-flex items-center gap-1 rounded-md px-1.5 py-1 text-indigo-600 hover:text-indigo-700 dark:text-indigo-300 dark:hover:text-indigo-200"
|
|
79
|
+
{{on "click" (fn this.toggleAdvanced item.key)}}
|
|
80
|
+
>
|
|
81
|
+
<FaIcon @icon={{if (set-has-item this.expanded item.key) "chevron-down" "chevron-right"}} @size="sm" />
|
|
82
|
+
{{#if (set-has-item this.expanded item.key)}}
|
|
83
|
+
Hide advanced
|
|
84
|
+
{{else}}
|
|
85
|
+
Show advanced ({{item.advancedChanges.length}})
|
|
86
|
+
{{/if}}
|
|
87
|
+
</button>
|
|
88
|
+
|
|
89
|
+
{{#if (set-has-item this.expanded item.key)}}
|
|
90
|
+
<div
|
|
91
|
+
class="{{@advancedChangesWrapperClass}} mt-1 rounded-md border border-gray-200 dark:border-gray-800 bg-gray-50 dark:bg-gray-900/40 px-3 py-2 text-xs text-gray-800 dark:text-gray-200 overflow-x-auto"
|
|
92
|
+
>
|
|
93
|
+
{{#each item.advancedChanges as |c|}}
|
|
94
|
+
<div class="py-1 leading-6">
|
|
95
|
+
<span
|
|
96
|
+
class="inline-flex items-center rounded bg-white dark:bg-gray-900 px-2 py-0.5 text-xs font-mono font-medium text-gray-700 dark:text-gray-300 ring-1 ring-inset ring-gray-200 dark:ring-gray-700"
|
|
97
|
+
>
|
|
98
|
+
{{c.key}}
|
|
99
|
+
</span>
|
|
100
|
+
<span class="mx-1 font-mono text-gray-500 dark:text-gray-400">from</span>
|
|
101
|
+
<code
|
|
102
|
+
class="px-1 py-0.5 font-mono rounded bg-white dark:bg-gray-900 ring-1 ring-gray-200 dark:ring-gray-700 text-gray-900 dark:text-gray-100"
|
|
103
|
+
>{{c.from}}</code>
|
|
104
|
+
<span class="mx-1 font-mono text-gray-500 dark:text-gray-400">to</span>
|
|
105
|
+
<code
|
|
106
|
+
class="px-1 py-0.5 font-mono rounded bg-white dark:bg-gray-900 ring-1 ring-gray-200 dark:ring-gray-700 text-gray-900 dark:text-gray-100"
|
|
107
|
+
>{{c.to}}</code>
|
|
108
|
+
</div>
|
|
109
|
+
{{/each}}
|
|
110
|
+
</div>
|
|
111
|
+
{{/if}}
|
|
112
|
+
</div>
|
|
113
|
+
{{/if}}
|
|
114
|
+
</div>
|
|
115
|
+
</div>
|
|
116
|
+
</div>
|
|
117
|
+
</li>
|
|
118
|
+
{{/each}}
|
|
119
|
+
</ol>
|
|
120
|
+
</section>
|
|
121
|
+
{{/each}}
|
|
122
|
+
|
|
123
|
+
{{#if (eq this.groups.length 0)}}
|
|
124
|
+
<div class="min-h-24 p-4 col-span-2">
|
|
125
|
+
<div class="flex items-center justify-center border border-dashed border-gray-300 dark:border-gray-600 p-6 rounded-xl bg-gray-50 dark:bg-gray-800">
|
|
126
|
+
<div class="text-center">
|
|
127
|
+
{{#if this.loadActivities.isRunning}}
|
|
128
|
+
<Spinner @loadingMessage="Loading activity..." />
|
|
129
|
+
{{else}}
|
|
130
|
+
<FaIcon @icon="bars-staggered" @size="2x" class="text-gray-400 mb-2" />
|
|
131
|
+
<div class="text-sm text-gray-600 dark:text-gray-400 font-medium">No activity yet</div>
|
|
132
|
+
{{/if}}
|
|
133
|
+
</div>
|
|
134
|
+
</div>
|
|
135
|
+
</div>
|
|
136
|
+
{{/if}}
|
|
137
|
+
</div>
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
import Component from '@glimmer/component';
|
|
2
|
+
import { tracked } from '@glimmer/tracking';
|
|
3
|
+
import { inject as service } from '@ember/service';
|
|
4
|
+
import { action } from '@ember/object';
|
|
5
|
+
import { debug } from '@ember/debug';
|
|
6
|
+
import { isArray } from '@ember/array';
|
|
7
|
+
import { capitalize } from '@ember/string';
|
|
8
|
+
import { htmlSafe } from '@ember/template';
|
|
9
|
+
import { task } from 'ember-concurrency';
|
|
10
|
+
import { parseISO, isDate, isValid, format, formatDistanceToNow } from 'date-fns';
|
|
11
|
+
import smartHumanize from '../utils/smart-humanize';
|
|
12
|
+
|
|
13
|
+
export default class ActivityLogComponent extends Component {
|
|
14
|
+
@service store;
|
|
15
|
+
@tracked activities = [];
|
|
16
|
+
@tracked expanded = new Set();
|
|
17
|
+
@tracked dateFilter = null;
|
|
18
|
+
@tracked query = null;
|
|
19
|
+
|
|
20
|
+
// Optional style “knobs” (you can pass in from the parent)
|
|
21
|
+
get density() {
|
|
22
|
+
return this.args.density ?? 'compact';
|
|
23
|
+
} // 'cozy'|'compact'
|
|
24
|
+
get showAvatars() {
|
|
25
|
+
return this.args.showAvatars ?? true;
|
|
26
|
+
}
|
|
27
|
+
get showBadges() {
|
|
28
|
+
return this.args.showBadges ?? true;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
get groups() {
|
|
32
|
+
const activities = isArray(this.activities) ? this.activities : [];
|
|
33
|
+
|
|
34
|
+
const normalized = activities.map((a, i) => this.#normalizeActivity(a, i)).sort((a, b) => (b.timestamp?.dateMs ?? 0) - (a.timestamp?.dateMs ?? 0));
|
|
35
|
+
|
|
36
|
+
const byDay = new Map();
|
|
37
|
+
for (const item of normalized) {
|
|
38
|
+
const key = item.dayKey ?? 'unknown';
|
|
39
|
+
if (!byDay.has(key)) byDay.set(key, { dateLabel: item.dayLabel ?? key, items: [] });
|
|
40
|
+
byDay.get(key).items.push(item);
|
|
41
|
+
}
|
|
42
|
+
return [...byDay.values()];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
constructor() {
|
|
46
|
+
super(...arguments);
|
|
47
|
+
this.loadActivities.perform();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// ── Data ────────────────────────────────────────────────────────────────────
|
|
51
|
+
@task *loadActivities() {
|
|
52
|
+
try {
|
|
53
|
+
const params = {};
|
|
54
|
+
if (this.args.subjectId) params.subject_id = this.args.subjectId;
|
|
55
|
+
if (this.args.causerId) params.causer_id = this.args.causerId;
|
|
56
|
+
if (this.dateFilter) params.created_at = this.dateFilter;
|
|
57
|
+
|
|
58
|
+
const activities = yield this.store.query('activity', params);
|
|
59
|
+
this.activities = activities.toArray();
|
|
60
|
+
} catch (err) {
|
|
61
|
+
debug('Failed to load activities: ' + err.message);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@action reload() {
|
|
66
|
+
this.loadActivities.perform();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@action setDateFilter({ formattedDate }) {
|
|
70
|
+
this.dateFilter = formattedDate;
|
|
71
|
+
this.loadActivities.perform();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
@action onCauserClick(causer) {
|
|
75
|
+
if (typeof this.args.onCauserClick === 'function') this.args.onCauserClick(causer);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
@action onSubjectClick(subject) {
|
|
79
|
+
if (typeof this.args.onSubjectClick === 'function') this.args.onSubjectClick(subject);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
@action toggleAdvanced(itemKey) {
|
|
83
|
+
const next = new Set(this.expanded);
|
|
84
|
+
next.has(itemKey) ? next.delete(itemKey) : next.add(itemKey);
|
|
85
|
+
this.expanded = next;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// ── Normalize & Phrase ──────────────────────────────────────────────────────
|
|
89
|
+
#normalizeActivity(activity, idx = 0) {
|
|
90
|
+
const createdISO = activity?.created_at ?? null;
|
|
91
|
+
const updatedISO = activity?.updated_at ?? null;
|
|
92
|
+
const tsISO = createdISO ?? updatedISO ?? null;
|
|
93
|
+
|
|
94
|
+
const d = this.#parseDate(tsISO);
|
|
95
|
+
const dateMs = d ? d.getTime() : 0;
|
|
96
|
+
const dayKey = d ? format(d, 'yyyy-MM-dd') : 'unknown';
|
|
97
|
+
const dayLabel = d ? format(d, 'EEE, MMM dd, yyyy') : 'Unknown date';
|
|
98
|
+
const exactLocal = d ? format(d, 'PP p') : '';
|
|
99
|
+
const relative = d ? formatDistanceToNow(d, { addSuffix: true }) : '';
|
|
100
|
+
|
|
101
|
+
const causer = activity?.causer ?? {};
|
|
102
|
+
const subject = activity?.subject ?? {};
|
|
103
|
+
const subjectTypeLabel = activity?.humanized_subject_type ?? this.#subjectTypeLabel(activity?.subject_type);
|
|
104
|
+
const subjectDisplay = this.#subjectDisplay(subject);
|
|
105
|
+
const event = String(activity?.event || '').toLowerCase();
|
|
106
|
+
|
|
107
|
+
const eventLabel = capitalize(event || 'updated');
|
|
108
|
+
const verb = this.#eventToVerb(event, activity?.description);
|
|
109
|
+
|
|
110
|
+
// Diffs → split into simple vs advanced, and also build a human inline sentence
|
|
111
|
+
const allChanges = this.#computeChanges(activity?.properties);
|
|
112
|
+
const simpleChanges = [];
|
|
113
|
+
const advancedChanges = [];
|
|
114
|
+
|
|
115
|
+
for (const c of allChanges) {
|
|
116
|
+
if (this.#isAdvancedValue(c.fromRaw, c.toRaw) || this.#isLikelyUuidKey(c.key)) {
|
|
117
|
+
advancedChanges.push(c);
|
|
118
|
+
} else {
|
|
119
|
+
simpleChanges.push(c);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const inlineSummary = this.#summarizeSimple(simpleChanges);
|
|
124
|
+
|
|
125
|
+
const sentence = `${causer?.name ?? 'Someone'} ${verb} ${subjectTypeLabel} (${subjectDisplay})`;
|
|
126
|
+
|
|
127
|
+
// Event → badge style (Fleetbase-ish accent mapping)
|
|
128
|
+
const badge = this.#eventBadge(event);
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
key: `${dayKey}-${idx}`,
|
|
132
|
+
actor: {
|
|
133
|
+
name: causer?.name ?? 'Unknown',
|
|
134
|
+
avatarUrl: causer?.avatar_url ?? null,
|
|
135
|
+
raw: causer,
|
|
136
|
+
},
|
|
137
|
+
subject,
|
|
138
|
+
causer,
|
|
139
|
+
verb,
|
|
140
|
+
event,
|
|
141
|
+
eventLabel,
|
|
142
|
+
badge, // {text, class}
|
|
143
|
+
subjectTypeLabel,
|
|
144
|
+
subjectDisplay,
|
|
145
|
+
sentence,
|
|
146
|
+
inlineSummary, // "set color to red; status to live"
|
|
147
|
+
timestamp: {
|
|
148
|
+
iso: tsISO,
|
|
149
|
+
exactLocal,
|
|
150
|
+
relative,
|
|
151
|
+
dateMs,
|
|
152
|
+
},
|
|
153
|
+
dayKey,
|
|
154
|
+
dayLabel,
|
|
155
|
+
simpleChanges,
|
|
156
|
+
advancedChanges,
|
|
157
|
+
raw: activity,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
#summarizeSimple(simpleChanges) {
|
|
162
|
+
if (!simpleChanges?.length) return '';
|
|
163
|
+
|
|
164
|
+
const parts = [];
|
|
165
|
+
for (const c of simpleChanges) {
|
|
166
|
+
const k = c.key.replace(/_/g, ' ');
|
|
167
|
+
|
|
168
|
+
if (c.from !== 'null' && c.from !== undefined && c.from !== '' && c.from !== c.to) {
|
|
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>`
|
|
171
|
+
);
|
|
172
|
+
} else {
|
|
173
|
+
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>`
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Make the entire thing safe once at the end
|
|
180
|
+
return htmlSafe(parts.join(', '));
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
#code(v) {
|
|
184
|
+
// lightweight backtick wrapper for inline emphasis
|
|
185
|
+
return this.args.backtickValues ? `\`${String(v)}\`` : v;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
#eventToVerb(event, description) {
|
|
189
|
+
if (description && typeof description === 'string') return description;
|
|
190
|
+
switch (event) {
|
|
191
|
+
case 'created':
|
|
192
|
+
return 'created';
|
|
193
|
+
case 'deleted':
|
|
194
|
+
return 'deleted';
|
|
195
|
+
case 'restored':
|
|
196
|
+
return 'restored';
|
|
197
|
+
default:
|
|
198
|
+
return 'updated';
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
#eventBadge(event) {
|
|
203
|
+
// Tailwind classes set to feel like Fleetbase pills
|
|
204
|
+
switch (event) {
|
|
205
|
+
case 'created':
|
|
206
|
+
return { text: 'Created', class: 'bg-green-50 text-green-700 ring-green-200 dark:bg-green-900/20 dark:text-green-300 dark:ring-green-800' };
|
|
207
|
+
case 'deleted':
|
|
208
|
+
return { text: 'Deleted', class: 'bg-red-50 text-red-700 ring-red-200 dark:bg-red-900/20 dark:text-red-300 dark:ring-red-800' };
|
|
209
|
+
case 'restored':
|
|
210
|
+
return { text: 'Restored', class: 'bg-blue-50 text-blue-700 ring-blue-200 dark:bg-blue-900/20 dark:text-blue-300 dark:ring-blue-800' };
|
|
211
|
+
default:
|
|
212
|
+
return { text: 'Updated', class: 'bg-indigo-50 text-indigo-700 ring-indigo-200 dark:bg-indigo-900/20 dark:text-indigo-300 dark:ring-indigo-800' };
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// ── Changes & formatting ─────────────────────────────────────────────────────
|
|
217
|
+
#computeChanges(properties) {
|
|
218
|
+
const attrs = properties?.attributes ?? {};
|
|
219
|
+
const old = properties?.old ?? {};
|
|
220
|
+
const keys = new Set([...Object.keys(attrs), ...Object.keys(old)]);
|
|
221
|
+
const out = [];
|
|
222
|
+
|
|
223
|
+
for (const key of keys) {
|
|
224
|
+
const next = attrs[key];
|
|
225
|
+
const prev = old[key];
|
|
226
|
+
const same = next === prev || (next == null && prev == null) || (this.#isPlainObject(next) && this.#isPlainObject(prev) && JSON.stringify(next) === JSON.stringify(prev));
|
|
227
|
+
if (same) continue;
|
|
228
|
+
|
|
229
|
+
out.push({
|
|
230
|
+
key,
|
|
231
|
+
from: this.#formatValue(prev),
|
|
232
|
+
to: this.#formatValue(next),
|
|
233
|
+
fromRaw: prev,
|
|
234
|
+
toRaw: next,
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const priority = ['status', 'scheduled_at', 'name', 'title', 'color', 'plate_number', 'updated_at', 'created_at'];
|
|
239
|
+
out.sort((a, b) => {
|
|
240
|
+
const ai = priority.indexOf(a.key);
|
|
241
|
+
const bi = priority.indexOf(b.key);
|
|
242
|
+
if (ai !== -1 || bi !== -1) return (ai === -1 ? 99 : ai) - (bi === -1 ? 99 : bi);
|
|
243
|
+
return a.key.localeCompare(b.key);
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
return out;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
#isAdvancedValue(a, b) {
|
|
250
|
+
const isComplex = (v) => this.#isPlainObject(v) || isArray(v) || (typeof v === 'string' && (this.#looksLikeUuid(v) || v.length > 32));
|
|
251
|
+
return isComplex(a) || isComplex(b);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
#isLikelyUuidKey(key) {
|
|
255
|
+
return typeof key === 'string' && (key.endsWith('_uuid') || key === 'uuid' || key.endsWith('Id') || key.endsWith('_id'));
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
#looksLikeUuid(v) {
|
|
259
|
+
return /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$/.test(v);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
#parseDate(input) {
|
|
263
|
+
if (!input) return null;
|
|
264
|
+
if (isDate(input)) return isValid(input) ? input : null;
|
|
265
|
+
try {
|
|
266
|
+
const d = parseISO(String(input));
|
|
267
|
+
return isValid(d) ? d : null;
|
|
268
|
+
} catch {
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
#subjectTypeLabel(subjectType) {
|
|
274
|
+
if (!subjectType || typeof subjectType !== 'string') return '';
|
|
275
|
+
const parts = subjectType.split('\\').filter(Boolean);
|
|
276
|
+
let lastSegment = parts[parts.length - 1];
|
|
277
|
+
if (lastSegment) {
|
|
278
|
+
return smartHumanize(lastSegment);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
return subjectType;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
#subjectDisplay(subject) {
|
|
285
|
+
if (!subject) return 'Unknown';
|
|
286
|
+
return subject.display_name || subject.name || subject.title || subject.address || subject.tracking || subject.public_id || subject.uuid || 'Unknown';
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
#isPlainObject(v) {
|
|
290
|
+
return v && typeof v === 'object' && !isArray(v);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
#formatValue(v) {
|
|
294
|
+
if (v === null || v === undefined) return 'null';
|
|
295
|
+
if (typeof v === 'boolean') return v ? 'true' : 'false';
|
|
296
|
+
if (isArray(v)) return v.length ? JSON.stringify(v) : '[]';
|
|
297
|
+
if (this.#isPlainObject(v)) {
|
|
298
|
+
if (v.type === 'Point' && isArray(v.coordinates)) {
|
|
299
|
+
const [lng, lat] = v.coordinates;
|
|
300
|
+
return `Point(${lat}, ${lng})`;
|
|
301
|
+
}
|
|
302
|
+
return JSON.stringify(v);
|
|
303
|
+
}
|
|
304
|
+
if (typeof v === 'string' && /^\d{4}-\d{2}-\d{2}T/.test(v)) {
|
|
305
|
+
const d = this.#parseDate(v);
|
|
306
|
+
if (d) return format(d, 'PP p');
|
|
307
|
+
}
|
|
308
|
+
return String(v);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<div class="status-badge {{safe-dasherize (or @type @status
|
|
1
|
+
<div class="status-badge {{safe-dasherize (or @type @status 'info')}}-status-badge {{@wrapperClass}}" ...attributes>
|
|
2
2
|
<span
|
|
3
3
|
class="status-badge-inner-wrap inline-flex items-center
|
|
4
4
|
{{unless @roundedFull 'px-2 py-0.5 rounded' 'badge-rounded-full'}}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<DropdownButton @icon={{or @icon "magnifying-glass"}} @buttonWrapperClass={{@buttonWrapperClass}} @size={{or @size "xs"}} as |dd|>
|
|
2
|
+
<div class="bulk-search-dropdown-container filters-dropdown-container">
|
|
3
|
+
<div class="filters-dropdown-header">
|
|
4
|
+
<h4>{{or @title "Bulk Search"}}</h4>
|
|
5
|
+
</div>
|
|
6
|
+
<div class="filters-dropdown-body">
|
|
7
|
+
<Textarea @value={{this.value}} class="form-input w-full" rows={{or @rows "8"}} placeholder={{or @placeholder "Input comma delimited ID's to perform a bulk search"}} />
|
|
8
|
+
</div>
|
|
9
|
+
<div class="filters-dropdown-footer space-x-2">
|
|
10
|
+
<Button @text="Clear" @icon="trash" @size="xs" @onClick={{dropdown-fn dd this.clear}} />
|
|
11
|
+
<Button @text="Search" @icon="check" @type="primary" @size="xs" @onClick={{dropdown-fn dd this.submit}} />
|
|
12
|
+
</div>
|
|
13
|
+
</div>
|
|
14
|
+
</DropdownButton>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import Component from '@glimmer/component';
|
|
2
|
+
import { tracked } from '@glimmer/tracking';
|
|
3
|
+
import { action } from '@ember/object';
|
|
4
|
+
|
|
5
|
+
export default class BulkSearchDropdownComponent extends Component {
|
|
6
|
+
@tracked value = '';
|
|
7
|
+
|
|
8
|
+
constructor(owner, { value = '' }) {
|
|
9
|
+
super(...arguments);
|
|
10
|
+
this.value = value;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
@action clear() {
|
|
14
|
+
this.value = '';
|
|
15
|
+
|
|
16
|
+
if (typeof this.args.onClear === 'function') {
|
|
17
|
+
this.args.onClear(this.value);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@action submit() {
|
|
22
|
+
if (typeof this.args.onSubmit === 'function') {
|
|
23
|
+
this.args.onSubmit(this.value);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
{{#if this.visible}}
|
|
2
|
-
<span
|
|
2
|
+
<span
|
|
3
|
+
class="btn-wrapper {{@wrapperClass}} inline-flex rounded-md {{if this.isNotSecondary 'shadow-sm'}} {{if @isLoading 'is-loading'}}"
|
|
4
|
+
{{did-insert this.setupComponent}}
|
|
5
|
+
{{did-update this.onArgsChanged @disabled @visible @permission}}
|
|
6
|
+
>
|
|
3
7
|
<button
|
|
4
8
|
class="btn {{if @isLoading 'btn-is-loading'}} {{if @outline 'btn-outline'}} btn-{{or @type 'default'}} btn-{{or @size 'sm'}}"
|
|
5
9
|
disabled={{this.isDisabled}}
|
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
<div class="thread-comment-content-wrapper flex-1">
|
|
6
6
|
<div class="thread-comment-author flex flex-row items-center">
|
|
7
7
|
<div class="thread-comment-author-name text-sm dark:text-white text-black font-bold mr-1.5">{{this.comment.author.name}}</div>
|
|
8
|
-
<div class="thread-comment-created-at dark:text-gray-300 text-gray-600 text-xs">{{t "
|
|
8
|
+
<div class="thread-comment-created-at dark:text-gray-300 text-gray-600 text-xs">{{t "comment-thread.comment-published-ago" createdAgo=this.comment.createdAgo}}</div>
|
|
9
9
|
</div>
|
|
10
10
|
<div class="thread-comment-conent-paragraph-wrapper mt-2">
|
|
11
11
|
{{#if this.editing}}
|
|
12
12
|
<Textarea
|
|
13
13
|
@value={{this.comment.content}}
|
|
14
14
|
class="form-input w-full"
|
|
15
|
-
placeholder={{t "
|
|
15
|
+
placeholder={{t "comment-thread.comment-reply-placeholder"}}
|
|
16
16
|
rows={{2}}
|
|
17
17
|
disabled={{not this.updateComment.isIdle}}
|
|
18
18
|
/>
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
@iconSize="xs"
|
|
44
44
|
@textClass="text-xs"
|
|
45
45
|
@icon="reply"
|
|
46
|
-
@text={{t "
|
|
46
|
+
@text={{t "comment-thread.reply-comment-button-text"}}
|
|
47
47
|
@onClick={{this.reply}}
|
|
48
48
|
/>
|
|
49
49
|
{{#if this.comment.editable}}
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
@iconSize="xs"
|
|
56
56
|
@textClass="text-xs"
|
|
57
57
|
@icon="edit"
|
|
58
|
-
@text={{t "
|
|
58
|
+
@text={{t "comment-thread.edit-comment-button-text"}}
|
|
59
59
|
@onClick={{this.edit}}
|
|
60
60
|
/>
|
|
61
61
|
<Button
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
@iconClass="text-xs text-danger"
|
|
68
68
|
@textClass="text-xs text-danger"
|
|
69
69
|
@icon="trash"
|
|
70
|
-
@text={{t "
|
|
70
|
+
@text={{t "comment-thread.delete-comment-button-text"}}
|
|
71
71
|
@onClick={{this.delete}}
|
|
72
72
|
/>
|
|
73
73
|
{{/if}}
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
<Textarea
|
|
78
78
|
@value={{this.input}}
|
|
79
79
|
class="form-input w-full"
|
|
80
|
-
placeholder={{t "
|
|
80
|
+
placeholder={{t "comment-thread.comment-reply-placeholder"}}
|
|
81
81
|
rows={{2}}
|
|
82
82
|
disabled={{not this.publishReply.isIdle}}
|
|
83
83
|
/>
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
@size="xs"
|
|
91
91
|
@iconSize="xs"
|
|
92
92
|
@iconClass="text-xs"
|
|
93
|
-
@text={{t "
|
|
93
|
+
@text={{t "comment-thread.publish-reply-button-text"}}
|
|
94
94
|
@onClick={{perform this.publishReply}}
|
|
95
95
|
@disabled={{or (not this.publishReply.isIdle) (not this.input)}}
|
|
96
96
|
/>
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
<div class="flex flex-col mb-4" ...attributes>
|
|
2
|
-
<Textarea @value={{this.input}} class="form-input w-full" placeholder={{t "
|
|
2
|
+
<Textarea @value={{this.input}} class="form-input w-full" placeholder={{t "comment-thread.comment-input-placeholder"}} rows={{3}} disabled={{not this.publishComment.isIdle}} />
|
|
3
3
|
<div class="flex flex-row items-center justify-end mt-2">
|
|
4
4
|
<Button
|
|
5
5
|
@type="primary"
|
|
6
6
|
@buttonType="button"
|
|
7
7
|
@icon="paper-plane"
|
|
8
|
-
@text={{t "
|
|
8
|
+
@text={{t "comment-thread.publish-comment-button-text"}}
|
|
9
9
|
@onClick={{perform this.publishComment}}
|
|
10
10
|
@disabled={{or (not this.publishComment.isIdle) (not this.input)}}
|
|
11
11
|
/>
|