Add WeatherAPI config page
This commit is contained in:
@@ -0,0 +1,24 @@
|
|||||||
|
# THIS IS AUTOGENERATED. DO NOT EDIT MANUALLY
|
||||||
|
version = 1
|
||||||
|
name = "pleno-vue"
|
||||||
|
|
||||||
|
[setup]
|
||||||
|
script = '''
|
||||||
|
npm ci
|
||||||
|
npx playwright install
|
||||||
|
'''
|
||||||
|
|
||||||
|
[[actions]]
|
||||||
|
name = "Run dev"
|
||||||
|
icon = "run"
|
||||||
|
command = "npm run dev"
|
||||||
|
|
||||||
|
[[actions]]
|
||||||
|
name = "Run all tests"
|
||||||
|
icon = "test"
|
||||||
|
command = "npm run test:all"
|
||||||
|
|
||||||
|
[[actions]]
|
||||||
|
name = "Run debug"
|
||||||
|
icon = "debug"
|
||||||
|
command = "npx playwright test --debug"
|
||||||
@@ -148,6 +148,13 @@ const menu_items = ref([
|
|||||||
children: [],
|
children: [],
|
||||||
hidden: false
|
hidden: false
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: SessionUser.superUser.modules.weatherapi.meta.title,
|
||||||
|
value: SessionUser.superUser.modules.weatherapi.meta.config_endpoint,
|
||||||
|
icon: SessionUser.superUser.modules.weatherapi.meta.icon,
|
||||||
|
children: [],
|
||||||
|
hidden: false
|
||||||
|
},
|
||||||
],
|
],
|
||||||
onSelect: async (value) => {
|
onSelect: async (value) => {
|
||||||
SessionUser.functions.redirectTo.superUser(value);
|
SessionUser.functions.redirectTo.superUser(value);
|
||||||
@@ -219,4 +226,4 @@ const selectDepartment = (department) => {
|
|||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ const items = computed<NavigationItemProps[]>(() => [
|
|||||||
{ label: firstToUpperCase(SessionUser.superUser.modules.motorapi.meta.labels.multiple), to: '/superuser/configuration/motorapi'},
|
{ label: firstToUpperCase(SessionUser.superUser.modules.motorapi.meta.labels.multiple), to: '/superuser/configuration/motorapi'},
|
||||||
{ label: firstToUpperCase(SessionUser.superUser.modules.stripe.meta.labels.multiple), to: '/superuser/configuration/stripe'},
|
{ label: firstToUpperCase(SessionUser.superUser.modules.stripe.meta.labels.multiple), to: '/superuser/configuration/stripe'},
|
||||||
{ label: firstToUpperCase(SessionUser.superUser.modules.fxratesapi.meta.labels.multiple), to: '/superuser/configuration/fxratesapi'},
|
{ label: firstToUpperCase(SessionUser.superUser.modules.fxratesapi.meta.labels.multiple), to: '/superuser/configuration/fxratesapi'},
|
||||||
|
{ label: firstToUpperCase(SessionUser.superUser.modules.weatherapi.meta.labels.multiple), to: '/superuser/configuration/weatherapi'},
|
||||||
{ label: firstToUpperCase(SessionUser.superUser.modules.gatewayapi.meta.labels.multiple), to: '/superuser/configuration/gatewayapi'},
|
{ label: firstToUpperCase(SessionUser.superUser.modules.gatewayapi.meta.labels.multiple), to: '/superuser/configuration/gatewayapi'},
|
||||||
{ label: firstToUpperCase(SessionUser.superUser.modules.entra.meta.labels.multiple), to: '/superuser/configuration/entra'},
|
{ label: firstToUpperCase(SessionUser.superUser.modules.entra.meta.labels.multiple), to: '/superuser/configuration/entra'},
|
||||||
{ label: firstToUpperCase(SessionUser.superUser.modules.limble.meta.labels.multiple), to: '/superuser/configuration/limble'},
|
{ label: firstToUpperCase(SessionUser.superUser.modules.limble.meta.labels.multiple), to: '/superuser/configuration/limble'},
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
<script>
|
||||||
|
import { authenticatedRequest } from "@/components/session/authenticatedRequest.vue";
|
||||||
|
import { handleEconomicError } from "@/components/request/HandleEconomicError.vue";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The WeatherAPI -> Config object
|
||||||
|
*/
|
||||||
|
export const Config = {
|
||||||
|
get: async (variable) => {
|
||||||
|
return authenticatedRequest(
|
||||||
|
"/weatherapi/config?variable=" + variable,
|
||||||
|
"GET"
|
||||||
|
);
|
||||||
|
},
|
||||||
|
get_all: async () => {
|
||||||
|
return authenticatedRequest(
|
||||||
|
"/weatherapi/config",
|
||||||
|
"GET"
|
||||||
|
);
|
||||||
|
},
|
||||||
|
set: async (variable, value) => {
|
||||||
|
return authenticatedRequest(
|
||||||
|
"/weatherapi/config",
|
||||||
|
"POST",
|
||||||
|
{
|
||||||
|
variable: variable,
|
||||||
|
value: value
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
keys: {
|
||||||
|
secret_key: {
|
||||||
|
get: async () => {
|
||||||
|
return Config.get("secret_key");
|
||||||
|
},
|
||||||
|
set: async (value) => {
|
||||||
|
return Config.set("secret_key", value);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
enabled: {
|
||||||
|
get: async () => {
|
||||||
|
return Config.get("enabled");
|
||||||
|
},
|
||||||
|
set: async (enabled) => {
|
||||||
|
return Config.set("enabled", enabled);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
<script>
|
||||||
|
import { authenticatedRequest } from "@/components/session/authenticatedRequest.vue";
|
||||||
|
import { handleEconomicError } from "@/components/request/HandleEconomicError.vue";
|
||||||
|
import { Config } from "@/components/session/token/superUser/modules/weatherapi/Config.vue";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The WeatherAPI object
|
||||||
|
*/
|
||||||
|
export const WeatherAPI = {
|
||||||
|
meta: {
|
||||||
|
title: "WeatherAPI",
|
||||||
|
icon: "fas fa-cloud-sun",
|
||||||
|
description: "The WeatherAPI integration",
|
||||||
|
endpoint: "/modules/weatherapi",
|
||||||
|
config_endpoint: "/configuration/weatherapi",
|
||||||
|
labels: {
|
||||||
|
single: "weatherapi",
|
||||||
|
multiple: "weatherapi",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
config: Config,
|
||||||
|
functions: {
|
||||||
|
current: async (query) => {
|
||||||
|
return authenticatedRequest(
|
||||||
|
"/modules/weatherapi/current?q=" + encodeURIComponent(query),
|
||||||
|
"GET"
|
||||||
|
);
|
||||||
|
},
|
||||||
|
forecast: async (query, days = null) => {
|
||||||
|
const daysParameter = Number.isInteger(days) ? "&days=" + days : "";
|
||||||
|
return authenticatedRequest(
|
||||||
|
"/modules/weatherapi/forecast?q=" + encodeURIComponent(query) + daysParameter,
|
||||||
|
"GET"
|
||||||
|
);
|
||||||
|
},
|
||||||
|
search: async (query) => {
|
||||||
|
return authenticatedRequest(
|
||||||
|
"/modules/weatherapi/search?q=" + encodeURIComponent(query),
|
||||||
|
"GET"
|
||||||
|
);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
</script>
|
||||||
@@ -10,6 +10,7 @@ import { Backups } from "@/components/session/token/superUser/modules/Backups/Ba
|
|||||||
import { MotorAPI } from "@/components/session/token/superUser/modules/motorapi/MotorAPI.vue";
|
import { MotorAPI } from "@/components/session/token/superUser/modules/motorapi/MotorAPI.vue";
|
||||||
import { Stripe } from "@/components/session/token/superUser/modules/stripe/Stripe.vue";
|
import { Stripe } from "@/components/session/token/superUser/modules/stripe/Stripe.vue";
|
||||||
import { FXRatesAPI } from "@/components/session/token/superUser/modules/fxratesapi/FXRatesAPI.vue";
|
import { FXRatesAPI } from "@/components/session/token/superUser/modules/fxratesapi/FXRatesAPI.vue";
|
||||||
|
import { WeatherAPI } from "@/components/session/token/superUser/modules/weatherapi/WeatherAPI.vue";
|
||||||
import { GatewayAPI } from "@/components/session/token/superUser/modules/gatewayapi/GatewayAPI.vue";
|
import { GatewayAPI } from "@/components/session/token/superUser/modules/gatewayapi/GatewayAPI.vue";
|
||||||
import { XLVask } from "@/components/session/token/superUser/modules/xlvask/XLVask.vue";
|
import { XLVask } from "@/components/session/token/superUser/modules/xlvask/XLVask.vue";
|
||||||
import { Entra } from "@/components/session/token/superUser/modules/entra/Entra.vue";
|
import { Entra } from "@/components/session/token/superUser/modules/entra/Entra.vue";
|
||||||
@@ -39,6 +40,7 @@ export const SuperUserObject = {
|
|||||||
motorapi: MotorAPI,
|
motorapi: MotorAPI,
|
||||||
stripe: Stripe,
|
stripe: Stripe,
|
||||||
fxratesapi: FXRatesAPI,
|
fxratesapi: FXRatesAPI,
|
||||||
|
weatherapi: WeatherAPI,
|
||||||
gatewayapi: GatewayAPI,
|
gatewayapi: GatewayAPI,
|
||||||
xlvask: XLVask,
|
xlvask: XLVask,
|
||||||
entra: Entra,
|
entra: Entra,
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ import GuestHome from "@/views/guest/GuestHome.vue";
|
|||||||
import GuestBookExteriorWash from "@/views/guest/book/GuestBookExteriorWash.vue";
|
import GuestBookExteriorWash from "@/views/guest/book/GuestBookExteriorWash.vue";
|
||||||
import DepartmentProfile from "@/views/dashboards/superUserDashboard/department/DepartmentProfile.vue";
|
import DepartmentProfile from "@/views/dashboards/superUserDashboard/department/DepartmentProfile.vue";
|
||||||
import ConfigurationFXRatesAPI from "@/views/dashboards/superUserDashboard/configuration/ConfigurationFXRatesAPI.vue";
|
import ConfigurationFXRatesAPI from "@/views/dashboards/superUserDashboard/configuration/ConfigurationFXRatesAPI.vue";
|
||||||
|
import ConfigurationWeatherAPI from "@/views/dashboards/superUserDashboard/configuration/ConfigurationWeatherAPI.vue";
|
||||||
import ConfigurationGatewayAPI from "@/views/dashboards/superUserDashboard/configuration/ConfigurationGatewayAPI.vue";
|
import ConfigurationGatewayAPI from "@/views/dashboards/superUserDashboard/configuration/ConfigurationGatewayAPI.vue";
|
||||||
import UserWashSubscriptions from "@/views/dashboards/superUserDashboard/user/UserWashSubscriptions.vue";
|
import UserWashSubscriptions from "@/views/dashboards/superUserDashboard/user/UserWashSubscriptions.vue";
|
||||||
import UserProfile from "@/views/dashboards/userDashboard/profile/UserProfile.vue";
|
import UserProfile from "@/views/dashboards/userDashboard/profile/UserProfile.vue";
|
||||||
@@ -778,6 +779,12 @@ export const router = createRouter({
|
|||||||
component: ConfigurationFXRatesAPI,
|
component: ConfigurationFXRatesAPI,
|
||||||
meta: { middleware: superUserMiddleware }
|
meta: { middleware: superUserMiddleware }
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'configurationWeatherAPI',
|
||||||
|
path: '/superuser/configuration/weatherapi',
|
||||||
|
component: ConfigurationWeatherAPI,
|
||||||
|
meta: { middleware: superUserMiddleware }
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'configurationGatewayAPI',
|
name: 'configurationGatewayAPI',
|
||||||
path: '/superuser/configuration/gatewayapi',
|
path: '/superuser/configuration/gatewayapi',
|
||||||
|
|||||||
@@ -0,0 +1,135 @@
|
|||||||
|
<script setup>
|
||||||
|
import PageTitle from "@/components/global/PageTitle.vue";
|
||||||
|
import RestrictedPageWrapper from "@/components/page/wrappers/RestrictedPageWrapper.vue";
|
||||||
|
import { SessionUser } from "@/components/session/token/SessionUser.vue";
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import ConfigurationSubPageWrapper
|
||||||
|
from "@/views/dashboards/superUserDashboard/configuration/ConfigurationSubPageWrapper.vue";
|
||||||
|
import ConfigurationCategory from "@/components/displays/superuser/configuration/ConfigurationCategory.vue";
|
||||||
|
import ConfigurationSwitch from "@/components/displays/superuser/configuration/ConfigurationSwitch.vue";
|
||||||
|
import ConfigurationSecretKey from "@/components/displays/superuser/configuration/ConfigurationSecretKey.vue";
|
||||||
|
import Swal from "sweetalert2";
|
||||||
|
|
||||||
|
const module_config = ref([]);
|
||||||
|
|
||||||
|
const getModuleConfig = async () => {
|
||||||
|
await SessionUser.superUser.modules.weatherapi.config.get_all().then((response) => {
|
||||||
|
const tmp_module_config = response.data.data;
|
||||||
|
const tmp_module_config_array = [];
|
||||||
|
for (const value of Object.values(tmp_module_config)) {
|
||||||
|
tmp_module_config_array.push({
|
||||||
|
variable: value.variable,
|
||||||
|
value: value.value,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
module_config.value = tmp_module_config_array;
|
||||||
|
}).catch((error) => {
|
||||||
|
console.log(error);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const getModuleConfigValue = (variable) => {
|
||||||
|
const config = module_config.value.find((entry) => entry.variable === variable);
|
||||||
|
return config ? config.value : '';
|
||||||
|
};
|
||||||
|
|
||||||
|
const load = async () => {
|
||||||
|
await getModuleConfig();
|
||||||
|
};
|
||||||
|
|
||||||
|
load();
|
||||||
|
|
||||||
|
const showCurrentWeather = () => {
|
||||||
|
Swal.fire({
|
||||||
|
title: "Lookup current weather",
|
||||||
|
input: "text",
|
||||||
|
inputValue: "Copenhagen",
|
||||||
|
inputLabel: "Location query",
|
||||||
|
inputPlaceholder: "e.g. Copenhagen, 10001, 55.6761,12.5683",
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonText: "Lookup",
|
||||||
|
showLoaderOnConfirm: true,
|
||||||
|
preConfirm: (query) => {
|
||||||
|
if (!query || query.trim() === "") {
|
||||||
|
Swal.showValidationMessage("A location query is required.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SessionUser.superUser.modules.weatherapi.functions.current(query.trim())
|
||||||
|
.then((response) => response.data.data)
|
||||||
|
.catch((error) => {
|
||||||
|
console.log(error);
|
||||||
|
Swal.showValidationMessage(`Request failed: ${error}`);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
allowOutsideClick: () => !Swal.isLoading()
|
||||||
|
}).then((result) => {
|
||||||
|
if (!result.isConfirmed || !result.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Swal.fire({
|
||||||
|
title: "Current weather result",
|
||||||
|
html: "<pre>" + JSON.stringify(result.value, null, 2) + "</pre>",
|
||||||
|
width: "50rem",
|
||||||
|
confirmButtonText: "Close",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<RestrictedPageWrapper :hasPermission="SessionUser.canAccessSuperUser()">
|
||||||
|
<ConfigurationSubPageWrapper>
|
||||||
|
<template #title>
|
||||||
|
<PageTitle title="WeatherAPI configuration" subtitle="Configuration of the WeatherAPI integration" />
|
||||||
|
</template>
|
||||||
|
<template v-if="module_config.length > 0" #content>
|
||||||
|
<ConfigurationCategory
|
||||||
|
class="mt-2"
|
||||||
|
module="WeatherAPI"
|
||||||
|
title="General settings"
|
||||||
|
description="General settings for the WeatherAPI integration."
|
||||||
|
icon="fas fa-cloud-sun"
|
||||||
|
>
|
||||||
|
<ConfigurationSwitch
|
||||||
|
class="mt-2"
|
||||||
|
module="WeatherAPI"
|
||||||
|
title="Enable WeatherAPI"
|
||||||
|
description="Enable or disable the WeatherAPI integration."
|
||||||
|
icon="fas fa-cloud-sun"
|
||||||
|
:value="getModuleConfigValue('enabled') === true"
|
||||||
|
:on-switch="SessionUser.superUser.modules.weatherapi.config.enabled.set"
|
||||||
|
/>
|
||||||
|
</ConfigurationCategory>
|
||||||
|
<ConfigurationCategory
|
||||||
|
class="mt-2"
|
||||||
|
module="WeatherAPI"
|
||||||
|
title="API connection settings"
|
||||||
|
description="The API connection settings used for WeatherAPI requests."
|
||||||
|
icon="fas fa-key"
|
||||||
|
>
|
||||||
|
<ConfigurationSecretKey
|
||||||
|
class="mt-2"
|
||||||
|
module="WeatherAPI"
|
||||||
|
title="Secret key (API key)"
|
||||||
|
description="The secret key used to authenticate requests to WeatherAPI."
|
||||||
|
icon="fas fa-key"
|
||||||
|
:isSet="getModuleConfigValue('secret_key') !== ''"
|
||||||
|
:on-save="SessionUser.superUser.modules.weatherapi.config.keys.secret_key.set"
|
||||||
|
/>
|
||||||
|
</ConfigurationCategory>
|
||||||
|
<button class="button is-dark" @click="showCurrentWeather">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fas fa-cloud-sun"></i>
|
||||||
|
</span>
|
||||||
|
<span>Test current weather lookup</span>
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
</ConfigurationSubPageWrapper>
|
||||||
|
</RestrictedPageWrapper>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
+2
-1
@@ -15,6 +15,7 @@ const tabs = [
|
|||||||
{ name: 'MotorAPI', path: '/superuser/configuration/motorapi' },
|
{ name: 'MotorAPI', path: '/superuser/configuration/motorapi' },
|
||||||
{ name: 'Stripe', path: '/superuser/configuration/stripe' },
|
{ name: 'Stripe', path: '/superuser/configuration/stripe' },
|
||||||
{ name: 'FXRatesAPI', path: '/superuser/configuration/fxratesapi' },
|
{ name: 'FXRatesAPI', path: '/superuser/configuration/fxratesapi' },
|
||||||
|
{ name: 'WeatherAPI', path: '/superuser/configuration/weatherapi' },
|
||||||
{ name: 'GatewayAPI', path: '/superuser/configuration/gatewayapi' },
|
{ name: 'GatewayAPI', path: '/superuser/configuration/gatewayapi' },
|
||||||
{ name: 'XLVask', path: '/superuser/configuration/xlvask' },
|
{ name: 'XLVask', path: '/superuser/configuration/xlvask' },
|
||||||
{ name: 'Entra', path: '/superuser/configuration/entra'},
|
{ name: 'Entra', path: '/superuser/configuration/entra'},
|
||||||
@@ -53,4 +54,4 @@ const changeTab = (index) => {
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user