adminforth 2.70.0-next.5 → 2.71.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.
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
:class="{
|
|
8
8
|
'cursor-default opacity-50 pointer-events-none': props.disabled,
|
|
9
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-white/60':
|
|
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-white/60': props.mode === 'secondary',
|
|
11
11
|
}"
|
|
12
12
|
>
|
|
13
13
|
<Spinner v-if="props.loader" class="w-4 h-4 text-lightButtonsText dark:text-darkButtonsText fill-lightButtonsBackground dark:fill-darkPrimary" />
|
|
@@ -17,22 +17,17 @@
|
|
|
17
17
|
|
|
18
18
|
<script setup lang="ts">
|
|
19
19
|
import { Spinner } from '@/afcl';
|
|
20
|
-
import { computed } from 'vue';
|
|
21
20
|
|
|
22
21
|
const props = withDefaults(defineProps<{
|
|
23
22
|
loader?: boolean;
|
|
24
23
|
disabled?: boolean;
|
|
25
24
|
active?: boolean;
|
|
26
|
-
variant?: 'primary' | 'secondary';
|
|
27
|
-
/** @deprecated use variant instead of mode */
|
|
28
25
|
mode?: 'primary' | 'secondary';
|
|
29
26
|
}>(), {
|
|
30
27
|
loader: false,
|
|
31
28
|
disabled: false,
|
|
32
29
|
active: false,
|
|
30
|
+
mode: 'primary'
|
|
33
31
|
});
|
|
34
32
|
|
|
35
|
-
// mode is deprecated, but we still want to support it for backward compatibility,
|
|
36
|
-
// so we check both variant and mode props
|
|
37
|
-
const currentVariant = computed(() => props.variant ?? props.mode ?? 'primary');
|
|
38
33
|
</script>
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
:closeByClickOutside="clickToCloseOutside || closeByClickOutside"
|
|
6
6
|
:closeByEsc="closeByEsc || closable"
|
|
7
7
|
:beforeCloseFunction="beforeCloseFunction"
|
|
8
|
-
:beforeCancelFunction="beforeCancelFunction"
|
|
9
8
|
:beforeOpenFunction="beforeOpenFunction"
|
|
10
9
|
:askForCloseConfirmation="askForCloseConfirmation"
|
|
11
10
|
:closeConfirmationText="closeConfirmationText"
|
|
@@ -27,7 +26,7 @@
|
|
|
27
26
|
v-if="headerCloseButton"
|
|
28
27
|
type="button"
|
|
29
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"
|
|
30
|
-
@click="
|
|
29
|
+
@click="tryToHideModal"
|
|
31
30
|
>
|
|
32
31
|
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14">
|
|
33
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"/>
|
|
@@ -119,15 +118,10 @@ function close() {
|
|
|
119
118
|
modalRef.value.close();
|
|
120
119
|
}
|
|
121
120
|
|
|
122
|
-
function tryToCancelModal() {
|
|
123
|
-
modalRef.value?.cancel();
|
|
124
|
-
}
|
|
125
|
-
|
|
126
121
|
defineExpose({
|
|
127
122
|
open: open,
|
|
128
123
|
close: close,
|
|
129
124
|
tryToHideModal: tryToHideModal,
|
|
130
|
-
tryToCancelModal: tryToCancelModal,
|
|
131
125
|
})
|
|
132
126
|
|
|
133
127
|
function tryToHideModal() {
|
|
@@ -177,11 +171,6 @@ interface DialogProps {
|
|
|
177
171
|
*/
|
|
178
172
|
beforeOpenFunction?: (() => void | Promise<void>) | null
|
|
179
173
|
|
|
180
|
-
/**
|
|
181
|
-
* Function that will be called before the dialog is canceled.
|
|
182
|
-
*/
|
|
183
|
-
beforeCancelFunction?: (() => void | Promise<void | boolean>) | null
|
|
184
|
-
|
|
185
174
|
/**
|
|
186
175
|
* Disables close on Ecs button
|
|
187
176
|
*
|
|
@@ -212,21 +201,19 @@ interface DialogProps {
|
|
|
212
201
|
|
|
213
202
|
/********** for the backward compatibility ***************/
|
|
214
203
|
class Dialog implements IDialogInsideButtonClickHandler {
|
|
215
|
-
hide: (
|
|
216
|
-
constructor(
|
|
217
|
-
this.hide =
|
|
204
|
+
hide: () => void
|
|
205
|
+
constructor( hide: () => void ) {
|
|
206
|
+
this.hide = hide;
|
|
218
207
|
}
|
|
219
208
|
}
|
|
220
209
|
const dialog: Ref<Dialog> = ref(
|
|
221
|
-
new Dialog(
|
|
222
|
-
|
|
223
|
-
if (
|
|
224
|
-
|
|
225
|
-
} else {
|
|
226
|
-
modalRef.value?.close();
|
|
210
|
+
new Dialog(
|
|
211
|
+
() => {
|
|
212
|
+
if (dialog.value) {
|
|
213
|
+
tryToHideModal();
|
|
227
214
|
}
|
|
228
215
|
}
|
|
229
|
-
|
|
216
|
+
)
|
|
230
217
|
);
|
|
231
218
|
/*************************************************************/
|
|
232
219
|
|
|
@@ -70,7 +70,6 @@ interface DialogProps {
|
|
|
70
70
|
closeByEsc?: boolean
|
|
71
71
|
beforeCloseFunction?: (() => void | Promise<void | boolean>) | null
|
|
72
72
|
beforeOpenFunction?: (() => void | Promise<void>) | null
|
|
73
|
-
beforeCancelFunction?: (() => void | Promise<void | boolean>) | null
|
|
74
73
|
askForCloseConfirmation?: boolean
|
|
75
74
|
closeConfirmationText?: string
|
|
76
75
|
removeFromDomOnClose?: boolean
|
|
@@ -83,7 +82,6 @@ const props = withDefaults(defineProps<DialogProps>(), {
|
|
|
83
82
|
closeByEsc: true,
|
|
84
83
|
beforeCloseFunction: null,
|
|
85
84
|
beforeOpenFunction: null,
|
|
86
|
-
beforeCancelFunction: null,
|
|
87
85
|
askForCloseConfirmation: false,
|
|
88
86
|
closeConfirmationText: 'Are you sure you want to close this dialog?',
|
|
89
87
|
removeFromDomOnClose: false,
|
|
@@ -111,14 +109,6 @@ async function close() {
|
|
|
111
109
|
isModalOpen.value = false;
|
|
112
110
|
}
|
|
113
111
|
|
|
114
|
-
async function cancel() {
|
|
115
|
-
if (props.beforeCancelFunction) {
|
|
116
|
-
const shouldCancel = await props.beforeCancelFunction?.();
|
|
117
|
-
if (shouldCancel === false) return;
|
|
118
|
-
}
|
|
119
|
-
isModalOpen.value = false;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
112
|
defineOptions({
|
|
123
113
|
inheritAttrs: false,
|
|
124
114
|
})
|
|
@@ -126,17 +116,12 @@ defineOptions({
|
|
|
126
116
|
defineExpose({
|
|
127
117
|
open: open,
|
|
128
118
|
close: close,
|
|
129
|
-
cancel: cancel,
|
|
130
119
|
tryToHideModal: tryToHideModal,
|
|
131
120
|
})
|
|
132
121
|
|
|
133
|
-
function tryToHideModal(
|
|
134
|
-
if (!props.askForCloseConfirmation) {
|
|
135
|
-
|
|
136
|
-
cancel();
|
|
137
|
-
} else {
|
|
138
|
-
close();
|
|
139
|
-
}
|
|
122
|
+
function tryToHideModal() {
|
|
123
|
+
if (!props.askForCloseConfirmation ) {
|
|
124
|
+
close();
|
|
140
125
|
} else {
|
|
141
126
|
showConfirmationOnClose.value = true;
|
|
142
127
|
}
|
|
@@ -151,8 +136,10 @@ function toggleModal() {
|
|
|
151
136
|
}
|
|
152
137
|
|
|
153
138
|
function onEsc(event: KeyboardEvent) {
|
|
154
|
-
if (event.key === 'Escape'
|
|
155
|
-
|
|
139
|
+
if (event.key === 'Escape') {
|
|
140
|
+
if (props.closeByEsc) {
|
|
141
|
+
tryToHideModal();
|
|
142
|
+
}
|
|
156
143
|
}
|
|
157
144
|
}
|
|
158
145
|
|
|
@@ -167,7 +154,7 @@ onUnmounted(() => {
|
|
|
167
154
|
|
|
168
155
|
function backdropClick(e: MouseEvent) {
|
|
169
156
|
if (props.closeByClickOutside && e.target === e.currentTarget) {
|
|
170
|
-
tryToHideModal(
|
|
157
|
+
tryToHideModal();
|
|
171
158
|
}
|
|
172
159
|
}
|
|
173
160
|
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
@click="()=>{checkboxes = []}"
|
|
36
36
|
v-if="checkboxes.length"
|
|
37
37
|
data-tooltip-target="tooltip-remove-all"
|
|
38
|
-
class="flex gap-1 items-center py-1 px-3 text-sm font-medium text-lightListViewButtonText af-button-shadow
|
|
38
|
+
class="flex gap-1 items-center py-1 px-3 me-2 text-sm font-medium text-lightListViewButtonText af-button-shadow
|
|
39
39
|
focus:outline-none bg-lightListViewButtonBackground rounded border border-lightListViewButtonBorder h-[2.125rem]
|
|
40
40
|
hover:bg-lightListViewButtonBackgroundHover hover:text-lightListViewButtonTextHover focus:z-10 focus:ring-4
|
|
41
41
|
focus:ring-lightListViewButtonFocusRing dark:focus:ring-darkListViewButtonFocusRing
|
|
@@ -125,7 +125,7 @@
|
|
|
125
125
|
</RouterLink>
|
|
126
126
|
|
|
127
127
|
<button
|
|
128
|
-
class="af-filter-button flex gap-1 items-center py-1 h-[2.125rem] px-3 af-button-shadow text-sm font-medium
|
|
128
|
+
class="af-filter-button flex gap-1 items-center py-1 h-[2.125rem] px-3 me-2 af-button-shadow text-sm font-medium
|
|
129
129
|
text-lightListViewButtonText transition-all focus:outline-none bg-lightListViewButtonBackground rounded border
|
|
130
130
|
border-lightListViewButtonBorder hover:bg-lightListViewButtonBackgroundHover hover:text-lightListViewButtonTextHover
|
|
131
131
|
focus:z-10 focus:ring-4 focus:ring-lightListViewButtonFocusRing dark:focus:ring-darkListViewButtonFocusRing
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
|
|
2
|
-
|
|
2
|
+
type WebsocketCallback = (data: any) => void;
|
|
3
|
+
type Unsubscribe = () => void;
|
|
4
|
+
type Subscription = {
|
|
5
|
+
id: number;
|
|
6
|
+
callback: WebsocketCallback;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const subscriptions: { [topic: string]: Subscription[] } = {};
|
|
10
|
+
let nextSubscriptionId = 1;
|
|
3
11
|
|
|
4
12
|
interface ExtendedWebSocket extends WebSocket {
|
|
5
13
|
connected?: boolean;
|
|
@@ -65,8 +73,8 @@ async function connect () {
|
|
|
65
73
|
const topic = message.topic;
|
|
66
74
|
const data = message.data;
|
|
67
75
|
if (subscriptions[topic]) {
|
|
68
|
-
for (const
|
|
69
|
-
callback(data);
|
|
76
|
+
for (const subscription of subscriptions[topic]) {
|
|
77
|
+
subscription.callback(data);
|
|
70
78
|
}
|
|
71
79
|
}
|
|
72
80
|
}
|
|
@@ -104,19 +112,49 @@ setInterval(() => {
|
|
|
104
112
|
}, 10_000);
|
|
105
113
|
|
|
106
114
|
|
|
115
|
+
function unsubscribeSubscription(topic: string, subscriptionId: number): void {
|
|
116
|
+
if (!subscriptions[topic]) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
subscriptions[topic] = subscriptions[topic].filter((subscription) => subscription.id !== subscriptionId);
|
|
121
|
+
if (subscriptions[topic].length > 0) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
delete subscriptions[topic];
|
|
126
|
+
if (state.status === 'connected') {
|
|
127
|
+
doPhysicalUnsubscribe(topic);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
107
131
|
export default {
|
|
108
|
-
subscribe(topic: string, callback:
|
|
132
|
+
subscribe(topic: string, callback: WebsocketCallback): Unsubscribe {
|
|
109
133
|
const isFirstSubscription = !subscriptions[topic];
|
|
110
134
|
if (!subscriptions[topic]) {
|
|
111
135
|
subscriptions[topic] = [];
|
|
112
136
|
}
|
|
113
|
-
|
|
137
|
+
const subscriptionId = nextSubscriptionId++;
|
|
138
|
+
subscriptions[topic].push({
|
|
139
|
+
id: subscriptionId,
|
|
140
|
+
callback,
|
|
141
|
+
});
|
|
114
142
|
if (isFirstSubscription && state.status === 'connected') {
|
|
115
143
|
doPhysicalSubscribe(topic);
|
|
116
144
|
}
|
|
145
|
+
|
|
146
|
+
let isSubscribed = true;
|
|
147
|
+
return () => {
|
|
148
|
+
if (!isSubscribed) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
isSubscribed = false;
|
|
152
|
+
unsubscribeSubscription(topic, subscriptionId);
|
|
153
|
+
};
|
|
117
154
|
},
|
|
118
155
|
|
|
119
156
|
unsubscribe(topic: string): void {
|
|
157
|
+
console.warn('This method is deprecated because it removes all subscriptions for the topic. Use the unsubscribe function returned by subscribe(), or use unsubscribeByPrefix() when you explicitly need to unsubscribe by topic prefix.');
|
|
120
158
|
if (!subscriptions[topic]) {
|
|
121
159
|
return;
|
|
122
160
|
}
|
|
@@ -146,4 +184,4 @@ export default {
|
|
|
146
184
|
});
|
|
147
185
|
}
|
|
148
186
|
|
|
149
|
-
}
|
|
187
|
+
}
|