adminforth 2.25.0-test.9 → 2.25.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/commands/createApp/templates/Dockerfile.hbs +5 -5
- package/commands/createApp/templates/custom/package.json.hbs +12 -0
- package/commands/createApp/templates/package.json.hbs +6 -6
- package/commands/createApp/templates/readme.md.hbs +5 -5
- package/commands/createApp/utils.js +10 -10
- package/commands/createPlugin/utils.js +6 -5
- package/commands/postinstall.js +1 -1
- package/dist/dataConnectors/baseConnector.d.ts +2 -2
- package/dist/dataConnectors/baseConnector.d.ts.map +1 -1
- package/dist/dataConnectors/baseConnector.js +1 -1
- package/dist/dataConnectors/baseConnector.js.map +1 -1
- package/dist/dataConnectors/mysql.d.ts +3 -2
- package/dist/dataConnectors/mysql.d.ts.map +1 -1
- package/dist/dataConnectors/mysql.js +26 -1
- package/dist/dataConnectors/mysql.js.map +1 -1
- package/dist/dataConnectors/postgres.d.ts +3 -2
- package/dist/dataConnectors/postgres.d.ts.map +1 -1
- package/dist/dataConnectors/postgres.js +25 -1
- package/dist/dataConnectors/postgres.js.map +1 -1
- package/dist/dataConnectors/sqlite.d.ts +3 -2
- package/dist/dataConnectors/sqlite.d.ts.map +1 -1
- package/dist/dataConnectors/sqlite.js +21 -1
- package/dist/dataConnectors/sqlite.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/modules/codeInjector.d.ts +2 -2
- package/dist/modules/codeInjector.d.ts.map +1 -1
- package/dist/modules/codeInjector.js +48 -76
- package/dist/modules/codeInjector.js.map +1 -1
- package/dist/modules/configValidator.d.ts.map +1 -1
- package/dist/modules/configValidator.js +8 -1
- package/dist/modules/configValidator.js.map +1 -1
- package/dist/modules/restApi.d.ts.map +1 -1
- package/dist/modules/restApi.js +5 -0
- package/dist/modules/restApi.js.map +1 -1
- package/dist/modules/styles.d.ts +0 -4
- package/dist/modules/styles.d.ts.map +1 -1
- package/dist/modules/styles.js +0 -4
- package/dist/modules/styles.js.map +1 -1
- package/dist/modules/utils.d.ts +7 -0
- package/dist/modules/utils.d.ts.map +1 -1
- package/dist/modules/utils.js +34 -0
- package/dist/modules/utils.js.map +1 -1
- package/dist/servers/express.d.ts +1 -0
- package/dist/servers/express.d.ts.map +1 -1
- package/dist/spa/README.md +4 -4
- package/dist/spa/package-lock.json +1420 -1882
- package/dist/spa/package.json +3 -3
- package/dist/spa/src/afcl/Button.vue +5 -12
- package/dist/spa/src/afcl/Dialog.vue +126 -155
- package/dist/spa/src/afcl/Modal.vue +6 -25
- package/dist/spa/src/afcl/Select.vue +1 -1
- 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 +2 -1
- package/dist/spa/src/types/Back.ts +4 -3
- package/dist/spa/src/types/Common.ts +0 -6
- package/dist/spa/src/types/FrontendAPI.ts +3 -0
- package/dist/spa/src/utils/utils.ts +2 -57
- package/dist/spa/src/views/CreateView.vue +11 -12
- package/dist/spa/src/views/EditView.vue +13 -9
- package/dist/spa/vite.config.ts +40 -27
- package/dist/types/Back.d.ts +5 -3
- package/dist/types/Back.d.ts.map +1 -1
- package/dist/types/Common.d.ts +0 -5
- package/dist/types/Common.d.ts.map +1 -1
- package/dist/types/Common.js.map +1 -1
- package/package.json +6 -13
- package/commands/createApp/templates/pnpm-workspace.yaml.hbs +0 -2
- package/dist/spa/pnpm-lock.yaml +0 -3546
package/dist/spa/package.json
CHANGED
|
@@ -30,8 +30,7 @@
|
|
|
30
30
|
"vue-diff": "^1.2.4",
|
|
31
31
|
"vue-i18n": "^10.0.5",
|
|
32
32
|
"vue-router": "^4.3.0",
|
|
33
|
-
"vue-slider-component": "^4.1.0-beta.7"
|
|
34
|
-
"vue3-json-viewer": "^2.2.2"
|
|
33
|
+
"vue-slider-component": "^4.1.0-beta.7"
|
|
35
34
|
},
|
|
36
35
|
"devDependencies": {
|
|
37
36
|
"@rushstack/eslint-patch": "^1.8.0",
|
|
@@ -55,6 +54,7 @@
|
|
|
55
54
|
"typescript": "~5.4.0",
|
|
56
55
|
"vite": "^5.2.13",
|
|
57
56
|
"vue-i18n-extract": "^2.0.7",
|
|
58
|
-
"vue-tsc": "^2.0.11"
|
|
57
|
+
"vue-tsc": "^2.0.11",
|
|
58
|
+
"vue3-json-viewer": "^2.2.2"
|
|
59
59
|
}
|
|
60
60
|
}
|
|
@@ -6,8 +6,7 @@
|
|
|
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
|
|
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',
|
|
9
|
+
'active brightness-200 hover:brightness-150' : props.active
|
|
11
10
|
}"
|
|
12
11
|
>
|
|
13
12
|
<svg v-if="props.loader"
|
|
@@ -19,16 +18,10 @@
|
|
|
19
18
|
|
|
20
19
|
<script setup lang="ts">
|
|
21
20
|
|
|
22
|
-
const props =
|
|
23
|
-
loader
|
|
24
|
-
disabled
|
|
25
|
-
active
|
|
26
|
-
mode?: 'primary' | 'secondary';
|
|
27
|
-
}>(), {
|
|
28
|
-
loader: false,
|
|
29
|
-
disabled: false,
|
|
30
|
-
active: false,
|
|
31
|
-
mode: 'primary'
|
|
21
|
+
const props = defineProps({
|
|
22
|
+
loader: Boolean,
|
|
23
|
+
disabled: Boolean,
|
|
24
|
+
active: Boolean,
|
|
32
25
|
});
|
|
33
26
|
|
|
34
27
|
</script>
|
|
@@ -1,188 +1,124 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
:closeByClickOutside="clickToCloseOutside || closeByClickOutside"
|
|
6
|
-
:closeByEsc="closeByEsc || closable"
|
|
7
|
-
:beforeCloseFunction="beforeCloseFunction"
|
|
8
|
-
:beforeOpenFunction="beforeOpenFunction"
|
|
9
|
-
:askForCloseConfirmation="askForCloseConfirmation"
|
|
10
|
-
:closeConfirmationText="closeConfirmationText"
|
|
11
|
-
:removeFromDomOnClose="removeFromDomOnClose"
|
|
2
|
+
<div
|
|
3
|
+
v-if="$slots.trigger"
|
|
4
|
+
@click="modal?.show()" class="inline-flex items-center cursor-pointer"
|
|
12
5
|
>
|
|
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
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
6
|
+
<slot name="trigger"></slot>
|
|
7
|
+
</div>
|
|
8
|
+
<Teleport to="body">
|
|
9
|
+
<div ref="modalEl" tabindex="-1" aria-hidden="true" class="[scrollbar-gutter:stable] hidden overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-full max-h-full">
|
|
10
|
+
<div v-bind="$attrs" class="relative p-4 max-w-2xl max-h-full" :class="($attrs.class as string)?.includes('w-') ? '' : 'w-full'">
|
|
11
|
+
<!-- Modal content -->
|
|
12
|
+
<div class="relative bg-lightDialogBackgorund rounded-lg shadow-sm dark:bg-darkDialogBackgorund">
|
|
13
|
+
<!-- Modal header -->
|
|
14
|
+
<div
|
|
15
|
+
v-if="header"
|
|
16
|
+
class="flex items-center justify-between p-4 md:p-5 border-b rounded-t dark:border-darkDialogBreakLine border-lightDialogBreakLine"
|
|
17
|
+
>
|
|
18
|
+
<h3 class="text-xl font-semibold text-lightDialogHeaderText dark:text-darkDialogHeaderText">
|
|
19
|
+
{{ header }}
|
|
20
|
+
</h3>
|
|
21
|
+
<button
|
|
22
|
+
v-if="headerCloseButton"
|
|
23
|
+
type="button"
|
|
24
|
+
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"
|
|
25
|
+
@click="tryToHideModal"
|
|
26
|
+
>
|
|
27
|
+
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14">
|
|
28
|
+
<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"/>
|
|
29
|
+
</svg>
|
|
30
|
+
<span class="sr-only">Close modal</span>
|
|
31
|
+
</button>
|
|
32
|
+
</div>
|
|
33
|
+
<!-- Modal body -->
|
|
34
|
+
<div class="p-4 md:p-5 space-y-4 text-lightDialogBodyText dark:text-darkDialogBodyText">
|
|
35
|
+
<slot></slot>
|
|
36
|
+
</div>
|
|
37
|
+
<!-- Modal footer -->
|
|
38
|
+
<div
|
|
39
|
+
v-if="buttons.length"
|
|
40
|
+
class="flex items-center p-4 md:p-5 border-t border-lightDialogBreakLine rounded-b dark:border-darkDialogBreakLine"
|
|
41
|
+
>
|
|
42
|
+
<Button
|
|
43
|
+
v-for="(button, buttonIndex) in buttons"
|
|
44
|
+
:key="buttonIndex"
|
|
45
|
+
v-bind="button.options"
|
|
46
|
+
:class="{ 'ms-3': buttonIndex > 0 }"
|
|
47
|
+
@click="button.onclick(modal)"
|
|
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>
|
|
55
82
|
</div>
|
|
56
|
-
</
|
|
83
|
+
</Teleport>
|
|
57
84
|
</template>
|
|
58
85
|
|
|
59
86
|
<script setup lang="ts">
|
|
60
87
|
import Button from "./Button.vue";
|
|
61
|
-
import { ref, computed, type Ref } from 'vue';
|
|
62
|
-
import { Modal } from '
|
|
63
|
-
import { useI18n } from "vue-i18n";
|
|
64
|
-
|
|
65
|
-
const { t } = useI18n();
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
interface IDialogInsideButtonClickHandler {
|
|
69
|
-
hide: () => void
|
|
70
|
-
}
|
|
88
|
+
import { ref, onMounted, nextTick, onUnmounted, computed, type Ref } from 'vue';
|
|
89
|
+
import { Modal } from 'flowbite';
|
|
71
90
|
|
|
91
|
+
const modalEl = ref(null);
|
|
92
|
+
const modal: Ref<Modal|null> = ref(null);
|
|
72
93
|
|
|
73
94
|
interface DialogButton {
|
|
74
95
|
label: string
|
|
75
|
-
onclick: (dialog:
|
|
96
|
+
onclick: (dialog: any) => void
|
|
76
97
|
options?: Record<string, any>
|
|
77
98
|
}
|
|
78
99
|
|
|
79
|
-
|
|
80
100
|
interface DialogProps {
|
|
81
|
-
/**
|
|
82
|
-
* The header text to display in the dialog. If not provided, no header will be displayed.
|
|
83
|
-
*/
|
|
84
101
|
header?: string
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* If true, a close button will be displayed in the dialog header. Default is true.
|
|
88
|
-
*/
|
|
89
102
|
headerCloseButton?: boolean
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* An array of buttons to display in the dialog footer.
|
|
93
|
-
*/
|
|
94
103
|
buttons?: DialogButton[]
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* If true, clicking outside the dialog will close it. Default is true.
|
|
98
|
-
*
|
|
99
|
-
* @deprecated Use `closeByClickOutside` instead
|
|
100
|
-
*/
|
|
101
104
|
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
|
-
*/
|
|
116
105
|
beforeCloseFunction?: (() => void | Promise<void>) | null
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Function that will be called before the dialog is opened.
|
|
120
|
-
*/
|
|
121
106
|
beforeOpenFunction?: (() => void | Promise<void>) | null
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Disables close on Ecs button
|
|
125
|
-
*
|
|
126
|
-
* @deprecated Use `closeByEsc` or instead
|
|
127
|
-
*/
|
|
128
107
|
closable?: boolean
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* If true, the dialog will ask for confirmation before closing. Default is false.
|
|
132
|
-
*/
|
|
133
108
|
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
|
-
*/
|
|
138
109
|
closeConfirmationText?: string
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* If true, the dialog will be removed from the DOM when closed. Default is false.
|
|
142
|
-
*/
|
|
143
|
-
removeFromDomOnClose?: boolean
|
|
144
110
|
}
|
|
145
111
|
|
|
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
|
-
|
|
173
112
|
const props = withDefaults(defineProps<DialogProps>(), {
|
|
174
113
|
header: '',
|
|
175
114
|
headerCloseButton: true,
|
|
176
115
|
buttons: () => [],
|
|
177
|
-
clickToCloseOutside:
|
|
178
|
-
closeByEsc: true,
|
|
179
|
-
closeByClickOutside: true,
|
|
116
|
+
clickToCloseOutside: true,
|
|
180
117
|
beforeCloseFunction: null,
|
|
181
118
|
beforeOpenFunction: null,
|
|
182
|
-
closable:
|
|
119
|
+
closable: true,
|
|
183
120
|
askForCloseConfirmation: false,
|
|
184
121
|
closeConfirmationText: 'Are you sure you want to close this dialog?',
|
|
185
|
-
removeFromDomOnClose: false,
|
|
186
122
|
})
|
|
187
123
|
|
|
188
124
|
const buttons = computed<DialogButton[]>(() => {
|
|
@@ -193,20 +129,51 @@ const buttons = computed<DialogButton[]>(() => {
|
|
|
193
129
|
{
|
|
194
130
|
label: 'Close',
|
|
195
131
|
onclick: (dialog: any) => {
|
|
196
|
-
|
|
132
|
+
if (!props.askForCloseConfirmation) {
|
|
133
|
+
dialog.hide();
|
|
134
|
+
} else {
|
|
135
|
+
showConfirmationOnClose.value = true;
|
|
136
|
+
}
|
|
197
137
|
},
|
|
198
138
|
options: {}
|
|
199
139
|
}
|
|
200
140
|
];
|
|
201
141
|
});
|
|
202
142
|
|
|
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
|
+
})
|
|
203
170
|
|
|
204
171
|
function open() {
|
|
205
|
-
|
|
172
|
+
modal.value?.show();
|
|
206
173
|
}
|
|
207
174
|
|
|
208
175
|
function close() {
|
|
209
|
-
|
|
176
|
+
modal.value?.hide();
|
|
210
177
|
}
|
|
211
178
|
|
|
212
179
|
defineExpose({
|
|
@@ -216,7 +183,11 @@ defineExpose({
|
|
|
216
183
|
})
|
|
217
184
|
|
|
218
185
|
function tryToHideModal() {
|
|
219
|
-
|
|
186
|
+
if (!props.askForCloseConfirmation ) {
|
|
187
|
+
modal.value?.hide();
|
|
188
|
+
} else {
|
|
189
|
+
showConfirmationOnClose.value = true;
|
|
190
|
+
}
|
|
220
191
|
}
|
|
221
192
|
|
|
222
193
|
|
|
@@ -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" 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
|
|
9
|
+
<div v-show="isModalOpen" v-if="!removeFromDom" @click="backdropClick" v-bind="$attrs" 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 md:inset-0 h-1rem max-h-full flex" >
|
|
10
10
|
<!-- Modal content -->
|
|
11
|
-
<div
|
|
11
|
+
<div class="relative bg-lightDialogBackgorund rounded-lg shadow-sm dark:bg-darkDialogBackgorund">
|
|
12
12
|
|
|
13
13
|
<!-- Modal body -->
|
|
14
|
-
<div class="text-lightDialogBodyText dark:text-darkDialogBodyText">
|
|
14
|
+
<div class="p-4 md:p-5 space-y-4 text-lightDialogBodyText dark:text-darkDialogBodyText">
|
|
15
15
|
<slot ></slot>
|
|
16
16
|
</div>
|
|
17
17
|
|
|
@@ -57,8 +57,7 @@ const removeFromDom = computed(() => {
|
|
|
57
57
|
})
|
|
58
58
|
|
|
59
59
|
interface DialogProps {
|
|
60
|
-
|
|
61
|
-
closeByEsc?: boolean
|
|
60
|
+
clickToCloseOutside?: boolean
|
|
62
61
|
beforeCloseFunction?: (() => void | Promise<void>) | null
|
|
63
62
|
beforeOpenFunction?: (() => void | Promise<void>) | null
|
|
64
63
|
askForCloseConfirmation?: boolean
|
|
@@ -67,8 +66,7 @@ interface DialogProps {
|
|
|
67
66
|
}
|
|
68
67
|
|
|
69
68
|
const props = withDefaults(defineProps<DialogProps>(), {
|
|
70
|
-
|
|
71
|
-
closeByEsc: true,
|
|
69
|
+
clickToCloseOutside: true,
|
|
72
70
|
beforeCloseFunction: null,
|
|
73
71
|
beforeOpenFunction: null,
|
|
74
72
|
askForCloseConfirmation: false,
|
|
@@ -111,25 +109,8 @@ function toggleModal() {
|
|
|
111
109
|
}
|
|
112
110
|
}
|
|
113
111
|
|
|
114
|
-
function onEsc(event: KeyboardEvent) {
|
|
115
|
-
if (event.key === 'Escape') {
|
|
116
|
-
if (props.closeByEsc) {
|
|
117
|
-
tryToHideModal();
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
onMounted(() => {
|
|
123
|
-
document.addEventListener('keydown', onEsc)
|
|
124
|
-
})
|
|
125
|
-
|
|
126
|
-
onUnmounted(() => {
|
|
127
|
-
document.removeEventListener('keydown', onEsc)
|
|
128
|
-
})
|
|
129
|
-
|
|
130
|
-
|
|
131
112
|
function backdropClick(e: MouseEvent) {
|
|
132
|
-
if (props.
|
|
113
|
+
if (props.clickToCloseOutside && e.target === e.currentTarget) {
|
|
133
114
|
tryToHideModal();
|
|
134
115
|
}
|
|
135
116
|
}
|
|
@@ -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)[]>,
|
|
126
126
|
default: () => [],
|
|
127
127
|
},
|
|
128
128
|
multiple: {
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
:class="{
|
|
29
29
|
'hidden': !(coreStore.config?.showBrandLogoInSidebar !== false && (!iconOnlySidebarEnabled || !isSidebarIconOnly || (isSidebarIconOnly && isSidebarHovering))) }"
|
|
30
30
|
/>
|
|
31
|
-
<img
|
|
31
|
+
<img :src="loadFile(coreStore.config?.iconOnlySidebar?.logo || '')" :alt="`${ coreStore.config?.brandName } Logo`" class="af-sidebar-icon-only-logo h-8" :class="{ 'hidden': !(coreStore.config?.showBrandLogoInSidebar !== false && coreStore.config?.iconOnlySidebar?.logo && iconOnlySidebarEnabled && isSidebarIconOnly && !isSidebarHovering) }" />
|
|
32
32
|
<span
|
|
33
33
|
v-if="coreStore.config?.showBrandNameInSidebar && (!iconOnlySidebarEnabled || !isSidebarIconOnly || (isSidebarIconOnly && isSidebarHovering))"
|
|
34
34
|
class="af-title self-center text-lightNavbarText-size font-semibold sm:text-lightNavbarText-size whitespace-nowrap dark:text-darkSidebarText text-lightSidebarText"
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
'hidden': !showDropdown,
|
|
19
19
|
'left-0 md:left-auto': checkboxes && checkboxes.length > 0
|
|
20
20
|
}"
|
|
21
|
-
class="absolute z-30 mt-3 bg-lightThreeDotsMenuBodyBackground divide-y divide-gray-100 rounded-lg shadow w-
|
|
21
|
+
class="absolute z-30 mt-3 bg-lightThreeDotsMenuBodyBackground divide-y divide-gray-100 rounded-lg shadow w-auto max-w-64 dark:bg-darkThreeDotsMenuBodyBackground dark:divide-gray-600 right-0">
|
|
22
22
|
<ul class="py-2 text-sm text-lightThreeDotsMenuBodyText dark:text-darkThreeDotsMenuBodyText" aria-labelledby="dropdownMenuIconButton">
|
|
23
23
|
<li v-for="(item, i) in threeDotsDropdownItems" :key="`dropdown-item-${i}`">
|
|
24
24
|
<div
|
|
@@ -117,7 +117,7 @@ import timezone from 'dayjs/plugin/timezone';
|
|
|
117
117
|
import {checkEmptyValues} from '@/utils';
|
|
118
118
|
import { useRoute, useRouter } from 'vue-router';
|
|
119
119
|
import { JsonViewer } from "vue3-json-viewer";
|
|
120
|
-
import "vue3-json-viewer/dist/
|
|
120
|
+
import "vue3-json-viewer/dist/index.css";
|
|
121
121
|
import type { AdminForthResourceColumnCommon } from '@/types/Common';
|
|
122
122
|
|
|
123
123
|
import { useCoreStore } from '@/stores/core';
|
|
@@ -92,7 +92,6 @@ export const useCoreStore = defineStore('core', () => {
|
|
|
92
92
|
|
|
93
93
|
// console.log('🔔 subscribeToMenuBadges', mi.badge, JSON.stringify(mi));
|
|
94
94
|
if (mi.badge !== undefined) {
|
|
95
|
-
websocket.unsubscribe(`/opentopic/update-menu-badge/${mi.itemId}`);
|
|
96
95
|
websocket.subscribe(`/opentopic/update-menu-badge/${mi.itemId}`, ({ badge }) => {
|
|
97
96
|
mi.badge = badge;
|
|
98
97
|
});
|
|
@@ -122,6 +121,8 @@ export const useCoreStore = defineStore('core', () => {
|
|
|
122
121
|
item.badge = badge;
|
|
123
122
|
}
|
|
124
123
|
});
|
|
124
|
+
// TODO: This thing was created for something. Find out why
|
|
125
|
+
// websocket.unsubscribeAll();
|
|
125
126
|
subscribeToMenuBadges();
|
|
126
127
|
|
|
127
128
|
}
|
|
@@ -192,7 +192,7 @@ export interface IAdminForthDataSourceConnector {
|
|
|
192
192
|
*
|
|
193
193
|
* @param resource
|
|
194
194
|
*/
|
|
195
|
-
discoverFields(resource: AdminForthResource): Promise<{[key: string]: AdminForthResourceColumn}>;
|
|
195
|
+
discoverFields(resource: AdminForthResource, config: AdminForthConfig): Promise<{[key: string]: AdminForthResourceColumn}>;
|
|
196
196
|
|
|
197
197
|
|
|
198
198
|
/**
|
|
@@ -1206,8 +1206,8 @@ interface AdminForthInputConfigCustomization {
|
|
|
1206
1206
|
*
|
|
1207
1207
|
* ```bashcreating rec
|
|
1208
1208
|
* cd custom
|
|
1209
|
-
*
|
|
1210
|
-
*
|
|
1209
|
+
* npm init -y
|
|
1210
|
+
* npm install highcharts highcharts-vue
|
|
1211
1211
|
* ```
|
|
1212
1212
|
*
|
|
1213
1213
|
* And specify vueUsesFile in AdminForth config:
|
|
@@ -2056,6 +2056,7 @@ export interface AdminForthForeignResource extends AdminForthForeignResourceComm
|
|
|
2056
2056
|
afterDatasourceResponse?: AfterDataSourceResponseFunction | Array<AfterDataSourceResponseFunction>,
|
|
2057
2057
|
},
|
|
2058
2058
|
},
|
|
2059
|
+
onDelete?: 'cascade' | 'setNull'
|
|
2059
2060
|
}
|
|
2060
2061
|
|
|
2061
2062
|
export type ShowInModernInput = {
|
|
@@ -361,12 +361,6 @@ export interface AdminForthResourceInputCommon {
|
|
|
361
361
|
recordLabel?: (item: any) => string,
|
|
362
362
|
|
|
363
363
|
|
|
364
|
-
/**
|
|
365
|
-
* If true, user will not see warning about unsaved changes when tries to leave edit or create page with unsaved changes.
|
|
366
|
-
* default is false
|
|
367
|
-
*/
|
|
368
|
-
dontShowWarningAboutUnsavedChanges?: boolean,
|
|
369
|
-
|
|
370
364
|
/**
|
|
371
365
|
* General options for resource.
|
|
372
366
|
*/
|
|
@@ -5,13 +5,13 @@ import router from "../router";
|
|
|
5
5
|
import { useCoreStore } from '../stores/core';
|
|
6
6
|
import { useUserStore } from '../stores/user';
|
|
7
7
|
import { Dropdown } from 'flowbite';
|
|
8
|
-
import adminforth
|
|
8
|
+
import adminforth from '../adminforth';
|
|
9
9
|
import sanitizeHtml from 'sanitize-html'
|
|
10
10
|
import debounce from 'debounce';
|
|
11
11
|
import type { AdminForthResourceColumnInputCommon, Predicate } from '@/types/Common';
|
|
12
12
|
import { i18nInstance } from '../i18n'
|
|
13
13
|
import { useI18n } from 'vue-i18n';
|
|
14
|
-
|
|
14
|
+
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
|
|
@@ -616,59 +616,4 @@ export function getTimeAgoString(date: Date): string {
|
|
|
616
616
|
const days = Math.floor(diffInSeconds / 86400);
|
|
617
617
|
return `${days} ${days === 1 ? 'day' : 'days'} ago`;
|
|
618
618
|
}
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
export class leaveGuardActiveClass {
|
|
622
|
-
private active = false;
|
|
623
|
-
|
|
624
|
-
isActive() {
|
|
625
|
-
return this.active;
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
setActive(value: boolean) {
|
|
629
|
-
this.active = value;
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
export async function onBeforeRouteLeaveCreateEditViewGuard(initialValues: any, record: any, checkIfWeCanLeavePage: () => boolean, leaveGuardActive: leaveGuardActiveClass, isActive: { value: boolean }): Promise<void> {
|
|
634
|
-
|
|
635
|
-
const { confirm } = useAdminforth();
|
|
636
|
-
const { t } = useI18n();
|
|
637
|
-
|
|
638
|
-
onBeforeRouteLeave(async (to, from) => {
|
|
639
|
-
if (!isActive.value) {
|
|
640
|
-
return true;
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
if (leaveGuardActive.isActive()) {
|
|
645
|
-
return false;
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
if (checkIfWeCanLeavePage()) {
|
|
649
|
-
return true;
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
leaveGuardActive.setActive(true);
|
|
653
|
-
|
|
654
|
-
try {
|
|
655
|
-
const { changedFields } = compareOldAndNewRecord(
|
|
656
|
-
initialValues.value,
|
|
657
|
-
record.value
|
|
658
|
-
);
|
|
659
|
-
|
|
660
|
-
const messageHtml =
|
|
661
|
-
generateMessageHtmlForRecordChange(changedFields, t);
|
|
662
|
-
|
|
663
|
-
const answer = await confirm({
|
|
664
|
-
messageHtml,
|
|
665
|
-
yes: t('Yes'),
|
|
666
|
-
no: t('No'),
|
|
667
|
-
});
|
|
668
|
-
|
|
669
|
-
return answer;
|
|
670
|
-
} finally {
|
|
671
|
-
leaveGuardActive.setActive(false);
|
|
672
|
-
}
|
|
673
|
-
});
|
|
674
619
|
}
|