Merge pull request #1750 from freqtrade/fix/useToast_broken

Fix broken use toast after bootstrap-vue-next update
This commit is contained in:
Matthias 2024-02-11 09:49:06 +01:00 committed by GitHub
commit de16c50baf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 119 additions and 83 deletions

View File

@ -22,7 +22,7 @@
"@vueuse/integrations": "^10.7.2", "@vueuse/integrations": "^10.7.2",
"axios": "^1.6.7", "axios": "^1.6.7",
"bootstrap": "^5.3.2", "bootstrap": "^5.3.2",
"bootstrap-vue-next": "^0.15.5", "bootstrap-vue-next": "^0.16.1",
"core-js": "^3.35.1", "core-js": "^3.35.1",
"date-fns": "^2.30.0", "date-fns": "^2.30.0",
"date-fns-tz": "^2.0.0", "date-fns-tz": "^2.0.0",

View File

@ -1,7 +1,7 @@
<template> <template>
<div id="app" class="d-flex flex-column dvh-100" :style="colorStore.cssVars"> <div id="app" class="d-flex flex-column dvh-100" :style="colorStore.cssVars">
<NavBar /> <NavBar />
<BToaster></BToaster> <BaseAlert></BaseAlert>
<BodyLayout class="flex-fill overflow-auto" /> <BodyLayout class="flex-fill overflow-auto" />
<NavFooter /> <NavFooter />
</div> </div>

View File

@ -115,6 +115,7 @@ declare global {
const unrefElement: typeof import('@vueuse/core')['unrefElement'] const unrefElement: typeof import('@vueuse/core')['unrefElement']
const until: typeof import('@vueuse/core')['until'] const until: typeof import('@vueuse/core')['until']
const useActiveElement: typeof import('@vueuse/core')['useActiveElement'] const useActiveElement: typeof import('@vueuse/core')['useActiveElement']
const useAlertsStore: typeof import('./stores/alertsStore')['useAlertsStore']
const useAnimate: typeof import('@vueuse/core')['useAnimate'] const useAnimate: typeof import('@vueuse/core')['useAnimate']
const useArrayDifference: typeof import('@vueuse/core')['useArrayDifference'] const useArrayDifference: typeof import('@vueuse/core')['useArrayDifference']
const useArrayEvery: typeof import('@vueuse/core')['useArrayEvery'] const useArrayEvery: typeof import('@vueuse/core')['useArrayEvery']
@ -421,6 +422,7 @@ declare module 'vue' {
readonly unrefElement: UnwrapRef<typeof import('@vueuse/core')['unrefElement']> readonly unrefElement: UnwrapRef<typeof import('@vueuse/core')['unrefElement']>
readonly until: UnwrapRef<typeof import('@vueuse/core')['until']> readonly until: UnwrapRef<typeof import('@vueuse/core')['until']>
readonly useActiveElement: UnwrapRef<typeof import('@vueuse/core')['useActiveElement']> readonly useActiveElement: UnwrapRef<typeof import('@vueuse/core')['useActiveElement']>
readonly useAlertsStore: UnwrapRef<typeof import('./stores/alertsStore')['useAlertsStore']>
readonly useAnimate: UnwrapRef<typeof import('@vueuse/core')['useAnimate']> readonly useAnimate: UnwrapRef<typeof import('@vueuse/core')['useAnimate']>
readonly useArrayDifference: UnwrapRef<typeof import('@vueuse/core')['useArrayDifference']> readonly useArrayDifference: UnwrapRef<typeof import('@vueuse/core')['useArrayDifference']>
readonly useArrayEvery: UnwrapRef<typeof import('@vueuse/core')['useArrayEvery']> readonly useArrayEvery: UnwrapRef<typeof import('@vueuse/core')['useArrayEvery']>
@ -719,6 +721,7 @@ declare module '@vue/runtime-core' {
readonly unrefElement: UnwrapRef<typeof import('@vueuse/core')['unrefElement']> readonly unrefElement: UnwrapRef<typeof import('@vueuse/core')['unrefElement']>
readonly until: UnwrapRef<typeof import('@vueuse/core')['until']> readonly until: UnwrapRef<typeof import('@vueuse/core')['until']>
readonly useActiveElement: UnwrapRef<typeof import('@vueuse/core')['useActiveElement']> readonly useActiveElement: UnwrapRef<typeof import('@vueuse/core')['useActiveElement']>
readonly useAlertsStore: UnwrapRef<typeof import('./stores/alertsStore')['useAlertsStore']>
readonly useAnimate: UnwrapRef<typeof import('@vueuse/core')['useAnimate']> readonly useAnimate: UnwrapRef<typeof import('@vueuse/core')['useAnimate']>
readonly useArrayDifference: UnwrapRef<typeof import('@vueuse/core')['useArrayDifference']> readonly useArrayDifference: UnwrapRef<typeof import('@vueuse/core')['useArrayDifference']>
readonly useArrayEvery: UnwrapRef<typeof import('@vueuse/core')['useArrayEvery']> readonly useArrayEvery: UnwrapRef<typeof import('@vueuse/core')['useArrayEvery']>

View File

@ -20,7 +20,7 @@
v-model="auth.url" v-model="auth.url"
required required
trim trim
:state="urlState === '' ? null : urlState" :state="urlState"
@keydown.enter="handleOk" @keydown.enter="handleOk"
></b-form-input> ></b-form-input>
<b-alert <b-alert
@ -43,7 +43,7 @@
v-model="auth.username" v-model="auth.username"
required required
placeholder="Freqtrader" placeholder="Freqtrader"
:state="nameState === '' ? null : nameState" :state="nameState"
@keydown.enter="handleOk" @keydown.enter="handleOk"
></b-form-input> ></b-form-input>
</b-form-group> </b-form-group>
@ -58,7 +58,7 @@
v-model="auth.password" v-model="auth.password"
required required
type="password" type="password"
:state="pwdState === '' ? null : pwdState" :state="pwdState"
@keydown.enter="handleOk" @keydown.enter="handleOk"
></b-form-input> ></b-form-input>
</b-form-group> </b-form-group>
@ -102,9 +102,9 @@ const router = useRouter();
const route = useRoute(); const route = useRoute();
const botStore = useBotStore(); const botStore = useBotStore();
const nameState = ref<boolean | ''>(''); const nameState = ref<boolean>();
const pwdState = ref<boolean | ''>(''); const pwdState = ref<boolean>();
const urlState = ref<boolean | ''>(''); const urlState = ref<boolean>();
const errorMessage = ref<string>(''); const errorMessage = ref<string>('');
const errorMessageCORS = ref<boolean>(false); const errorMessageCORS = ref<boolean>(false);
const formRef = ref<HTMLFormElement>(); const formRef = ref<HTMLFormElement>();
@ -138,9 +138,9 @@ const resetLogin = () => {
auth.value.url = defaultURL; auth.value.url = defaultURL;
auth.value.username = ''; auth.value.username = '';
auth.value.password = ''; auth.value.password = '';
nameState.value = ''; nameState.value = undefined;
pwdState.value = ''; pwdState.value = undefined;
urlState.value = ''; urlState.value = undefined;
errorMessage.value = ''; errorMessage.value = '';
botEdit.value = false; botEdit.value = false;
}; };

View File

@ -9,12 +9,12 @@
autofocus autofocus
/> />
<div class="d-flex ms-2"> <div class="d-flex ms-2 no-min-w">
<b-button type="submit" size="sm" title="Save"> <b-button type="submit" size="sm" title="Save" class="no-min-w">
<i-mdi-check /> <i-mdi-check />
</b-button> </b-button>
<b-button class="ms-1" size="sm" title="Cancel" @click="$emit('cancelled')"> <b-button class="ms-1 no-min-w" size="sm" title="Cancel" @click="$emit('cancelled')">
<i-mdi-close /> <i-mdi-close />
</b-button> </b-button>
</div> </div>

View File

@ -66,7 +66,13 @@ const settingsStore = useSettingsStore();
// registerTransform(ecStat.transform.histogram); // registerTransform(ecStat.transform.histogram);
// console.log(profits); // console.log(profits);
// const data = [[]]; // const data = [[]];
const binOptions = [10, 15, 20, 25, 50]; const binOptions = [
{ text: '10', value: 10 },
{ text: '15', value: 15 },
{ text: '20', value: 20 },
{ text: '25', value: 25 },
{ text: '50', value: 50 },
];
const data = computed(() => { const data = computed(() => {
const profits = props.trades.map((trade) => trade.profit_ratio); const profits = props.trades.map((trade) => trade.profit_ratio);

View File

@ -15,11 +15,9 @@
:disabled="tradeModes.length < 2" :disabled="tradeModes.length < 2"
> >
</b-form-select> </b-form-select>
<div class="ms-2"> <b-button class="ms-2 no-min-w" size="sm" @click="botStore.activeBot.getExchangeList">
<b-button size="sm" @click="botStore.activeBot.getExchangeList"> <i-mdi-refresh />
<i-mdi-refresh /> </b-button>
</b-button>
</div>
</div> </div>
</template> </template>
@ -56,7 +54,7 @@ const tradeModesTyped = computed(() => {
return val ?? []; return val ?? [];
}); });
const tradeModes = computed<Record<string, unknown>[]>(() => { const tradeModes = computed(() => {
return tradeModesTyped.value.map((tm) => { return tradeModesTyped.value.map((tm) => {
return ( return (
{ {
@ -64,7 +62,7 @@ const tradeModes = computed<Record<string, unknown>[]>(() => {
value: tm, value: tm,
} ?? [] } ?? []
); );
}) as Record<string, unknown>[]; });
}); });
watch( watch(

View File

@ -0,0 +1,21 @@
<script setup lang="ts">
const alertStore = useAlertsStore();
</script>
<template>
<teleport to="body">
<div class="toast-container position-fixed p-3 top-0 mt-5 end-0">
<BToast
v-for="(alert, idx) in alertStore.activeMessages"
:key="idx"
v-model="alert.timeout"
:variant="alert.severity"
:title="alert.title"
@hide.prevent="alertStore.removeAlert(alert)"
>
{{ alert.message }}
</BToast>
</div>
</teleport>
</template>
<style lang="scss" scoped></style>

View File

@ -3,7 +3,7 @@ import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
import App from './App.vue'; import App from './App.vue';
// Eensure Bootstrap css still loads // Eensure Bootstrap css still loads
import './plugins/bootstrap-vue'; import { createBootstrap } from './plugins/bootstrap-vue';
import { VueDraggableGrid } from './plugins/vue-grid-layout'; import { VueDraggableGrid } from './plugins/vue-grid-layout';
import router from './router'; import router from './router';
@ -13,6 +13,7 @@ myApp.use(PiniaVuePlugin);
const pinia = createPinia(); const pinia = createPinia();
pinia.use(piniaPluginPersistedstate); pinia.use(piniaPluginPersistedstate);
myApp.use(pinia); myApp.use(pinia);
myApp.use(createBootstrap());
myApp.use(router); myApp.use(router);
myApp.use(VueDraggableGrid); myApp.use(VueDraggableGrid);

View File

@ -2,3 +2,5 @@ import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap-vue-next/dist/bootstrap-vue-next.css'; import 'bootstrap-vue-next/dist/bootstrap-vue-next.css';
import '@/styles/main.scss'; import '@/styles/main.scss';
export { createBootstrap } from 'bootstrap-vue-next';

View File

@ -1,10 +1,14 @@
import { AlertSeverity } from '@/types/alertTypes'; import { AlertSeverity } from '@/types/alertTypes';
import { useToast } from 'bootstrap-vue-next';
export function showAlert(message: string, severity: AlertSeverity = 'warning', bot: string = '') { export function showAlert(message: string, severity: AlertSeverity = 'warning', bot: string = '') {
const { show } = useToast(); const alertStore = useAlertsStore();
show(message, { title: `${bot ? 'Bot: ' + bot : 'Notification'}`, variant: severity }); alertStore.addAlert({
message,
title: `${bot ? 'Bot: ' + bot : 'Notification'}`,
severity,
timeout: 60000,
});
} }
export function useAlertForBot(botName: string) { export function useAlertForBot(botName: string) {

16
src/stores/alertsStore.ts Normal file
View File

@ -0,0 +1,16 @@
import { defineStore } from 'pinia';
import { AlertType } from '@/types/alertTypes';
export const useAlertsStore = defineStore('alerts', {
state: () => {
return { activeMessages: [] as AlertType[] };
},
actions: {
addAlert(message: AlertType) {
this.activeMessages.push(message);
},
removeAlert(alert: AlertType) {
this.activeMessages = this.activeMessages.filter((v) => v !== alert);
},
},
});

View File

@ -17,6 +17,11 @@
height: 100dvh; height: 100dvh;
} }
.no-min-w {
// Remove min-width
min-width: unset;
}
.logo-svg { .logo-svg {
background-color: #000000; background-color: #000000;
@ -273,7 +278,6 @@
&.text-bg-warning { &.text-bg-warning {
--toast-bg-color: rgb(41, 39, 1) !important; --toast-bg-color: rgb(41, 39, 1) !important;
--toast-bg-color-header: rgb(29, 27, 1) !important; --toast-bg-color-header: rgb(29, 27, 1) !important;
// background-color: rgb(41, 39, 1) !important;
color: rgb(255, 218, 106) !important; color: rgb(255, 218, 106) !important;
} }
@ -283,6 +287,13 @@
--toast-bg-color-header: rgb(3, 19, 12) !important; --toast-bg-color-header: rgb(3, 19, 12) !important;
color: rgb(118, 183, 152) !important; color: rgb(118, 183, 152) !important;
} }
&.text-bg-info {
--toast-bg-color: rgb(13, 63, 104)!important;
--toast-bg-color-header: rgb(9, 39, 65) !important;
color: rgb(116, 188, 252) !important;
}
} }
.vue-grid-item>.vue-resizable-handle { .vue-grid-item>.vue-resizable-handle {
// Stupid workaround to have the Shevron actually show. // Stupid workaround to have the Shevron actually show.

View File

@ -2,6 +2,7 @@ export type AlertSeverity = 'danger' | 'warning' | 'info' | 'success';
export interface AlertType { export interface AlertType {
message: string; message: string;
title: string;
severity: AlertSeverity; severity: AlertSeverity;
timeout: number; timeout: number;
} }

View File

@ -371,39 +371,40 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@floating-ui/core@npm:^1.4.2": "@floating-ui/core@npm:^1.6.0":
version: 1.5.0 version: 1.6.0
resolution: "@floating-ui/core@npm:1.5.0" resolution: "@floating-ui/core@npm:1.6.0"
dependencies: dependencies:
"@floating-ui/utils": ^0.1.3 "@floating-ui/utils": ^0.2.1
checksum: 54b4fe26b3c228746ac5589f97303abf158b80aa5f8b99027259decd68d1c2030c4c637648ebd33dfe78a4212699453bc2bd7537fd5a594d3bd3e63d362f666f checksum: 2e25c53b0c124c5c9577972f8ae21d081f2f7895e6695836a53074463e8c65b47722744d6d2b5a993164936da006a268bcfe87fe68fd24dc235b1cb86bed3127
languageName: node languageName: node
linkType: hard linkType: hard
"@floating-ui/dom@npm:^1.4.5": "@floating-ui/dom@npm:^1.6.1":
version: 1.5.3 version: 1.6.1
resolution: "@floating-ui/dom@npm:1.5.3" resolution: "@floating-ui/dom@npm:1.6.1"
dependencies: dependencies:
"@floating-ui/core": ^1.4.2 "@floating-ui/core": ^1.6.0
"@floating-ui/utils": ^0.1.3 "@floating-ui/utils": ^0.2.1
checksum: 00053742064aac70957f0bd5c1542caafb3bfe9716588bfe1d409fef72a67ed5e60450d08eb492a77f78c22ed1ce4f7955873cc72bf9f9caf2b0f43ae3561c21 checksum: 5565e4dee612bab62950913c311d75d3f773bd1d9dc437f7e33b46340f32ec565733c995c6185381adaf64e627df3c79901d0a9d555f58c02509d0764bceb57d
languageName: node languageName: node
linkType: hard linkType: hard
"@floating-ui/utils@npm:^0.1.3": "@floating-ui/utils@npm:^0.2.1":
version: 0.1.6 version: 0.2.1
resolution: "@floating-ui/utils@npm:0.1.6" resolution: "@floating-ui/utils@npm:0.2.1"
checksum: b34d4b5470869727f52e312e08272edef985ba5a450a76de0917ba0a9c6f5df2bdbeb99448e2c60f39b177fb8981c772ff1831424e75123471a27ebd5b52c1eb checksum: 9ed4380653c7c217cd6f66ae51f20fdce433730dbc77f95b5abfb5a808f5fdb029c6ae249b4e0490a816f2453aa6e586d9a873cd157fdba4690f65628efc6e06
languageName: node languageName: node
linkType: hard linkType: hard
"@floating-ui/vue@npm:^1.0.2": "@floating-ui/vue@npm:^1.0.4":
version: 1.0.2 version: 1.0.6
resolution: "@floating-ui/vue@npm:1.0.2" resolution: "@floating-ui/vue@npm:1.0.6"
dependencies: dependencies:
"@floating-ui/dom": ^1.4.5 "@floating-ui/dom": ^1.6.1
"@floating-ui/utils": ^0.2.1
vue-demi: ">=0.13.0" vue-demi: ">=0.13.0"
checksum: bf206a354a0a452a450350f38e48d5223f5331169ee62e7b479dd0b0d87b81172fa5ad9508f98f5e74fbbb1b8834a0b44d72757f90a2718d7c7372cbd5a72193 checksum: 6cd5c6acc676cab06b157f16a5ce7a6552f7477e6b9b4849c07d54029f775e797066a41be07b14fe0e3f6c37968b66e19b4afe9b833e46f0569276d1a834cc7c
languageName: node languageName: node
linkType: hard linkType: hard
@ -1775,18 +1776,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@vueuse/core@npm:^10.6.0":
version: 10.6.1
resolution: "@vueuse/core@npm:10.6.1"
dependencies:
"@types/web-bluetooth": ^0.0.20
"@vueuse/metadata": 10.6.1
"@vueuse/shared": 10.6.1
vue-demi: ">=0.14.6"
checksum: 13b892a32fbf99a32947f7a7ff8014525ca1ceb937663b0d6c5ef811eceb7857138c2c3710c2aa9d21dda7a1cdacb1f0faf9f6e38efefb03c2bae4997d13dcc4
languageName: node
linkType: hard
"@vueuse/integrations@npm:^10.7.2": "@vueuse/integrations@npm:^10.7.2":
version: 10.7.2 version: 10.7.2
resolution: "@vueuse/integrations@npm:10.7.2" resolution: "@vueuse/integrations@npm:10.7.2"
@ -1836,13 +1825,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@vueuse/metadata@npm:10.6.1":
version: 10.6.1
resolution: "@vueuse/metadata@npm:10.6.1"
checksum: 5739e5ebfd6e377bf50116ee0a5ee11ec97d62adf7336456fe1db2d6712d7fd7c4fcce04f7821494fa17424eca5cd17b38ed89a0b4b4625448dcce7ee9541a65
languageName: node
linkType: hard
"@vueuse/metadata@npm:10.7.2": "@vueuse/metadata@npm:10.7.2":
version: 10.7.2 version: 10.7.2
resolution: "@vueuse/metadata@npm:10.7.2" resolution: "@vueuse/metadata@npm:10.7.2"
@ -1850,15 +1832,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@vueuse/shared@npm:10.6.1":
version: 10.6.1
resolution: "@vueuse/shared@npm:10.6.1"
dependencies:
vue-demi: ">=0.14.6"
checksum: 1e2fb9b0ce5092003d45042776adaeaa0094f209b864d43879496c69a51c2ab9b0c88cdf838fe9a65417f148867ad95f1bdf33b69f815ddcdb6bd9a1a8a80fb3
languageName: node
linkType: hard
"@vueuse/shared@npm:10.7.2": "@vueuse/shared@npm:10.7.2":
version: 10.7.2 version: 10.7.2
resolution: "@vueuse/shared@npm:10.7.2" resolution: "@vueuse/shared@npm:10.7.2"
@ -2165,15 +2138,15 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"bootstrap-vue-next@npm:^0.15.5": "bootstrap-vue-next@npm:^0.16.1":
version: 0.15.5 version: 0.16.1
resolution: "bootstrap-vue-next@npm:0.15.5" resolution: "bootstrap-vue-next@npm:0.16.1"
dependencies: dependencies:
"@floating-ui/vue": ^1.0.2 "@floating-ui/vue": ^1.0.4
"@vueuse/core": ^10.6.0 "@vueuse/core": ^10.7.2
peerDependencies: peerDependencies:
vue: ^3.3.8 vue: ^3.4.14
checksum: f2a631fe023426bd3b6179945f7267a55ec9647056304cb8056e8f5406f67461f634ebb755bcd7adff6f5e8750261605bc025592822a6f1e48088faf7ce7621c checksum: 688c35cdec342ff4a82514badc0054f8a6c0700af75da2e7a8550587988c627f047d0795609584939011b9e7831828f3f7535b17260ee71e6252679a08c972c5
languageName: node languageName: node
linkType: hard linkType: hard
@ -3554,7 +3527,7 @@ __metadata:
"@vueuse/integrations": ^10.7.2 "@vueuse/integrations": ^10.7.2
axios: ^1.6.7 axios: ^1.6.7
bootstrap: ^5.3.2 bootstrap: ^5.3.2
bootstrap-vue-next: ^0.15.5 bootstrap-vue-next: ^0.16.1
core-js: ^3.35.1 core-js: ^3.35.1
cypress: ^13.6.4 cypress: ^13.6.4
date-fns: ^2.30.0 date-fns: ^2.30.0