@nixweb/nixloc-ui 1.0.0 → 1.2.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.
- package/package.json +1 -1
- package/src/component/forms/ButtonFilter.vue +1 -0
- package/src/component/forms/InputTextEdit.vue +1 -1
- package/src/component/forms/Modal.vue +5 -1
- package/src/component/layout/BottomActionsBar.vue +193 -0
- package/src/component/layout/ColorPicker.vue +175 -0
- package/src/component/layout/IconPicker.vue +161 -0
- package/src/component/layout/Tab.vue +144 -29
- package/src/component/shared/Pagination.vue +6 -1
- package/src/component/shared/Table.vue +61 -3
- package/src/component/shared/TableItem.vue +2 -1
- package/src/component/shared/TableTotalPerPage.vue +84 -48
- package/src/component/shared/TableTotalization.vue +11 -11
- package/src/component/shared/actions/ActionButtons.vue +29 -0
- package/src/component/shared/actions/ActionErrorContent.vue +103 -0
- package/src/component/shared/actions/ActionFooter.vue +55 -0
- package/src/component/shared/actions/ActionHeader.vue +110 -0
- package/src/component/shared/actions/ActionItemList.vue +121 -0
- package/src/component/shared/actions/ActionsOptions.vue +159 -0
- package/src/component/shared/actions/ActionsSelected.vue +213 -0
- package/src/component/template/ListViewWithDataHandler.vue +21 -17
- package/src/component/template/ViewTemplateConfiguration.vue +6 -2
- package/src/component/template/ViewTemplateWithTable.vue +5 -1
- package/src/store/modules/generic.js +12 -4
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<div class="error-details-header">
|
|
4
|
+
<i class="fas fa-triangle-exclamation"></i>
|
|
5
|
+
<div>
|
|
6
|
+
<div class="error-details-title title">O que deu errado?</div>
|
|
7
|
+
<!-- <div class="error-details-sub">ID: {{ id }}</div> -->
|
|
8
|
+
</div>
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
<ScrollBar :minHeight="190" :maxHeight="190">
|
|
12
|
+
<ul class="error-list">
|
|
13
|
+
<li v-for="(msg, i) in safeMessages" :key="i" class="error-item">
|
|
14
|
+
<i class="fas fa-info-circle"></i>
|
|
15
|
+
<span>{{ msg }}</span>
|
|
16
|
+
</li>
|
|
17
|
+
|
|
18
|
+
<li v-if="safeMessages.length === 0" class="error-item muted">
|
|
19
|
+
<i class="fas fa-info-circle"></i>
|
|
20
|
+
<span>Algo deu errado, mas não recebemos detalhes do servidor.</span>
|
|
21
|
+
</li>
|
|
22
|
+
</ul>
|
|
23
|
+
</ScrollBar>
|
|
24
|
+
|
|
25
|
+
<div class="text-center">
|
|
26
|
+
<Button key="closeErrors" title="Fechar" color="white" backGroundColor="#6B7280" size="small"
|
|
27
|
+
:clicked="() => $emit('close')" />
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
</template>
|
|
31
|
+
|
|
32
|
+
<script>
|
|
33
|
+
import ScrollBar from "@nixweb/nixloc-ui/src/component/layout/ScrollBar.vue";
|
|
34
|
+
import Button from "@nixweb/nixloc-ui/src/component/forms/Button";
|
|
35
|
+
|
|
36
|
+
export default {
|
|
37
|
+
name: "ActionErrorContent",
|
|
38
|
+
components: { ScrollBar, Button },
|
|
39
|
+
props: {
|
|
40
|
+
id: { type: [String, Number], required: true },
|
|
41
|
+
index: { type: Number, default: -1 },
|
|
42
|
+
messages: { type: Array, default: () => [] },
|
|
43
|
+
},
|
|
44
|
+
computed: {
|
|
45
|
+
safeMessages() {
|
|
46
|
+
return (this.messages || []).filter(Boolean);
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
</script>
|
|
51
|
+
|
|
52
|
+
<style scoped>
|
|
53
|
+
.error-details-header {
|
|
54
|
+
display: flex;
|
|
55
|
+
gap: 10px;
|
|
56
|
+
align-items: center;
|
|
57
|
+
margin-bottom: 12px;
|
|
58
|
+
color: #dc2626;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.error-details-header i {
|
|
62
|
+
font-size: 18px;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.error-details-title {
|
|
66
|
+
font-weight: 600;
|
|
67
|
+
color: #111827;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.error-details-sub {
|
|
71
|
+
font-size: 12px;
|
|
72
|
+
color: #6b7280;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.error-list {
|
|
76
|
+
list-style: none;
|
|
77
|
+
margin: 0;
|
|
78
|
+
padding: 0;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.error-item {
|
|
82
|
+
display: flex;
|
|
83
|
+
gap: 8px;
|
|
84
|
+
align-items: flex-start;
|
|
85
|
+
padding: 8px 10px;
|
|
86
|
+
background: #fff7f7;
|
|
87
|
+
border: 1px solid #fde2e2;
|
|
88
|
+
border-radius: 8px;
|
|
89
|
+
margin-bottom: 8px;
|
|
90
|
+
font-size: 13px;
|
|
91
|
+
color: #dc2626;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.error-item i {
|
|
95
|
+
margin-top: 2px;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.error-item.muted {
|
|
99
|
+
background: #f9fafb;
|
|
100
|
+
border-color: #e5e7eb;
|
|
101
|
+
color: #6b7280;
|
|
102
|
+
}
|
|
103
|
+
</style>
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<div v-if="!isFinished" class="actions">
|
|
4
|
+
<div class="side-by-side">
|
|
5
|
+
<Button key="cancel" title="Cancelar" type="danger" size="small"
|
|
6
|
+
:disabled="processing || selected.length === 0" :clicked="hideModal" />
|
|
7
|
+
<Button key="ok" title="Processar" color="white" classIcon="fa-solid fa-play" backGroundColor="#007BFF" size="large"
|
|
8
|
+
:disabled="processing || selected.length === 0" :clicked="ok" />
|
|
9
|
+
</div>
|
|
10
|
+
</div>
|
|
11
|
+
|
|
12
|
+
<div v-else class="text-center">
|
|
13
|
+
<Button key="finish" title="Fechar" classIcon="fa-solid fa-xmark" color="white" backGroundColor="#6D757B" size="medium"
|
|
14
|
+
:clicked="finished" />
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
17
|
+
</template>
|
|
18
|
+
|
|
19
|
+
<script>
|
|
20
|
+
import Button from "@nixweb/nixloc-ui/src/component/forms/Button";
|
|
21
|
+
|
|
22
|
+
export default {
|
|
23
|
+
name: "ActionFooter",
|
|
24
|
+
components: { Button },
|
|
25
|
+
props: {
|
|
26
|
+
isFinished: { type: Boolean, default: false },
|
|
27
|
+
processing: { type: Boolean, default: false },
|
|
28
|
+
selected: { type: Array, default: () => [] },
|
|
29
|
+
},
|
|
30
|
+
emits: ["ok", "cancel", "finish"],
|
|
31
|
+
methods: {
|
|
32
|
+
ok() {
|
|
33
|
+
this.$emit("ok");
|
|
34
|
+
},
|
|
35
|
+
hideModal() {
|
|
36
|
+
this.$emit("cancel");
|
|
37
|
+
},
|
|
38
|
+
finished() {
|
|
39
|
+
this.$emit("finish");
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
</script>
|
|
44
|
+
|
|
45
|
+
<style scoped>
|
|
46
|
+
.actions {
|
|
47
|
+
text-align: center;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.side-by-side {
|
|
51
|
+
display: inline-flex;
|
|
52
|
+
align-items: center;
|
|
53
|
+
gap: 8px;
|
|
54
|
+
}
|
|
55
|
+
</style>
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<div class="action-banner">
|
|
4
|
+
<span class="action-accent"></span>
|
|
5
|
+
<span class="action-label">Ação</span>
|
|
6
|
+
<strong class="action-value title">{{ description }}</strong>
|
|
7
|
+
</div>
|
|
8
|
+
|
|
9
|
+
<div class="status-header">
|
|
10
|
+
<div class="status-chip">
|
|
11
|
+
<i class="fas fa-list"></i>
|
|
12
|
+
<span>Total {{ total }}</span>
|
|
13
|
+
</div>
|
|
14
|
+
<div class="status-chip success">
|
|
15
|
+
<i class="fas fa-check-circle"></i>
|
|
16
|
+
<span>Concluídos {{ done }}</span>
|
|
17
|
+
</div>
|
|
18
|
+
<div class="status-chip error-chip">
|
|
19
|
+
<i class="fas fa-times-circle"></i>
|
|
20
|
+
<span>Falhas {{ errors }}</span>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
</template>
|
|
25
|
+
|
|
26
|
+
<script>
|
|
27
|
+
export default {
|
|
28
|
+
name: "ActionModalHeader",
|
|
29
|
+
props: {
|
|
30
|
+
description: { type: String, default: "" },
|
|
31
|
+
total: { type: Number, default: 0 },
|
|
32
|
+
done: { type: Number, default: 0 },
|
|
33
|
+
errors: { type: Number, default: 0 },
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
</script>
|
|
37
|
+
|
|
38
|
+
<style scoped>
|
|
39
|
+
.status-header {
|
|
40
|
+
display: flex;
|
|
41
|
+
align-items: center;
|
|
42
|
+
gap: 10px;
|
|
43
|
+
flex-wrap: wrap;
|
|
44
|
+
margin-bottom: 10px;
|
|
45
|
+
padding: 8px 0;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.status-chip {
|
|
49
|
+
display: flex;
|
|
50
|
+
align-items: center;
|
|
51
|
+
gap: 6px;
|
|
52
|
+
background: #f3f4f6;
|
|
53
|
+
border: 1px solid #e5e7eb;
|
|
54
|
+
border-radius: 20px;
|
|
55
|
+
padding: 6px 10px;
|
|
56
|
+
font-size: 13px;
|
|
57
|
+
color: #374151;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.status-chip.success {
|
|
61
|
+
background: #ecfdf5;
|
|
62
|
+
border-color: #a7f3d0;
|
|
63
|
+
color: #065f46;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.status-chip.success i {
|
|
67
|
+
color: #16a34a;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.status-chip.error-chip {
|
|
71
|
+
background: #fef2f2;
|
|
72
|
+
border-color: #fecaca;
|
|
73
|
+
color: #b91c1c;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.status-chip.error-chip i {
|
|
77
|
+
color: #dc2626;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.action-banner {
|
|
81
|
+
display: flex;
|
|
82
|
+
align-items: center;
|
|
83
|
+
gap: 10px;
|
|
84
|
+
padding: 10px 12px;
|
|
85
|
+
margin-bottom: 12px;
|
|
86
|
+
background: #f8fafc;
|
|
87
|
+
border: 1px solid #e5e7eb;
|
|
88
|
+
border-radius: 12px;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.action-accent {
|
|
92
|
+
width: 4px;
|
|
93
|
+
align-self: stretch;
|
|
94
|
+
background: #3b82f6;
|
|
95
|
+
border-radius: 8px;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.action-label {
|
|
99
|
+
font-size: 12px;
|
|
100
|
+
text-transform: uppercase;
|
|
101
|
+
letter-spacing: 0.06em;
|
|
102
|
+
color: #64748b;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.action-value {
|
|
106
|
+
font-size: 14px;
|
|
107
|
+
color: #0f172a;
|
|
108
|
+
font-weight: 700;
|
|
109
|
+
}
|
|
110
|
+
</style>
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<ScrollBar :minHeight="300" :maxHeight="300">
|
|
3
|
+
<div v-for="(id, index) in selected" :key="id" class="item-row">
|
|
4
|
+
<div class="item-left title">Item {{ index + 1 }}</div>
|
|
5
|
+
<div class="item-right">
|
|
6
|
+
<span v-if="status[id] === 'waiting'" class="waiting">
|
|
7
|
+
<i class="fas fa-hourglass-half"></i>
|
|
8
|
+
</span>
|
|
9
|
+
|
|
10
|
+
<span v-else-if="status[id] === 'running'" class="loading">
|
|
11
|
+
<span class="spinner"></span> Processando...
|
|
12
|
+
</span>
|
|
13
|
+
|
|
14
|
+
<span v-else-if="status[id] === 'done'" class="done">
|
|
15
|
+
<i class="fas fa-check-circle done-icon"></i> Sucesso!
|
|
16
|
+
</span>
|
|
17
|
+
|
|
18
|
+
<span v-else-if="status[id] === 'error'" class="error">
|
|
19
|
+
<i class="fas fa-times-circle"></i> Falhou!
|
|
20
|
+
<button class="error-link" @click="$emit('show-error', { id, index })"><span class="title">Ver
|
|
21
|
+
detalhes</span></button>
|
|
22
|
+
</span>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
</ScrollBar>
|
|
26
|
+
</template>
|
|
27
|
+
|
|
28
|
+
<script>
|
|
29
|
+
import ScrollBar from "@nixweb/nixloc-ui/src/component/layout/ScrollBar.vue";
|
|
30
|
+
|
|
31
|
+
export default {
|
|
32
|
+
name: "ActionItemList",
|
|
33
|
+
components: { ScrollBar },
|
|
34
|
+
props: { selected: Array, status: Object, errorsMap: Object },
|
|
35
|
+
};
|
|
36
|
+
</script>
|
|
37
|
+
|
|
38
|
+
<style scoped>
|
|
39
|
+
.item-row {
|
|
40
|
+
display: flex;
|
|
41
|
+
align-items: center;
|
|
42
|
+
justify-content: space-between;
|
|
43
|
+
padding: 8px 10px;
|
|
44
|
+
border: 1px solid #eee;
|
|
45
|
+
border-radius: 8px;
|
|
46
|
+
background: #fafafa;
|
|
47
|
+
margin: 6px 0;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.item-left {
|
|
51
|
+
font-weight: 500;
|
|
52
|
+
color: #334155;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.item-right {
|
|
56
|
+
display: flex;
|
|
57
|
+
align-items: center;
|
|
58
|
+
gap: 8px;
|
|
59
|
+
font-size: 13px;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.waiting {
|
|
63
|
+
color: #6b7280;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.loading {
|
|
67
|
+
color: #007BFF;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.done {
|
|
71
|
+
color: #16a34a;
|
|
72
|
+
font-weight: 500;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.done-icon {
|
|
76
|
+
color: #22c55e;
|
|
77
|
+
font-size: 14px;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.error {
|
|
81
|
+
color: #dc2626;
|
|
82
|
+
font-weight: 500;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.error-link {
|
|
86
|
+
margin-left: 10px;
|
|
87
|
+
background: transparent;
|
|
88
|
+
border: none;
|
|
89
|
+
padding: 0;
|
|
90
|
+
font-size: 13px;
|
|
91
|
+
text-decoration: underline;
|
|
92
|
+
cursor: pointer;
|
|
93
|
+
color: #1f2937;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.error-link:hover {
|
|
97
|
+
opacity: 0.9;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.spinner {
|
|
101
|
+
display: inline-block;
|
|
102
|
+
width: 14px;
|
|
103
|
+
height: 14px;
|
|
104
|
+
border: 2px solid #007bff;
|
|
105
|
+
border-top: 2px solid transparent;
|
|
106
|
+
border-radius: 50%;
|
|
107
|
+
animation: spin 0.8s linear infinite;
|
|
108
|
+
vertical-align: middle;
|
|
109
|
+
margin-right: 6px;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
@keyframes spin {
|
|
113
|
+
0% {
|
|
114
|
+
transform: rotate(0deg);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
100% {
|
|
118
|
+
transform: rotate(360deg);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
</style>
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="actions-options">
|
|
3
|
+
<div class="ao-body">
|
|
4
|
+
<ScrollBar :minHeight="minHeight" :maxHeight="maxHeight" class="ao-scroll">
|
|
5
|
+
<div v-if="actionSelected.type == 'options'" class="ao-radios" role="group"
|
|
6
|
+
:aria-labelledby="'ao-title'">
|
|
7
|
+
<RadioGroup :field="fieldName" :options="filteredOptions" v-model="optionSelected" />
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
<div v-else class="ao-empty" aria-live="polite">
|
|
11
|
+
<i class="fas fa-inbox"></i>
|
|
12
|
+
<span>Nenhuma opção encontrada.</span>
|
|
13
|
+
</div>
|
|
14
|
+
</ScrollBar>
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
<footer class="ao-footer">
|
|
18
|
+
<div class="ao-footer-left">
|
|
19
|
+
<span v-if="optionSelected" class="ao-helper title">
|
|
20
|
+
Selecionado: <strong>{{ labelSelected }}</strong>
|
|
21
|
+
</span>
|
|
22
|
+
</div>
|
|
23
|
+
<div class="ao-footer-right">
|
|
24
|
+
<Button key="select" :disabled="!isValid" :title="btnNextLabel" type="primary" size="medium"
|
|
25
|
+
:clicked="next" />
|
|
26
|
+
</div>
|
|
27
|
+
</footer>
|
|
28
|
+
</div>
|
|
29
|
+
</template>
|
|
30
|
+
|
|
31
|
+
<script>
|
|
32
|
+
import Button from "@nixweb/nixloc-ui/src/component/forms/Button";
|
|
33
|
+
import RadioGroup from "@nixweb/nixloc-ui/src/component/forms/RadioGroup";
|
|
34
|
+
import ScrollBar from "@nixweb/nixloc-ui/src/component/layout/ScrollBar.vue";
|
|
35
|
+
import { mapMutations } from "vuex";
|
|
36
|
+
|
|
37
|
+
export default {
|
|
38
|
+
name: "ActionsOptions",
|
|
39
|
+
components: { Button, RadioGroup, ScrollBar },
|
|
40
|
+
props: {
|
|
41
|
+
actionSelected: { type: Object, required: true },
|
|
42
|
+
minHeight: { type: Number, default: 120 },
|
|
43
|
+
maxHeight: { type: Number, default: 260 },
|
|
44
|
+
btnNextLabel: { type: String, default: "Avançar" },
|
|
45
|
+
fieldName: { type: String, default: "group" },
|
|
46
|
+
searchThreshold: { type: Number, default: 10 },
|
|
47
|
+
value: String
|
|
48
|
+
},
|
|
49
|
+
data() {
|
|
50
|
+
return {
|
|
51
|
+
optionSelected: null,
|
|
52
|
+
query: ""
|
|
53
|
+
};
|
|
54
|
+
},
|
|
55
|
+
computed: {
|
|
56
|
+
optionsRaw() {
|
|
57
|
+
const list = (this.actionSelected && Array.isArray(this.actionSelected.options))
|
|
58
|
+
? this.actionSelected.options
|
|
59
|
+
: [];
|
|
60
|
+
return list.map(o => ({ text: o.text, value: o.value }));
|
|
61
|
+
},
|
|
62
|
+
filteredOptions() {
|
|
63
|
+
const q = (this.query || "").toLowerCase();
|
|
64
|
+
if (!q) return this.optionsRaw;
|
|
65
|
+
return this.optionsRaw.filter(opt =>
|
|
66
|
+
String(opt.text).toLowerCase().includes(q) ||
|
|
67
|
+
String(opt.value).toLowerCase().includes(q)
|
|
68
|
+
);
|
|
69
|
+
},
|
|
70
|
+
isValid() {
|
|
71
|
+
return this.optionSelected !== null && this.optionSelected !== undefined && this.optionSelected !== "";
|
|
72
|
+
},
|
|
73
|
+
labelSelected() {
|
|
74
|
+
const found = this.optionsRaw.find(o => o.value === this.optionSelected);
|
|
75
|
+
return found ? found.text : "";
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
watch: {
|
|
79
|
+
optionSelected: {
|
|
80
|
+
handler(value) {
|
|
81
|
+
this.$emit("input", value);
|
|
82
|
+
},
|
|
83
|
+
deep: true,
|
|
84
|
+
},
|
|
85
|
+
optionsRaw: {
|
|
86
|
+
immediate: true,
|
|
87
|
+
handler(list) {
|
|
88
|
+
if (Array.isArray(list) && list.length === 1) {
|
|
89
|
+
this.optionSelected = list[0].value;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
methods: {
|
|
95
|
+
...mapMutations("generic", ["openModal", "hideModal"]),
|
|
96
|
+
next() {
|
|
97
|
+
if (!this.isValid) return;
|
|
98
|
+
this.openModal("confirm");
|
|
99
|
+
},
|
|
100
|
+
enterToNext() {
|
|
101
|
+
if (this.isValid) this.next();
|
|
102
|
+
},
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
</script>
|
|
106
|
+
|
|
107
|
+
<style scoped>
|
|
108
|
+
.actions-options {
|
|
109
|
+
display: flex;
|
|
110
|
+
flex-direction: column;
|
|
111
|
+
gap: 12px;
|
|
112
|
+
max-width: 640px;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.ao-body {
|
|
116
|
+
display: flex;
|
|
117
|
+
flex-direction: column;
|
|
118
|
+
gap: 8px;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.ao-scroll {
|
|
122
|
+
border: 1px solid #e5e7eb;
|
|
123
|
+
border-radius: 10px;
|
|
124
|
+
padding: 8px;
|
|
125
|
+
background: #fff;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.ao-radios {
|
|
129
|
+
display: grid;
|
|
130
|
+
gap: 10px;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.ao-empty {
|
|
134
|
+
display: flex;
|
|
135
|
+
align-items: center;
|
|
136
|
+
gap: 8px;
|
|
137
|
+
color: #6b7280;
|
|
138
|
+
padding: 8px;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.ao-footer {
|
|
142
|
+
display: flex;
|
|
143
|
+
align-items: center;
|
|
144
|
+
justify-content: space-between;
|
|
145
|
+
gap: 12px;
|
|
146
|
+
padding-top: 8px;
|
|
147
|
+
position: sticky;
|
|
148
|
+
bottom: 0;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.ao-footer-right {
|
|
152
|
+
display: flex;
|
|
153
|
+
gap: 8px;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.ao-helper {
|
|
157
|
+
color: #374151;
|
|
158
|
+
}
|
|
159
|
+
</style>
|