avo 4.0.0.beta.2 → 4.0.0.beta.4
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/Gemfile.lock +1 -1
- data/app/assets/builds/avo/application.css +355 -51
- data/app/assets/builds/avo/application.js +166 -166
- data/app/assets/builds/avo/application.js.map +4 -4
- data/app/assets/stylesheets/application.css +2 -0
- data/app/assets/stylesheets/css/components/hotkey.css +50 -0
- data/app/assets/stylesheets/css/components/input.css +0 -6
- data/app/assets/stylesheets/css/components/ui/state.css +129 -0
- data/app/assets/stylesheets/css/layout.css +3 -4
- data/app/assets/stylesheets/css/pagination.css +12 -6
- data/app/assets/stylesheets/css/typography.css +18 -1
- data/app/assets/svgs/avo/circle-minus.svg +3 -0
- data/app/components/avo/alert_component.rb +4 -4
- data/app/components/avo/backtrace_alert_component.html.erb +1 -1
- data/app/components/avo/base_component.rb +9 -0
- data/app/components/avo/button_component.rb +2 -1
- data/app/components/avo/debug/status_component.html.erb +2 -2
- data/app/components/avo/empty_state_component.html.erb +15 -4
- data/app/components/avo/empty_state_component.rb +9 -0
- data/app/components/avo/fields/common/files/view_type/grid_item_component.html.erb +1 -1
- data/app/components/avo/fields/common/key_value_component.html.erb +1 -1
- data/app/components/avo/fields/common/stars_component.html.erb +1 -1
- data/app/components/avo/fields/common/status_viewer_component.html.erb +3 -3
- data/app/components/avo/fields/preview_field/index_component.rb +1 -1
- data/app/components/avo/fields/stars_field/edit_component.html.erb +1 -1
- data/app/components/avo/filters_component.html.erb +1 -1
- data/app/components/avo/items/switcher_component.html.erb +1 -1
- data/app/components/avo/keyboard_shortcuts_component.html.erb +29 -0
- data/app/components/avo/keyboard_shortcuts_component.rb +127 -0
- data/app/components/avo/media_library/item_details_component.html.erb +2 -2
- data/app/components/avo/media_library/list_component.html.erb +1 -1
- data/app/components/avo/media_library/list_item_component.html.erb +2 -2
- data/app/components/avo/modal_component.html.erb +39 -15
- data/app/components/avo/modal_component.rb +10 -0
- data/app/components/avo/paginator_component.html.erb +23 -17
- data/app/components/avo/paginator_component.rb +18 -0
- data/app/components/avo/resource_component.rb +14 -7
- data/app/components/avo/sidebar/group_component.html.erb +1 -1
- data/app/components/avo/sidebar/link_component.html.erb +13 -5
- data/app/components/avo/sidebar/link_component.rb +17 -0
- data/app/components/avo/sidebar/section_component.html.erb +1 -1
- data/app/components/avo/sidebar_component.html.erb +2 -2
- data/app/components/avo/sidebar_profile_component.html.erb +1 -1
- data/app/components/avo/u_i/search_input_component.html.erb +2 -2
- data/app/components/avo/views/resource_index_component.rb +1 -1
- data/app/javascript/application.js +12 -28
- data/app/javascript/js/controllers/base_modal_controller.js +65 -0
- data/app/javascript/js/controllers/confirm_dialog_controller.js +18 -0
- data/app/javascript/js/controllers/modal_controller.js +18 -26
- data/app/javascript/js/controllers/persistent_modal_controller.js +50 -0
- data/app/javascript/js/controllers/search_controller.js +0 -4
- data/app/javascript/js/controllers/sidebar_controller.js +22 -0
- data/app/javascript/js/controllers.js +4 -0
- data/app/javascript/js/global_hotkeys.js +77 -0
- data/app/javascript/js/helpers/toggle_hidden.js +7 -0
- data/app/views/avo/actions/show.html.erb +1 -1
- data/app/views/avo/base/_date_time_filter.html.erb +1 -1
- data/app/views/avo/base/preview.html.erb +1 -1
- data/app/views/avo/debug/_valid_indicator.html.erb +2 -2
- data/app/views/avo/home/failed_to_load.html.erb +40 -13
- data/app/views/avo/media_library/_form.html.erb +1 -1
- data/app/views/avo/partials/_color_scheme_switcher.html.erb +4 -4
- data/app/views/avo/partials/_confirm_dialog.html.erb +3 -3
- data/app/views/avo/partials/_custom_tools_alert.html.erb +3 -3
- data/app/views/avo/partials/_sortable_component.html.erb +3 -3
- data/app/views/avo/partials/_table_header.html.erb +1 -1
- data/app/views/avo/private/_links_and_buttons.html.erb +2 -2
- data/app/views/avo/private/design.html.erb +4 -4
- data/app/views/avo/sidebar/_license_warning.html.erb +2 -2
- data/app/views/layouts/avo/application.html.erb +1 -0
- data/lib/avo/resources/base.rb +1 -0
- data/lib/avo/version.rb +1 -1
- data/lib/generators/avo/resource_generator.rb +3 -3
- data/lib/generators/avo/templates/initializer/avo.tt +4 -4
- data/lib/generators/avo/templates/resource_tools/partial.tt +1 -1
- metadata +11 -15
- data/app/assets/svgs/avo/arrow-circle-right.svg +0 -1
- data/app/assets/svgs/avo/bell.svg +0 -3
- data/app/assets/svgs/avo/color-swatch.svg +0 -1
- data/app/assets/svgs/avo/dashboards.svg +0 -6
- data/app/assets/svgs/avo/exclamation.svg +0 -1
- data/app/assets/svgs/avo/filter.svg +0 -1
- data/app/assets/svgs/avo/logout.svg +0 -3
- data/app/assets/svgs/avo/resources.svg +0 -13
- data/app/assets/svgs/avo/save.svg +0 -8
- data/app/assets/svgs/avo/selector.svg +0 -1
- data/app/assets/svgs/avo/sort-ascending.svg +0 -1
- data/app/assets/svgs/avo/sort-descending.svg +0 -1
- data/app/assets/svgs/avo/times.svg +0 -3
- data/app/assets/svgs/avo/tools.svg +0 -3
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Controller } from '@hotwired/stimulus'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Shared behaviour for both modal strategies (destroy & toggle).
|
|
5
|
+
* Not registered with Stimulus directly — subclasses are.
|
|
6
|
+
*/
|
|
7
|
+
export default class extends Controller {
|
|
8
|
+
static targets = ['modal', 'backdrop']
|
|
9
|
+
|
|
10
|
+
static values = {
|
|
11
|
+
closeModalOnBackdropClick: { type: Boolean, default: true },
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// -- lifecycle ------------------------------------------------------------
|
|
15
|
+
|
|
16
|
+
connectModal() {
|
|
17
|
+
this.handleKeydown = this.handleKeydown.bind(this)
|
|
18
|
+
document.addEventListener('keydown', this.handleKeydown)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
disconnectModal() {
|
|
22
|
+
document.removeEventListener('keydown', this.handleKeydown)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// -- shared actions -------------------------------------------------------
|
|
26
|
+
|
|
27
|
+
handleKeydown(event) {
|
|
28
|
+
if (event.key === 'Escape' && this.isOpen() && this.closeModalOnBackdropClickValue) {
|
|
29
|
+
this.closeModal()
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** Backdrop click action — wired via data-action="click->…#close" */
|
|
34
|
+
close(event) {
|
|
35
|
+
if (event.target === this.backdropTarget) return
|
|
36
|
+
|
|
37
|
+
this.closeModal()
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// -- helpers --------------------------------------------------------------
|
|
41
|
+
|
|
42
|
+
addModalOpen() {
|
|
43
|
+
document.body.classList.add('modal-open')
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
removeModalOpen() {
|
|
47
|
+
document.body.classList.remove('modal-open')
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
dispatchClose() {
|
|
51
|
+
document.dispatchEvent(new Event('modal-controller:close'))
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// -- subclass contract (override in each strategy) ------------------------
|
|
55
|
+
|
|
56
|
+
/** @abstract */
|
|
57
|
+
closeModal() {
|
|
58
|
+
throw new Error('Subclass must implement closeModal()')
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** @abstract */
|
|
62
|
+
isOpen() {
|
|
63
|
+
throw new Error('Subclass must implement isOpen()')
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Controller } from '@hotwired/stimulus'
|
|
2
|
+
|
|
3
|
+
export default class extends Controller {
|
|
4
|
+
static targets = ['option']
|
|
5
|
+
|
|
6
|
+
navigate(event) {
|
|
7
|
+
if (!['ArrowDown', 'ArrowUp'].includes(event.key)) return
|
|
8
|
+
event.preventDefault()
|
|
9
|
+
|
|
10
|
+
const options = this.optionTargets
|
|
11
|
+
const index = options.indexOf(document.activeElement)
|
|
12
|
+
const next = event.key === 'ArrowDown'
|
|
13
|
+
? (index + 1) % options.length
|
|
14
|
+
: (index - 1 + options.length) % options.length
|
|
15
|
+
|
|
16
|
+
options[next]?.focus()
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -1,39 +1,31 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
import BaseModalController from './base_modal_controller'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Inject / destroy strategy.
|
|
5
|
+
*
|
|
6
|
+
* The modal is added to the DOM (usually via Turbo) when it should appear
|
|
7
|
+
* and removed entirely when it is closed.
|
|
8
|
+
*/
|
|
9
|
+
export default class extends BaseModalController {
|
|
11
10
|
connect() {
|
|
12
|
-
|
|
13
|
-
this.
|
|
14
|
-
|
|
11
|
+
this.connectModal()
|
|
12
|
+
this.addModalOpen()
|
|
13
|
+
this.modalTarget.focus()
|
|
15
14
|
}
|
|
16
15
|
|
|
17
16
|
disconnect() {
|
|
18
|
-
|
|
17
|
+
this.disconnectModal()
|
|
19
18
|
}
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
if (event.key === 'Escape' && this.closeModalOnBackdropClickValue) {
|
|
23
|
-
this.closeModal()
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
close(event) {
|
|
28
|
-
if (event.target === this.backdropTarget && !this.closeModalOnBackdropClickValue) return
|
|
20
|
+
// -- strategy implementation ----------------------------------------------
|
|
29
21
|
|
|
30
|
-
|
|
22
|
+
isOpen() {
|
|
23
|
+
return true // if the element is in the DOM it's open
|
|
31
24
|
}
|
|
32
25
|
|
|
33
|
-
// May be invoked by the other controllers
|
|
34
26
|
closeModal() {
|
|
35
27
|
this.modalTarget.remove()
|
|
36
|
-
|
|
37
|
-
|
|
28
|
+
this.removeModalOpen()
|
|
29
|
+
this.dispatchClose()
|
|
38
30
|
}
|
|
39
31
|
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import BaseModalController from './base_modal_controller'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Persistent / show-hide strategy.
|
|
5
|
+
*
|
|
6
|
+
* The modal lives in the DOM at all times. It starts with the `hidden`
|
|
7
|
+
* attribute and is revealed / hidden by toggling that attribute.
|
|
8
|
+
*/
|
|
9
|
+
export default class extends BaseModalController {
|
|
10
|
+
connect() {
|
|
11
|
+
this.connectModal()
|
|
12
|
+
|
|
13
|
+
this.handleOpen = this.openModal.bind(this)
|
|
14
|
+
this.handleToggle = this.toggleModal.bind(this)
|
|
15
|
+
document.addEventListener('persistent-modal:open', this.handleOpen)
|
|
16
|
+
document.addEventListener('persistent-modal:toggle', this.handleToggle)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
disconnect() {
|
|
20
|
+
this.disconnectModal()
|
|
21
|
+
document.removeEventListener('persistent-modal:open', this.handleOpen)
|
|
22
|
+
document.removeEventListener('persistent-modal:toggle', this.handleToggle)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// -- strategy implementation ----------------------------------------------
|
|
26
|
+
|
|
27
|
+
isOpen() {
|
|
28
|
+
return !this.modalTarget.hasAttribute('hidden')
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
closeModal() {
|
|
32
|
+
this.modalTarget.setAttribute('hidden', '')
|
|
33
|
+
this.removeModalOpen()
|
|
34
|
+
this.dispatchClose()
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
openModal() {
|
|
38
|
+
this.modalTarget.removeAttribute('hidden')
|
|
39
|
+
this.addModalOpen()
|
|
40
|
+
this.modalTarget.focus()
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
toggleModal() {
|
|
44
|
+
if (this.isOpen()) {
|
|
45
|
+
this.closeModal()
|
|
46
|
+
} else {
|
|
47
|
+
this.openModal()
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -117,10 +117,6 @@ export default class extends Controller {
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
disconnect() {
|
|
120
|
-
if (this.isGlobalSearch) {
|
|
121
|
-
Mousetrap.unbind(['command+k', 'ctrl+k'])
|
|
122
|
-
}
|
|
123
|
-
|
|
124
120
|
// Don't leave open autocompletes around when disconnected. Otherwise it will still
|
|
125
121
|
// be visible when navigating back to this page.
|
|
126
122
|
if (this.destroyMethod) {
|
|
@@ -69,6 +69,20 @@ export default class extends Controller {
|
|
|
69
69
|
? this.mainAreaTarget.classList.contains('sidebar-mobile-open')
|
|
70
70
|
: this.mainAreaTarget.classList.contains('sidebar-open')
|
|
71
71
|
this.setToggleButtonsState(isOpen ? 'open' : 'closed')
|
|
72
|
+
|
|
73
|
+
this.handleToggleShortcut = (event) => {
|
|
74
|
+
if (event.repeat || event.defaultPrevented) return
|
|
75
|
+
if (event.target?.closest('input, textarea, select, [contenteditable]')) return
|
|
76
|
+
if (!(event.metaKey || event.ctrlKey) || event.altKey || event.key !== '\\') return
|
|
77
|
+
|
|
78
|
+
event.preventDefault()
|
|
79
|
+
this.toggleSidebarForViewport()
|
|
80
|
+
}
|
|
81
|
+
document.addEventListener('keydown', this.handleToggleShortcut)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
disconnect() {
|
|
85
|
+
document.removeEventListener('keydown', this.handleToggleShortcut)
|
|
72
86
|
}
|
|
73
87
|
|
|
74
88
|
rememberScrollPosition() {
|
|
@@ -96,6 +110,14 @@ export default class extends Controller {
|
|
|
96
110
|
})
|
|
97
111
|
}
|
|
98
112
|
|
|
113
|
+
toggleSidebarForViewport() {
|
|
114
|
+
if (window.innerWidth < 1024) {
|
|
115
|
+
this.toggleSidebarOnMobile()
|
|
116
|
+
} else {
|
|
117
|
+
this.toggleSidebar()
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
99
121
|
toggleSidebar() {
|
|
100
122
|
if (this.sidebarTarget.classList.contains('hidden')) {
|
|
101
123
|
this.sidebarTarget.classList.remove('hidden')
|
|
@@ -10,6 +10,7 @@ import CardFiltersController from './controllers/card_filters_controller'
|
|
|
10
10
|
import ClearInputController from './controllers/fields/clear_input_controller'
|
|
11
11
|
import CodeFieldController from './controllers/fields/code_field_controller'
|
|
12
12
|
import ColorSchemeSwitcherController from './controllers/color_scheme_switcher_controller'
|
|
13
|
+
import ConfirmDialogController from './controllers/confirm_dialog_controller'
|
|
13
14
|
import CopyToClipboardController from './controllers/copy_to_clipboard_controller'
|
|
14
15
|
import DashboardCardController from './controllers/dashboard_card_controller'
|
|
15
16
|
import DateFieldController from './controllers/fields/date_field_controller'
|
|
@@ -35,6 +36,7 @@ import MultipleSelectFilterController from './controllers/multiple_select_filter
|
|
|
35
36
|
import NestedFormController from './controllers/nested_form_controller'
|
|
36
37
|
import PanelRefreshController from './controllers/fields/panel_refresh_controller'
|
|
37
38
|
import PerPageController from './controllers/per_page_controller'
|
|
39
|
+
import PersistentModalController from './controllers/persistent_modal_controller'
|
|
38
40
|
import PreviewController from './controllers/preview_controller'
|
|
39
41
|
import ProgressBarFieldController from './controllers/fields/progress_bar_field_controller'
|
|
40
42
|
import RecordSelectorController from './controllers/record_selector_controller'
|
|
@@ -61,6 +63,7 @@ import TrixBodyController from './controllers/trix_body_controller'
|
|
|
61
63
|
import TrixFieldController from './controllers/fields/trix_field_controller'
|
|
62
64
|
|
|
63
65
|
application.register('action', ActionController)
|
|
66
|
+
application.register('confirm-dialog', ConfirmDialogController)
|
|
64
67
|
application.register('actions-overflow', ActionsOverflowController)
|
|
65
68
|
application.register('actions-picker', ActionsPickerController)
|
|
66
69
|
application.register('attachments', AttachmentsController)
|
|
@@ -85,6 +88,7 @@ application.register('media-library', MediaLibraryController)
|
|
|
85
88
|
application.register('menu', MenuController)
|
|
86
89
|
application.register('modal', ModalController)
|
|
87
90
|
application.register('modal-size', ModalSizeController)
|
|
91
|
+
application.register('persistent-modal', PersistentModalController)
|
|
88
92
|
application.register('multiple-select-filter', MultipleSelectFilterController)
|
|
89
93
|
application.register('avo-nested-form', NestedFormController)
|
|
90
94
|
application.register('panel-refresh', PanelRefreshController)
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Global (non-element) keyboard shortcuts.
|
|
3
|
+
* Add new entries to HOTKEYS to register more.
|
|
4
|
+
*
|
|
5
|
+
* Two registries:
|
|
6
|
+
* - ELEMENT_HOTKEYS: handled via @github/hotkey (supports sequences like "r r r")
|
|
7
|
+
* - DIRECT_HOTKEYS: custom keydown listeners for keys needing cross-browser normalization
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { install } from '@github/hotkey'
|
|
11
|
+
|
|
12
|
+
// Use @github/hotkey for sequences and standard combos.
|
|
13
|
+
const ELEMENT_HOTKEYS = [
|
|
14
|
+
{
|
|
15
|
+
hotkey: 'r r r',
|
|
16
|
+
handle: () => {
|
|
17
|
+
window.reloadScrollTop = document.querySelector('.scrollable-wrapper')?.scrollTop
|
|
18
|
+
window.StreamActions.turbo_reload()
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
// Use direct listeners for keys where event.key varies across browsers/layouts.
|
|
24
|
+
const DIRECT_HOTKEYS = [
|
|
25
|
+
{
|
|
26
|
+
// Shift+/ → "?" on US layouts, but some browsers expose key:"Slash"+shiftKey instead.
|
|
27
|
+
match: (e) => e.key === '?' || (e.shiftKey && e.code === 'Slash'),
|
|
28
|
+
handle: () => document.dispatchEvent(new Event('persistent-modal:toggle')),
|
|
29
|
+
},
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
const TYPING_SELECTOR = 'input, textarea, select, [contenteditable]'
|
|
33
|
+
|
|
34
|
+
export function installGlobalHotkeys() {
|
|
35
|
+
// When a hotkey fires on a DOM element that contains a <kbd>, mark it cold
|
|
36
|
+
// before letting the click proceed. preventDefault + requestAnimationFrame
|
|
37
|
+
// gives the browser one frame to paint the cold state before navigation starts.
|
|
38
|
+
document.addEventListener('hotkey-fire', (event) => {
|
|
39
|
+
const kbd = event.target.querySelector('kbd')
|
|
40
|
+
if (!kbd) return
|
|
41
|
+
|
|
42
|
+
event.preventDefault()
|
|
43
|
+
kbd.classList.add('kbd--called')
|
|
44
|
+
requestAnimationFrame(() => event.target.click())
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
document.addEventListener('turbo:load', () => {
|
|
48
|
+
document.querySelectorAll('kbd.kbd--called').forEach((kbd) => kbd.classList.remove('kbd--called'))
|
|
49
|
+
|
|
50
|
+
if (window.reloadScrollTop) {
|
|
51
|
+
setTimeout(() => {
|
|
52
|
+
document.querySelector('.scrollable-wrapper')?.scrollTo(0, window.reloadScrollTop)
|
|
53
|
+
window.reloadScrollTop = null
|
|
54
|
+
}, 50)
|
|
55
|
+
}
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
ELEMENT_HOTKEYS.forEach(({ hotkey, handle }) => {
|
|
59
|
+
const el = document.createElement('span')
|
|
60
|
+
el.addEventListener('hotkey-fire', (event) => {
|
|
61
|
+
event.preventDefault()
|
|
62
|
+
handle()
|
|
63
|
+
})
|
|
64
|
+
install(el, hotkey)
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
document.addEventListener('keydown', (event) => {
|
|
68
|
+
if (event.defaultPrevented || event.repeat) return
|
|
69
|
+
if (event.target instanceof Element && event.target.closest(TYPING_SELECTOR)) return
|
|
70
|
+
|
|
71
|
+
const entry = DIRECT_HOTKEYS.find(({ match }) => match(event))
|
|
72
|
+
if (entry) {
|
|
73
|
+
event.preventDefault()
|
|
74
|
+
entry.handle()
|
|
75
|
+
}
|
|
76
|
+
})
|
|
77
|
+
}
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
<% c.with_heading do %>
|
|
26
26
|
<%= @action.action_name %>
|
|
27
27
|
<% if Rails.env.development? %>
|
|
28
|
-
<%= link_to editor_file_path(@action), target: "_blank", class: "inline-block align-middle ms-1", title: "Open action in your editor", data: { tippy: "tooltip" } do %>
|
|
28
|
+
<%= link_to editor_file_path(@action), target: "_blank", class: "inline-block align-middle ms-1", title: "Open action in your editor", data: { tippy: "tooltip" }, tabindex: "-1" do %>
|
|
29
29
|
<%= svg "tabler/outline/code", class: "size-4 text-content-secondary cursor-pointer" %>
|
|
30
30
|
<% end %>
|
|
31
31
|
<% end %>
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
<div class="shadow-lg rounded px-4 py-3 relative border text-white pointer-events-auto bg-blue-400 border-blue-600 m-2">
|
|
28
28
|
<div class="flex px-2">
|
|
29
29
|
<div class="shrink-0">
|
|
30
|
-
<%= svg "
|
|
30
|
+
<%= svg "tabler/filled/alert-circle", class: "h-6" %>
|
|
31
31
|
</div>
|
|
32
32
|
<div class="ms-3 flex-1 pt-0.5">
|
|
33
33
|
<p class="text-sm leading-5 font-semibold"><%= t "avo.not_authorized" %></p>
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<% if valid %>
|
|
2
2
|
<span class="text-green-700 text-xl">
|
|
3
|
-
<%= svg "
|
|
3
|
+
<%= svg "tabler/outline/rosette-discount-check", class: "h-5 inline -mt-1 relative" %> <span>Valid</span>
|
|
4
4
|
</span>
|
|
5
5
|
<% else %>
|
|
6
6
|
<span class="text-orange-700 text-xl">
|
|
7
|
-
<%= svg "
|
|
7
|
+
<%= svg "tabler/outline/exclamation-circle", class: "h-5 inline -mt-1 relative" %> <span>Invalid</span>
|
|
8
8
|
</span>
|
|
9
9
|
<% end %>
|
|
@@ -1,18 +1,45 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
<%
|
|
2
|
+
src_url = params[:src].present? && !params[:src].starts_with?("http://") ? CGI.escapeHTML(params[:src]) : nil
|
|
3
|
+
frame_label = if params[:turbo_frame].present?
|
|
4
|
+
params[:turbo_frame].to_s.humanize.downcase
|
|
5
|
+
else
|
|
6
|
+
"this frame"
|
|
7
|
+
end
|
|
6
8
|
%>
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
|
|
10
|
+
<%= render Avo::TurboFrameWrapperComponent.new(params[:turbo_frame]) do %>
|
|
11
|
+
<div class="state state--frame-load-failed">
|
|
12
|
+
<div class="state__illustration" aria-hidden="true">
|
|
13
|
+
<% %i[start center end].each do |position| %>
|
|
14
|
+
<div class="state__document state__document--<%= position %>">
|
|
15
|
+
<div class="state__document-body">
|
|
16
|
+
<div class="state__document-lines">
|
|
17
|
+
<span class="state__document-line"></span>
|
|
18
|
+
<span class="state__document-line"></span>
|
|
19
|
+
<span class="state__document-line"></span>
|
|
20
|
+
<span class="state__document-line"></span>
|
|
21
|
+
<span class="state__document-line state__document-line--short"></span>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
<% end %>
|
|
26
|
+
|
|
27
|
+
<div class="state__magnifier">
|
|
28
|
+
<%= svg "tabler/outline/zoom", class: "state__magnifier-icon" %>
|
|
15
29
|
</div>
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
<p class="state__message text-center font-normal">
|
|
33
|
+
Failed to load:
|
|
34
|
+
<span class="font-bold"><%= frame_label %></span>
|
|
35
|
+
</p>
|
|
36
|
+
|
|
37
|
+
<% if Rails.env.development? && src_url.present? %>
|
|
38
|
+
<p class="state__note text-center font-normal">
|
|
39
|
+
Follow
|
|
40
|
+
<%= link_to "this link", src_url, target: "_blank", rel: "noopener", class: "state__link font-normal" %>
|
|
41
|
+
for more details about the issue and how to fix it.
|
|
42
|
+
</p>
|
|
16
43
|
<% end %>
|
|
17
44
|
</div>
|
|
18
45
|
<% end %>
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
data-action="click->toggle#togglePanel"
|
|
38
38
|
class="color-scheme-switcher__button color-scheme-switcher__button--accent"
|
|
39
39
|
title="Accent color">
|
|
40
|
-
<%= svg "
|
|
40
|
+
<%= svg "tabler/outline/color-swatch", class: "color-scheme-switcher__icon" %>
|
|
41
41
|
<span class="color-scheme-switcher__accent-badge">
|
|
42
42
|
<span class="color-scheme-switcher__accent-badge-preview color-scheme-switcher__accent-badge-preview--neutral"></span>
|
|
43
43
|
<% accent_colors.each do |accent| %>
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
data-scheme="auto"
|
|
83
83
|
class="color-scheme-switcher__button"
|
|
84
84
|
title="Auto (system preference)">
|
|
85
|
-
<%= svg "
|
|
85
|
+
<%= svg "tabler/outline/device-desktop", class: "color-scheme-switcher__icon" %>
|
|
86
86
|
<span class="sr-only">Auto</span>
|
|
87
87
|
</button>
|
|
88
88
|
<button type="button"
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
data-scheme="light"
|
|
92
92
|
class="color-scheme-switcher__button"
|
|
93
93
|
title="Light mode">
|
|
94
|
-
<%= svg "
|
|
94
|
+
<%= svg "tabler/outline/sun", class: "color-scheme-switcher__icon" %>
|
|
95
95
|
<span class="sr-only">Light</span>
|
|
96
96
|
</button>
|
|
97
97
|
<button type="button"
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
data-scheme="dark"
|
|
101
101
|
class="color-scheme-switcher__button"
|
|
102
102
|
title="Dark mode">
|
|
103
|
-
<%= svg "
|
|
103
|
+
<%= svg "tabler/outline/moon", class: "color-scheme-switcher__icon" %>
|
|
104
104
|
<span class="sr-only">Dark</span>
|
|
105
105
|
</button>
|
|
106
106
|
</div>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<dialog id="turbo-confirm" class="mx-auto my-auto w-72">
|
|
1
|
+
<dialog id="turbo-confirm" class="mx-auto my-auto w-72" data-controller="confirm-dialog" data-action="keydown->confirm-dialog#navigate">
|
|
2
2
|
<form method="dialog">
|
|
3
3
|
<div class="card relative">
|
|
4
4
|
<button value="cancel" class="absolute top-3 inset-e-2.5 text-content-secondary bg-transparent hover:bg-tertiary hover:text-content rounded-lg text-sm size-8 ms-auto inline-flex justify-center items-center" data-modal-hide="popup-modal" tabindex="3">
|
|
@@ -16,10 +16,10 @@
|
|
|
16
16
|
</p>
|
|
17
17
|
</div>
|
|
18
18
|
<div class="flex flex-col gap-2 w-full p-4 pt-0 mt-6">
|
|
19
|
-
<button value="confirm" class="text-danger border border-danger hover:bg-danger/10 focus:ring-4 focus:outline-hidden focus:ring-danger/30 font-medium rounded-lg text-sm px-4 py-2 text-center cursor-pointer" tabindex="1" autofocus>
|
|
19
|
+
<button value="confirm" class="text-danger border border-danger hover:bg-danger/10 focus:ring-4 focus:outline-hidden focus:ring-danger/30 font-medium rounded-lg text-sm px-4 py-2 text-center cursor-pointer" tabindex="1" autofocus data-confirm-dialog-target="option">
|
|
20
20
|
<%= t "avo.yes_confirm" %>
|
|
21
21
|
</button>
|
|
22
|
-
<button value="cancel" class="px-4 py-2 text-sm font-medium text-content focus:outline-hidden bg-primary rounded-lg border border-tertiary hover:bg-secondary hover:text-content focus:z-10 focus:ring-4 focus:ring-tertiary cursor-pointer" tabindex="2">
|
|
22
|
+
<button value="cancel" class="px-4 py-2 text-sm font-medium text-content focus:outline-hidden bg-primary rounded-lg border border-tertiary hover:bg-secondary hover:text-content focus:z-10 focus:ring-4 focus:ring-tertiary cursor-pointer" tabindex="2" data-confirm-dialog-target="option">
|
|
23
23
|
<%= t "avo.no_cancel" %>
|
|
24
24
|
</button>
|
|
25
25
|
</div>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<% if @custom_tools_alert_visible %>
|
|
2
2
|
<div class="w-full inset-auto bottom-0 z-50 mb-4 opacity-75 hover:opacity-100 transition-opacity duration-150">
|
|
3
3
|
<a href="https://avohq.io/pricing" target="_blank" class="rounded-sm bg-orange-700 text-white py-2 px-4 text-sm block items-center flex leading-tight">
|
|
4
|
-
<%= svg "
|
|
4
|
+
<%= svg "tabler/outline/alert-triangle", class: "h-6 inline me-2 text-bold shrink-0 me-1" %> Warning. <%= @custom_tools_alert_visible %> This page will not be visible in a production environment.
|
|
5
5
|
</a>
|
|
6
6
|
</div>
|
|
7
7
|
<% end %>
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
%>
|
|
14
14
|
<div class="w-full inset-auto bottom-0 z-50 mb-4 opacity-75 hover:opacity-100 transition-opacity duration-150">
|
|
15
15
|
<a href="<%= url %>" target="<%= target %>" class="rounded-sm bg-orange-700 text-white py-2 px-4 text-sm items-center flex leading-tight space-x-2 rtl:space-x-reverse">
|
|
16
|
-
<%= svg "
|
|
16
|
+
<%= svg "tabler/outline/alert-triangle", class: "h-6 inline me-2 text-bold shrink-0 me-1" %>
|
|
17
17
|
<div>
|
|
18
18
|
<%= simple_format message %>
|
|
19
19
|
</div>
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
<% elsif error.is_a? String %>
|
|
23
23
|
<div class="w-full inset-auto bottom-0 z-50 mb-4 opacity-75 hover:opacity-100 transition-opacity duration-150">
|
|
24
24
|
<div class="rounded-sm bg-orange-700 text-white py-2 px-4 text-sm items-center flex leading-tight space-x-2 rtl:space-x-reverse">
|
|
25
|
-
<%= svg "
|
|
25
|
+
<%= svg "tabler/outline/alert-triangle", class: "h-6 inline me-2 text-bold shrink-0 me-1" %>
|
|
26
26
|
<div><%= simple_format error %></div>
|
|
27
27
|
</div>
|
|
28
28
|
</div>
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<%
|
|
2
|
-
icon = "
|
|
2
|
+
icon = "tabler/outline/selector"
|
|
3
3
|
|
|
4
4
|
if params[:sort_by] == field.id.to_s
|
|
5
5
|
case params[:sort_direction]
|
|
6
6
|
when 'asc'
|
|
7
|
-
icon = "
|
|
7
|
+
icon = "tabler/outline/sort-ascending"
|
|
8
8
|
when 'desc'
|
|
9
|
-
icon = "
|
|
9
|
+
icon = "tabler/outline/sort-descending"
|
|
10
10
|
end
|
|
11
11
|
end
|
|
12
12
|
%>
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
class="cursor-pointer <%= text_classes %>"
|
|
88
88
|
data-action="click->toggle#togglePanel"
|
|
89
89
|
>
|
|
90
|
-
<%= svg '
|
|
90
|
+
<%= svg 'tabler/filled/chart-pie-4', class: 'h-3 ms-1' %>
|
|
91
91
|
</div>
|
|
92
92
|
<turbo-frame
|
|
93
93
|
id="summary-frame-<%= field.id %>"
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
%>
|
|
29
29
|
<%
|
|
30
30
|
a_button_or_link = "a_#{entity}"
|
|
31
|
-
args = {icon: "
|
|
31
|
+
args = {icon: "tabler/outline/arrow-left", style: style, color: color, size: size, class: extra_classes, disabled: state == :disabled}
|
|
32
32
|
%>
|
|
33
33
|
<% if entity == :link %>
|
|
34
34
|
<div>
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
<% end %>
|
|
44
44
|
</div>
|
|
45
45
|
<div>
|
|
46
|
-
<%= a_button icon: "
|
|
46
|
+
<%= a_button icon: "tabler/outline/bell", style: style, color: color, size: size, class: extra_classes, disabled: state == :disabled %>
|
|
47
47
|
</div>
|
|
48
48
|
<% end %>
|
|
49
49
|
<% end %>
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
<div class="flex flex-col">
|
|
2
2
|
<%= render ui.panel(title: 'Welcome to Avo', description: 'This page is visible only in development. It will be hidden in other environments.') do |panel| %>
|
|
3
3
|
<% panel.with_controls do %>
|
|
4
|
-
<%= a_link('/admin', icon: "
|
|
4
|
+
<%= a_link('/admin', icon: "tabler/outline/arrow-left", color: :green, style: :primary, is_link: true) do %>
|
|
5
5
|
Primary
|
|
6
6
|
<% end %>
|
|
7
7
|
|
|
8
|
-
<%= a_link('/admin', icon: "
|
|
8
|
+
<%= a_link('/admin', icon: "tabler/outline/arrow-left", style: :outline, is_link: true) do %>
|
|
9
9
|
Outline
|
|
10
10
|
<% end %>
|
|
11
11
|
|
|
12
|
-
<%= a_link('/admin', icon: "
|
|
12
|
+
<%= a_link('/admin', icon: "tabler/outline/arrow-left", style: :outline, color: :red, is_link: true) do %>
|
|
13
13
|
Red
|
|
14
14
|
<% end %>
|
|
15
15
|
|
|
16
|
-
<%= a_link('/admin', icon: "
|
|
16
|
+
<%= a_link('/admin', icon: "tabler/outline/arrow-left", style: :text, color: :orange, is_link: true) do %>
|
|
17
17
|
Text
|
|
18
18
|
<% end %>
|
|
19
19
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<div class="w-10/12 ms-1/12 inset-auto bottom-0 z-50 my-4 opacity-50 hover:opacity-100 transition-opacity duration-150 group">
|
|
2
2
|
<a href="https://avohq.io/pricing" target="_blank" class="rounded-sm bg-green-700 text-white py-2 px-4 text-sm block group-hover:pt-4">
|
|
3
|
-
<%= svg "
|
|
3
|
+
<%= svg "tabler/outline/alert-triangle", class: 'h-6 inline me-1 text-bold' %> <%= title %>
|
|
4
4
|
<div class="group-hover:block hidden py-2">
|
|
5
|
-
<%= message %> <%= svg "
|
|
5
|
+
<%= message %> <%= svg "tabler/outline/circle-arrow-right", class: "h-6 inline float-right" %>
|
|
6
6
|
</div>
|
|
7
7
|
</a>
|
|
8
8
|
</div>
|