adminforth 2.25.1 → 2.26.0-next.10
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/commands/bundle.js +2 -1
- package/commands/createApp/templates/Dockerfile.hbs +12 -0
- package/commands/createApp/templates/package.json.hbs +18 -6
- package/commands/createApp/templates/pnpm_templates/pnpm-lock.yaml.hbs +8 -0
- package/commands/createApp/templates/pnpm_templates/pnpm-workspace.yaml.hbs +2 -0
- package/commands/createApp/templates/readme.md.hbs +23 -4
- package/commands/createApp/utils.js +107 -26
- package/commands/createPlugin/utils.js +5 -6
- package/commands/postinstall.js +1 -1
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js.map +1 -1
- package/dist/dataConnectors/clickhouse.d.ts +4 -0
- package/dist/dataConnectors/clickhouse.d.ts.map +1 -1
- package/dist/dataConnectors/clickhouse.js +14 -0
- package/dist/dataConnectors/clickhouse.js.map +1 -1
- package/dist/dataConnectors/mongo.d.ts +4 -0
- package/dist/dataConnectors/mongo.d.ts.map +1 -1
- package/dist/dataConnectors/mongo.js +9 -0
- package/dist/dataConnectors/mongo.js.map +1 -1
- package/dist/dataConnectors/mysql.d.ts +4 -0
- package/dist/dataConnectors/mysql.d.ts.map +1 -1
- package/dist/dataConnectors/mysql.js +11 -0
- package/dist/dataConnectors/mysql.js.map +1 -1
- package/dist/dataConnectors/postgres.d.ts +4 -0
- package/dist/dataConnectors/postgres.d.ts.map +1 -1
- package/dist/dataConnectors/postgres.js +11 -0
- package/dist/dataConnectors/postgres.js.map +1 -1
- package/dist/dataConnectors/sqlite.d.ts +4 -0
- package/dist/dataConnectors/sqlite.d.ts.map +1 -1
- package/dist/dataConnectors/sqlite.js +11 -0
- package/dist/dataConnectors/sqlite.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/modules/codeInjector.d.ts +11 -2
- package/dist/modules/codeInjector.d.ts.map +1 -1
- package/dist/modules/codeInjector.js +239 -82
- package/dist/modules/codeInjector.js.map +1 -1
- package/dist/modules/styles.d.ts +4 -0
- package/dist/modules/styles.d.ts.map +1 -1
- package/dist/modules/styles.js +4 -0
- package/dist/modules/styles.js.map +1 -1
- package/dist/modules/utils.d.ts.map +1 -1
- package/dist/servers/express.d.ts +0 -1
- package/dist/servers/express.d.ts.map +1 -1
- package/dist/spa/README.md +4 -4
- package/dist/spa/package-lock.json +1902 -1427
- package/dist/spa/package.json +4 -3
- package/dist/spa/pnpm-lock.yaml +3558 -0
- package/dist/spa/src/afcl/Button.vue +12 -5
- package/dist/spa/src/afcl/Dialog.vue +155 -126
- package/dist/spa/src/afcl/Modal.vue +31 -8
- package/dist/spa/src/afcl/Select.vue +6 -2
- package/dist/spa/src/components/AcceptModal.vue +31 -53
- package/dist/spa/src/components/MenuLink.vue +18 -4
- package/dist/spa/src/components/ResourceListTable.vue +11 -11
- package/dist/spa/src/components/ResourceListTableVirtual.vue +21 -26
- package/dist/spa/src/components/Sidebar.vue +1 -1
- package/dist/spa/src/components/ThreeDotsMenu.vue +1 -1
- package/dist/spa/src/components/ValueRenderer.vue +1 -1
- package/dist/spa/src/stores/core.ts +1 -2
- package/dist/spa/src/types/Back.ts +4 -3
- package/dist/spa/src/types/Common.ts +16 -0
- package/dist/spa/src/types/FrontendAPI.ts +0 -3
- package/dist/spa/src/utils/utils.ts +57 -2
- package/dist/spa/src/views/CreateView.vue +12 -11
- package/dist/spa/src/views/EditView.vue +9 -13
- package/dist/spa/vite.config.ts +29 -40
- package/dist/types/Back.d.ts +3 -4
- package/dist/types/Back.d.ts.map +1 -1
- package/dist/types/Back.js.map +1 -1
- package/dist/types/Common.d.ts +11 -0
- package/dist/types/Common.d.ts.map +1 -1
- package/dist/types/Common.js.map +1 -1
- package/package.json +14 -6
- package/scripts/postinstall.js +25 -0
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
focus:ring-4 focus:outline-none focus:ring-lightButtonFocusRing focus:ring-opacity-50 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:focus:ring-darkButtonFocusRing dark:text-darkButtonsText dark:border-darkButtonsBorder dark:hover:bg-darkButtonsHover dark:hover:border-darkButtonsBorderHover"
|
|
7
7
|
:class="{
|
|
8
8
|
'cursor-default opacity-50 pointer-events-none': props.disabled,
|
|
9
|
-
'active brightness-200 hover:brightness-150' : props.active
|
|
9
|
+
'active brightness-200 hover:brightness-150' : props.active,
|
|
10
|
+
'text-lightSecondaryContrast/70 bg-lightSecondary border-lightSecondaryContrast/30 dark:bg-darkSecondary hover:bg-lightSecondary/60 hover:border-lightSecondaryContrast/60 focus:ring-lightSecondary dark:focus:ring-darkSecondary/40 dark:text-darkSecondaryContrast dark:border-darkSecondaryContrast/40 dark:hover:bg-darkSecondary/60 dark:hover:border-darkSecondary/60': props.mode === 'secondary',
|
|
10
11
|
}"
|
|
11
12
|
>
|
|
12
13
|
<svg v-if="props.loader"
|
|
@@ -18,10 +19,16 @@
|
|
|
18
19
|
|
|
19
20
|
<script setup lang="ts">
|
|
20
21
|
|
|
21
|
-
const props = defineProps
|
|
22
|
-
loader
|
|
23
|
-
disabled
|
|
24
|
-
active
|
|
22
|
+
const props = withDefaults(defineProps<{
|
|
23
|
+
loader?: boolean;
|
|
24
|
+
disabled?: boolean;
|
|
25
|
+
active?: boolean;
|
|
26
|
+
mode?: 'primary' | 'secondary';
|
|
27
|
+
}>(), {
|
|
28
|
+
loader: false,
|
|
29
|
+
disabled: false,
|
|
30
|
+
active: false,
|
|
31
|
+
mode: 'primary'
|
|
25
32
|
});
|
|
26
33
|
|
|
27
34
|
</script>
|
|
@@ -1,124 +1,188 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
<Modal
|
|
3
|
+
ref="modalRef"
|
|
4
|
+
v-bind="$attrs"
|
|
5
|
+
:closeByClickOutside="clickToCloseOutside || closeByClickOutside"
|
|
6
|
+
:closeByEsc="closeByEsc || closable"
|
|
7
|
+
:beforeCloseFunction="beforeCloseFunction"
|
|
8
|
+
:beforeOpenFunction="beforeOpenFunction"
|
|
9
|
+
:askForCloseConfirmation="askForCloseConfirmation"
|
|
10
|
+
:closeConfirmationText="closeConfirmationText"
|
|
11
|
+
:removeFromDomOnClose="removeFromDomOnClose"
|
|
5
12
|
>
|
|
6
|
-
<
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
>
|
|
49
|
-
{{ button.label }}
|
|
50
|
-
</Button>
|
|
51
|
-
</div>
|
|
52
|
-
</div>
|
|
53
|
-
</div>
|
|
54
|
-
<div>
|
|
55
|
-
<!-- Confirmation Modal -->
|
|
56
|
-
<div
|
|
57
|
-
v-if="showConfirmationOnClose"
|
|
58
|
-
class="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50 z-[60]"
|
|
59
|
-
>
|
|
60
|
-
<div class="bg-white dark:bg-gray-800 p-6 rounded-lg shadow-lg max-w-sm w-full">
|
|
61
|
-
<h2 class="text-lg font-semibold mb-4 text-lightDialogHeaderText dark:text-darkDialogHeaderText">Confirm Close</h2>
|
|
62
|
-
<p class="mb-6 text-lightDialogBodyText dark:text-darkDialogBodyText">{{ props.closeConfirmationText }}</p>
|
|
63
|
-
<div class="flex justify-end">
|
|
64
|
-
<Button
|
|
65
|
-
class="me-3 !bg-gray-50 dark:!bg-gray-700 !text-lightDialogBodyText dark:!text-darkDialogBodyText hover:!bg-gray-100 dark:hover:!bg-gray-600 !border-gray-200 dark:!border-gray-600"
|
|
66
|
-
@click="showConfirmationOnClose = false"
|
|
67
|
-
>
|
|
68
|
-
Cancel
|
|
69
|
-
</Button>
|
|
70
|
-
<Button
|
|
71
|
-
@click="
|
|
72
|
-
showConfirmationOnClose = false;
|
|
73
|
-
modal?.hide();
|
|
74
|
-
"
|
|
75
|
-
>
|
|
76
|
-
Confirm
|
|
77
|
-
</Button>
|
|
78
|
-
</div>
|
|
79
|
-
</div>
|
|
80
|
-
</div>
|
|
81
|
-
</div>
|
|
13
|
+
<template v-if="$slots.trigger" #trigger>
|
|
14
|
+
<slot name="trigger"></slot>
|
|
15
|
+
</template>
|
|
16
|
+
|
|
17
|
+
<!-- Modal header -->
|
|
18
|
+
<div
|
|
19
|
+
v-if="header"
|
|
20
|
+
class="flex items-center justify-between p-4 md:p-5 border-b rounded-t dark:border-darkDialogBreakLine border-lightDialogBreakLine"
|
|
21
|
+
>
|
|
22
|
+
<h3 class="text-xl font-semibold text-lightDialogHeaderText dark:text-darkDialogHeaderText">
|
|
23
|
+
{{ header }}
|
|
24
|
+
</h3>
|
|
25
|
+
<button
|
|
26
|
+
v-if="headerCloseButton"
|
|
27
|
+
type="button"
|
|
28
|
+
class="text-lightDialogCloseButton bg-transparent hover:bg-lightDialogCloseButtonHoverBackground hover:text-lightDialogCloseButtonHover rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center dark:text-darkDialogCloseButton dark:hover:bg-darkDialogCloseButtonHoverBackground dark:hover:text-darkDialogCloseButtonHover"
|
|
29
|
+
@click="tryToHideModal"
|
|
30
|
+
>
|
|
31
|
+
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14">
|
|
32
|
+
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"/>
|
|
33
|
+
</svg>
|
|
34
|
+
<span class="sr-only">{{ t('Close Modal') }}</span>
|
|
35
|
+
</button>
|
|
36
|
+
</div>
|
|
37
|
+
<!-- Modal body -->
|
|
38
|
+
<div class="p-4 md:p-5 text-lightDialogBodyText dark:text-darkDialogBodyText">
|
|
39
|
+
<slot></slot>
|
|
40
|
+
</div>
|
|
41
|
+
<!-- Modal footer -->
|
|
42
|
+
<div
|
|
43
|
+
v-if="buttons.length"
|
|
44
|
+
class="flex items-center p-4 md:p-5 border-t border-lightDialogBreakLine rounded-b dark:border-darkDialogBreakLine"
|
|
45
|
+
>
|
|
46
|
+
<Button
|
|
47
|
+
v-for="(button, buttonIndex) in buttons"
|
|
48
|
+
:key="buttonIndex"
|
|
49
|
+
v-bind="button.options"
|
|
50
|
+
:class="{ 'ms-3': buttonIndex > 0 }"
|
|
51
|
+
@click="button.onclick(dialog)"
|
|
52
|
+
>
|
|
53
|
+
{{ button.label }}
|
|
54
|
+
</Button>
|
|
82
55
|
</div>
|
|
83
|
-
</
|
|
56
|
+
</Modal>
|
|
84
57
|
</template>
|
|
85
58
|
|
|
86
59
|
<script setup lang="ts">
|
|
87
60
|
import Button from "./Button.vue";
|
|
88
|
-
import { ref,
|
|
89
|
-
import { Modal } from '
|
|
61
|
+
import { ref, computed, type Ref } from 'vue';
|
|
62
|
+
import { Modal } from '@/afcl'
|
|
63
|
+
import { useI18n } from "vue-i18n";
|
|
64
|
+
|
|
65
|
+
const { t } = useI18n();
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
interface IDialogInsideButtonClickHandler {
|
|
69
|
+
hide: () => void
|
|
70
|
+
}
|
|
90
71
|
|
|
91
|
-
const modalEl = ref(null);
|
|
92
|
-
const modal: Ref<Modal|null> = ref(null);
|
|
93
72
|
|
|
94
73
|
interface DialogButton {
|
|
95
74
|
label: string
|
|
96
|
-
onclick: (dialog:
|
|
75
|
+
onclick: (dialog: IDialogInsideButtonClickHandler) => void
|
|
97
76
|
options?: Record<string, any>
|
|
98
77
|
}
|
|
99
78
|
|
|
79
|
+
|
|
100
80
|
interface DialogProps {
|
|
81
|
+
/**
|
|
82
|
+
* The header text to display in the dialog. If not provided, no header will be displayed.
|
|
83
|
+
*/
|
|
101
84
|
header?: string
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* If true, a close button will be displayed in the dialog header. Default is true.
|
|
88
|
+
*/
|
|
102
89
|
headerCloseButton?: boolean
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* An array of buttons to display in the dialog footer.
|
|
93
|
+
*/
|
|
103
94
|
buttons?: DialogButton[]
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* If true, clicking outside the dialog will close it. Default is true.
|
|
98
|
+
*
|
|
99
|
+
* @deprecated Use `closeByClickOutside` instead
|
|
100
|
+
*/
|
|
104
101
|
clickToCloseOutside?: boolean
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* If true, pressing the Esc key will close the dialog. Default is true.
|
|
105
|
+
*/
|
|
106
|
+
closeByEsc?: boolean
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* If true, clicking outside the dialog will close it. Default is true.
|
|
110
|
+
*/
|
|
111
|
+
closeByClickOutside?: boolean
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Function that will be called before the dialog is closed.
|
|
115
|
+
*/
|
|
105
116
|
beforeCloseFunction?: (() => void | Promise<void>) | null
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Function that will be called before the dialog is opened.
|
|
120
|
+
*/
|
|
106
121
|
beforeOpenFunction?: (() => void | Promise<void>) | null
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Disables close on Ecs button
|
|
125
|
+
*
|
|
126
|
+
* @deprecated Use `closeByEsc` or instead
|
|
127
|
+
*/
|
|
107
128
|
closable?: boolean
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* If true, the dialog will ask for confirmation before closing. Default is false.
|
|
132
|
+
*/
|
|
108
133
|
askForCloseConfirmation?: boolean
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* The text to display in the close confirmation dialog. Default is "Are you sure you want to close this dialog?".
|
|
137
|
+
*/
|
|
109
138
|
closeConfirmationText?: string
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* If true, the dialog will be removed from the DOM when closed. Default is false.
|
|
142
|
+
*/
|
|
143
|
+
removeFromDomOnClose?: boolean
|
|
110
144
|
}
|
|
111
145
|
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
/********** for the backward compatibility ***************/
|
|
152
|
+
class Dialog implements IDialogInsideButtonClickHandler {
|
|
153
|
+
hide: () => void
|
|
154
|
+
constructor( hide: () => void ) {
|
|
155
|
+
this.hide = hide;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
const dialog: Ref<Dialog> = ref(
|
|
159
|
+
new Dialog(
|
|
160
|
+
() => {
|
|
161
|
+
if (dialog.value) {
|
|
162
|
+
tryToHideModal();
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
)
|
|
166
|
+
);
|
|
167
|
+
/*************************************************************/
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
const modalRef = ref();
|
|
172
|
+
|
|
112
173
|
const props = withDefaults(defineProps<DialogProps>(), {
|
|
113
174
|
header: '',
|
|
114
175
|
headerCloseButton: true,
|
|
115
176
|
buttons: () => [],
|
|
116
|
-
clickToCloseOutside:
|
|
177
|
+
clickToCloseOutside: false,
|
|
178
|
+
closeByEsc: true,
|
|
179
|
+
closeByClickOutside: true,
|
|
117
180
|
beforeCloseFunction: null,
|
|
118
181
|
beforeOpenFunction: null,
|
|
119
|
-
closable:
|
|
182
|
+
closable: false,
|
|
120
183
|
askForCloseConfirmation: false,
|
|
121
184
|
closeConfirmationText: 'Are you sure you want to close this dialog?',
|
|
185
|
+
removeFromDomOnClose: false,
|
|
122
186
|
})
|
|
123
187
|
|
|
124
188
|
const buttons = computed<DialogButton[]>(() => {
|
|
@@ -129,51 +193,20 @@ const buttons = computed<DialogButton[]>(() => {
|
|
|
129
193
|
{
|
|
130
194
|
label: 'Close',
|
|
131
195
|
onclick: (dialog: any) => {
|
|
132
|
-
|
|
133
|
-
dialog.hide();
|
|
134
|
-
} else {
|
|
135
|
-
showConfirmationOnClose.value = true;
|
|
136
|
-
}
|
|
196
|
+
tryToHideModal();
|
|
137
197
|
},
|
|
138
198
|
options: {}
|
|
139
199
|
}
|
|
140
200
|
];
|
|
141
201
|
});
|
|
142
202
|
|
|
143
|
-
const showConfirmationOnClose = ref(false);
|
|
144
|
-
onMounted(async () => {
|
|
145
|
-
//await one tick when all is mounted
|
|
146
|
-
await nextTick();
|
|
147
|
-
modal.value = new Modal(
|
|
148
|
-
modalEl.value,
|
|
149
|
-
{
|
|
150
|
-
closable: props.closable,
|
|
151
|
-
backdrop: props.clickToCloseOutside ? 'dynamic' : 'static',
|
|
152
|
-
onHide: async () => {
|
|
153
|
-
if (props.beforeCloseFunction) {
|
|
154
|
-
await props.beforeCloseFunction();
|
|
155
|
-
}
|
|
156
|
-
},
|
|
157
|
-
onShow: async () => {
|
|
158
|
-
if (props.beforeOpenFunction) {
|
|
159
|
-
await props.beforeOpenFunction();
|
|
160
|
-
}
|
|
161
|
-
},
|
|
162
|
-
}
|
|
163
|
-
);
|
|
164
|
-
})
|
|
165
|
-
|
|
166
|
-
onUnmounted(() => {
|
|
167
|
-
//destroy tooltip
|
|
168
|
-
modal.value?.destroy();
|
|
169
|
-
})
|
|
170
203
|
|
|
171
204
|
function open() {
|
|
172
|
-
|
|
205
|
+
modalRef.value.open();
|
|
173
206
|
}
|
|
174
207
|
|
|
175
208
|
function close() {
|
|
176
|
-
|
|
209
|
+
modalRef.value.hide();
|
|
177
210
|
}
|
|
178
211
|
|
|
179
212
|
defineExpose({
|
|
@@ -183,11 +216,7 @@ defineExpose({
|
|
|
183
216
|
})
|
|
184
217
|
|
|
185
218
|
function tryToHideModal() {
|
|
186
|
-
|
|
187
|
-
modal.value?.hide();
|
|
188
|
-
} else {
|
|
189
|
-
showConfirmationOnClose.value = true;
|
|
190
|
-
}
|
|
219
|
+
modalRef.value?.tryToHideModal();
|
|
191
220
|
}
|
|
192
221
|
|
|
193
222
|
|
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
<slot name="trigger"></slot>
|
|
7
7
|
</div>
|
|
8
8
|
<Teleport to="body">
|
|
9
|
-
<div v-show="isModalOpen" v-if="!removeFromDom" @click="backdropClick"
|
|
9
|
+
<div v-show="isModalOpen" v-if="!removeFromDom" @click="backdropClick" class="bg-black/50 overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full h-full md:inset-0 h-1rem max-h-full flex" >
|
|
10
10
|
<!-- Modal content -->
|
|
11
|
-
<div class="relative bg-lightDialogBackgorund rounded-lg shadow-sm dark:bg-darkDialogBackgorund">
|
|
11
|
+
<div v-bind="$attrs" class="relative bg-lightDialogBackgorund rounded-lg shadow-sm dark:bg-darkDialogBackgorund">
|
|
12
12
|
|
|
13
13
|
<!-- Modal body -->
|
|
14
|
-
<div class="
|
|
14
|
+
<div class="text-lightDialogBodyText dark:text-darkDialogBodyText">
|
|
15
15
|
<slot ></slot>
|
|
16
16
|
</div>
|
|
17
17
|
|
|
@@ -57,7 +57,8 @@ const removeFromDom = computed(() => {
|
|
|
57
57
|
})
|
|
58
58
|
|
|
59
59
|
interface DialogProps {
|
|
60
|
-
|
|
60
|
+
closeByClickOutside?: boolean
|
|
61
|
+
closeByEsc?: boolean
|
|
61
62
|
beforeCloseFunction?: (() => void | Promise<void>) | null
|
|
62
63
|
beforeOpenFunction?: (() => void | Promise<void>) | null
|
|
63
64
|
askForCloseConfirmation?: boolean
|
|
@@ -66,7 +67,8 @@ interface DialogProps {
|
|
|
66
67
|
}
|
|
67
68
|
|
|
68
69
|
const props = withDefaults(defineProps<DialogProps>(), {
|
|
69
|
-
|
|
70
|
+
closeByClickOutside: true,
|
|
71
|
+
closeByEsc: true,
|
|
70
72
|
beforeCloseFunction: null,
|
|
71
73
|
beforeOpenFunction: null,
|
|
72
74
|
askForCloseConfirmation: false,
|
|
@@ -78,12 +80,16 @@ const showConfirmationOnClose = ref(false);
|
|
|
78
80
|
|
|
79
81
|
|
|
80
82
|
async function open() {
|
|
81
|
-
|
|
83
|
+
if (props.beforeOpenFunction) {
|
|
84
|
+
await props.beforeOpenFunction?.();
|
|
85
|
+
}
|
|
82
86
|
isModalOpen.value = true;
|
|
83
87
|
}
|
|
84
88
|
|
|
85
89
|
async function close() {
|
|
86
|
-
|
|
90
|
+
if (props.beforeCloseFunction) {
|
|
91
|
+
await props.beforeCloseFunction?.();
|
|
92
|
+
}
|
|
87
93
|
isModalOpen.value = false;
|
|
88
94
|
}
|
|
89
95
|
|
|
@@ -109,8 +115,25 @@ function toggleModal() {
|
|
|
109
115
|
}
|
|
110
116
|
}
|
|
111
117
|
|
|
118
|
+
function onEsc(event: KeyboardEvent) {
|
|
119
|
+
if (event.key === 'Escape') {
|
|
120
|
+
if (props.closeByEsc) {
|
|
121
|
+
tryToHideModal();
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
onMounted(() => {
|
|
127
|
+
document.addEventListener('keydown', onEsc)
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
onUnmounted(() => {
|
|
131
|
+
document.removeEventListener('keydown', onEsc)
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
|
|
112
135
|
function backdropClick(e: MouseEvent) {
|
|
113
|
-
if (props.
|
|
136
|
+
if (props.closeByClickOutside && e.target === e.currentTarget) {
|
|
114
137
|
tryToHideModal();
|
|
115
138
|
}
|
|
116
139
|
}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
class="block w-full pl-3 pr-10 py-2.5 border border-lightDropownButtonsBorder rounded-md leading-5 bg-lightDropdownButtonsBackground
|
|
14
14
|
placeholder-lightDropdownButtonsPlaceholderText text-lightDropdownButtonsText sm:text-sm transition duration-150 ease-in-out dark:bg-darkDropdownButtonsBackground dark:border-darkDropdownButtonsBorder dark:placeholder-darkDropdownButtonsPlaceholderText
|
|
15
15
|
dark:text-darkDropdownButtonsText focus:ring-lightPrimary focus:border-lightPrimary dark:focus:ring-darkPrimary dark:focus:border-darkPrimary"
|
|
16
|
-
:class="{'cursor-pointer': searchDisabled}"
|
|
16
|
+
:class="[{'cursor-pointer': searchDisabled}, classesForInput]"
|
|
17
17
|
autocomplete="off" data-custom="no-autofill"
|
|
18
18
|
:placeholder="
|
|
19
19
|
selectedItems.length && !multiple ? '' : (showDropdown ? $t('Search') : placeholder || $t('Select...'))
|
|
@@ -122,7 +122,7 @@ import { useElementSize } from '@vueuse/core'
|
|
|
122
122
|
const props = defineProps({
|
|
123
123
|
options: Array,
|
|
124
124
|
modelValue: {
|
|
125
|
-
type: Array as PropType<(string | number)[]>,
|
|
125
|
+
type: Array as PropType<(string | number)[] | (string | number)>,
|
|
126
126
|
default: () => [],
|
|
127
127
|
},
|
|
128
128
|
multiple: {
|
|
@@ -153,6 +153,10 @@ const props = defineProps({
|
|
|
153
153
|
type: Number,
|
|
154
154
|
default: 300,
|
|
155
155
|
},
|
|
156
|
+
classesForInput: {
|
|
157
|
+
type: String,
|
|
158
|
+
default: '',
|
|
159
|
+
},
|
|
156
160
|
});
|
|
157
161
|
|
|
158
162
|
const emit = defineEmits(['update:modelValue', 'scroll-near-end', 'search']);
|
|
@@ -1,41 +1,40 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<Teleport to="body">
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
3
|
+
<Modal
|
|
4
|
+
ref="modalRef"
|
|
5
|
+
:beforeCloseFunction="()=>{modalStore.onAcceptFunction(false);modalStore.isOpened=false}"
|
|
6
|
+
>
|
|
7
|
+
<div class="relative p-4 w-full max-w-md max-h-full" >
|
|
8
|
+
<button type="button" @click="modalStore.togleModal()" class="absolute top-3 end-2.5 text-lightAcceptModalCloseIcon bg-transparent hover:bg-lightAcceptModalCloseIconHoverBackground hover:text-lightAcceptModalCloseIconHover rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center dark:text-darkAcceptModalCloseIcon dark:hover:bg-darkAcceptModalCloseIconHoverBackground dark:hover:text-darkAcceptModalCloseIconHover" >
|
|
9
|
+
<svg class="w-3 h-3" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14">
|
|
10
|
+
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"/>
|
|
11
|
+
</svg>
|
|
12
|
+
<span class="sr-only">{{ $t('Close modal') }}</span>
|
|
13
|
+
</button>
|
|
14
|
+
<div class="p-4 md:p-5 text-center">
|
|
15
|
+
<svg class="mx-auto mb-4 text-lightAcceptModalWarningIcon w-12 h-12 dark:text-darkAcceptModalWarningIcon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20">
|
|
16
|
+
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 11V6m0 8h.01M19 10a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/>
|
|
17
|
+
</svg>
|
|
18
|
+
<h3 class="afcl-confirmation-title mb-5 text-lg font-normal text-lightAcceptModalText dark:text-darkAcceptModalText">{{ modalStore?.modalContent?.content }}</h3>
|
|
19
|
+
<h3 class=" afcl-confirmation-title mb-5 text-lg font-normal text-lightAcceptModalText dark:text-darkAcceptModalText" v-html="modalStore?.modalContent?.contentHTML"></h3>
|
|
20
|
+
|
|
21
|
+
<button @click="()=>{ modalStore.onAcceptFunction(true);modalStore.togleModal()}" type="button" class="afcl-confirmation-accept-button text-lightAcceptModalConfirmButtonText bg-lightAcceptModalConfirmButtonBackground hover:bg-lightAcceptModalConfirmButtonBackgroundHover focus:ring-4 focus:outline-none focus:ring-lightAcceptModalConfirmButtonFocus font-medium rounded-lg text-sm inline-flex items-center px-5 py-2.5 text-center dark:text-darkAcceptModalConfirmButtonText dark:bg-darkAcceptModalConfirmButtonBackground dark:hover:bg-darkAcceptModalConfirmButtonBackgroundHover dark:focus:ring-darkAcceptModalConfirmButtonFocus">
|
|
22
|
+
{{ modalStore?.modalContent?.acceptText }}
|
|
23
|
+
</button>
|
|
24
|
+
<button @click="()=>{modalStore.onAcceptFunction(false);modalStore.togleModal()}" type="button" class="afcl-confirmation-cancel-button py-2.5 px-5 ms-3 text-sm font-medium text-lightAcceptModalCancelButtonText focus:outline-none bg-lightAcceptModalCancelButtonBackground rounded-lg border border-lightAcceptModalCancelButtonBorder hover:bg-lightAcceptModalCancelButtonBackgroundHover hover:text-lightPrimary focus:z-10 focus:ring-4 focus:ring-lightAcceptModalCancelButtonFocus dark:focus:ring-darkAcceptModalCancelButtonFocus dark:bg-darkAcceptModalCancelButtonBackground dark:text-darkAcceptModalCancelButtonText dark:border-darkAcceptModalCancelButtonBorder dark:hover:text-darkAcceptModalCancelButtonTextHover dark:hover:bg-darkAcceptModalCancelButtonBackgroundHover">{{ modalStore?.modalContent?.cancelText }}</button>
|
|
25
25
|
</div>
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
</Teleport>
|
|
26
|
+
</div>
|
|
27
|
+
</Modal>
|
|
28
|
+
</Teleport>
|
|
29
29
|
</template>
|
|
30
30
|
|
|
31
31
|
<script setup lang="ts">
|
|
32
32
|
import { watch, onMounted, nextTick, ref } from 'vue';
|
|
33
33
|
import { useModalStore } from '@/stores/modal';
|
|
34
|
-
import { Modal } from '
|
|
34
|
+
import { Modal } from '@/afcl';
|
|
35
35
|
|
|
36
|
+
const modalRef = ref();
|
|
36
37
|
const modalStore = useModalStore();
|
|
37
|
-
const modalEl = ref(null);
|
|
38
|
-
const modal = ref(null);
|
|
39
38
|
|
|
40
39
|
watch( () => modalStore.isOpened, (newVal) => {
|
|
41
40
|
if (newVal) {
|
|
@@ -46,35 +45,14 @@ watch( () => modalStore.isOpened, (newVal) => {
|
|
|
46
45
|
}
|
|
47
46
|
);
|
|
48
47
|
|
|
49
|
-
|
|
50
|
-
await nextTick();
|
|
51
|
-
modal.value = new Modal(
|
|
52
|
-
modalEl.value,
|
|
53
|
-
{
|
|
54
|
-
closable: true,
|
|
55
|
-
backdrop: 'static',
|
|
56
|
-
backdropClasses: "bg-gray-900/50 dark:bg-gray-900/80 fixed inset-0 z-[100]"
|
|
57
|
-
}
|
|
58
|
-
);
|
|
59
|
-
})
|
|
48
|
+
|
|
60
49
|
|
|
61
50
|
function open() {
|
|
62
|
-
|
|
51
|
+
modalRef.value.open();
|
|
63
52
|
}
|
|
64
53
|
|
|
65
54
|
function close() {
|
|
66
|
-
|
|
55
|
+
modalRef.value.close();
|
|
67
56
|
}
|
|
68
57
|
|
|
69
|
-
</script>
|
|
70
|
-
|
|
71
|
-
<style scoped>
|
|
72
|
-
.modal {
|
|
73
|
-
position: fixed;
|
|
74
|
-
z-index: 999;
|
|
75
|
-
top: 20%;
|
|
76
|
-
left: 50%;
|
|
77
|
-
width: 300px;
|
|
78
|
-
margin-left: -150px;
|
|
79
|
-
}
|
|
80
|
-
</style>
|
|
58
|
+
</script>
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<RouterLink
|
|
3
|
-
:to="{name: item.resourceId ? 'resource-list' : item.path, params: item.resourceId ? { resourceId: item.resourceId }: {}}"
|
|
3
|
+
:to="item.url || { name: item.resourceId ? 'resource-list' : item.path, params: item.resourceId ? { resourceId: item.resourceId }: {}}"
|
|
4
|
+
:target="item.isOpenInNewTab ? '_blank' : '_self'"
|
|
4
5
|
class="af-menu-link flex group relative items-center w-full py-2 text-lightSidebarText dark:text-darkSidebarText rounded-default transition-all duration-200 ease-in-out"
|
|
5
6
|
:class="{
|
|
6
7
|
'hover:bg-lightSidebarItemHover hover:text-lightSidebarTextHover dark:hover:bg-darkSidebarItemHover dark:hover:text-darkSidebarTextHover active:bg-lightSidebarActive dark:active:bg-darkSidebarHover': !['divider', 'gap', 'heading'].includes(item.type),
|
|
7
8
|
'pl-6 pr-3.5': (isChild && !isSidebarIconOnly && !isSidebarHovering) || (isChild && isSidebarIconOnly && isSidebarHovering),
|
|
8
9
|
'px-3.5 ': !isChild || (isSidebarIconOnly && !isSidebarHovering),
|
|
9
10
|
'max-w-12': isSidebarIconOnly && !isSidebarHovering,
|
|
10
|
-
'bg-lightSidebarItemActive dark:bg-darkSidebarItemActive': item
|
|
11
|
-
($route.params.resourceId === item.resourceId && $route.name === 'resource-list') :
|
|
12
|
-
($route.name === item.path)
|
|
11
|
+
'bg-lightSidebarItemActive dark:bg-darkSidebarItemActive': isItemActive(item)
|
|
13
12
|
}"
|
|
14
13
|
>
|
|
15
14
|
<component v-if="item.icon" :is="getIcon(item.icon)"
|
|
@@ -61,6 +60,21 @@ import { Tooltip } from '@/afcl';
|
|
|
61
60
|
import { ref, watch, computed } from 'vue';
|
|
62
61
|
import { useCoreStore } from '@/stores/core';
|
|
63
62
|
import { IconFileImageOutline } from '@iconify-prerendered/vue-flowbite';
|
|
63
|
+
import { useRoute } from 'vue-router';
|
|
64
|
+
|
|
65
|
+
const route = useRoute();
|
|
66
|
+
|
|
67
|
+
const isItemActive = (item: any) => {
|
|
68
|
+
if (item.url) {
|
|
69
|
+
return route.fullPath === item.url;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (item.resourceId) {
|
|
73
|
+
return route.params.resourceId === item.resourceId && route.name === 'resource-list';
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return route.name === item.path;
|
|
77
|
+
};
|
|
64
78
|
|
|
65
79
|
const props = defineProps(['item', 'isChild', 'isSidebarIconOnly', 'isSidebarHovering']);
|
|
66
80
|
|