feat: Add a section in admin SettingsView to manage external links
Related to #1764
This commit is contained in:
@@ -200,6 +200,11 @@ export const ADMIN_SETTINGS_FRAGMENT = gql`
|
|||||||
instanceLongDescription
|
instanceLongDescription
|
||||||
instanceSlogan
|
instanceSlogan
|
||||||
contact
|
contact
|
||||||
|
externalUrls {
|
||||||
|
label
|
||||||
|
url
|
||||||
|
enabled
|
||||||
|
}
|
||||||
instanceLogo {
|
instanceLogo {
|
||||||
uuid
|
uuid
|
||||||
url
|
url
|
||||||
@@ -246,6 +251,7 @@ export const SAVE_ADMIN_SETTINGS = gql`
|
|||||||
$instanceLongDescription: String
|
$instanceLongDescription: String
|
||||||
$instanceSlogan: String
|
$instanceSlogan: String
|
||||||
$contact: String
|
$contact: String
|
||||||
|
$externalUrls: [ExternalUrlInput]
|
||||||
$instanceLogo: MediaInput
|
$instanceLogo: MediaInput
|
||||||
$instanceFavicon: MediaInput
|
$instanceFavicon: MediaInput
|
||||||
$defaultPicture: MediaInput
|
$defaultPicture: MediaInput
|
||||||
@@ -268,6 +274,7 @@ export const SAVE_ADMIN_SETTINGS = gql`
|
|||||||
instanceLongDescription: $instanceLongDescription
|
instanceLongDescription: $instanceLongDescription
|
||||||
instanceSlogan: $instanceSlogan
|
instanceSlogan: $instanceSlogan
|
||||||
contact: $contact
|
contact: $contact
|
||||||
|
externalUrls: $externalUrls
|
||||||
instanceLogo: $instanceLogo
|
instanceLogo: $instanceLogo
|
||||||
instanceFavicon: $instanceFavicon
|
instanceFavicon: $instanceFavicon
|
||||||
defaultPicture: $defaultPicture
|
defaultPicture: $defaultPicture
|
||||||
|
|||||||
@@ -84,6 +84,7 @@
|
|||||||
"Add / Remove\u2026": "Add / Remove\u2026",
|
"Add / Remove\u2026": "Add / Remove\u2026",
|
||||||
"Add a contact": "Add a contact",
|
"Add a contact": "Add a contact",
|
||||||
"Add a new post": "Add a new post",
|
"Add a new post": "Add a new post",
|
||||||
|
"Add a new link": "Add a new link",
|
||||||
"Add a note": "Add a note",
|
"Add a note": "Add a note",
|
||||||
"Add a recipient": "Add a recipient",
|
"Add a recipient": "Add a recipient",
|
||||||
"Add a todo": "Add a todo",
|
"Add a todo": "Add a todo",
|
||||||
@@ -345,6 +346,7 @@
|
|||||||
"Delete this discussion": "Delete this discussion",
|
"Delete this discussion": "Delete this discussion",
|
||||||
"Delete this identity": "Delete this identity",
|
"Delete this identity": "Delete this identity",
|
||||||
"Delete your identity": "Delete your identity",
|
"Delete your identity": "Delete your identity",
|
||||||
|
"Delete this link": "Delete this link",
|
||||||
"Delete {eventTitle}": "Delete {eventTitle}",
|
"Delete {eventTitle}": "Delete {eventTitle}",
|
||||||
"Delete {preferredUsername}": "Delete {preferredUsername}",
|
"Delete {preferredUsername}": "Delete {preferredUsername}",
|
||||||
"Deleting comment": "Deleting comment",
|
"Deleting comment": "Deleting comment",
|
||||||
@@ -453,6 +455,7 @@
|
|||||||
"Explore events": "Explore events",
|
"Explore events": "Explore events",
|
||||||
"Explore!": "Explore!",
|
"Explore!": "Explore!",
|
||||||
"Export": "Export",
|
"Export": "Export",
|
||||||
|
"External links":"External links",
|
||||||
"External provider URL": "External provider URL",
|
"External provider URL": "External provider URL",
|
||||||
"External registration": "External registration",
|
"External registration": "External registration",
|
||||||
"Failed to get location.": "Failed to get location.",
|
"Failed to get location.": "Failed to get location.",
|
||||||
@@ -1283,6 +1286,7 @@
|
|||||||
"This profile is from another instance, the informations shown here may be incomplete.": "This profile is from another instance, the informations shown here may be incomplete.",
|
"This profile is from another instance, the informations shown here may be incomplete.": "This profile is from another instance, the informations shown here may be incomplete.",
|
||||||
"This profile is located on this instance, so you need to {access_the_corresponding_account} to suspend it.": "This profile is located on this instance, so you need to {access_the_corresponding_account} to suspend it.",
|
"This profile is located on this instance, so you need to {access_the_corresponding_account} to suspend it.": "This profile is located on this instance, so you need to {access_the_corresponding_account} to suspend it.",
|
||||||
"This profile was not found": "This profile was not found",
|
"This profile was not found": "This profile was not found",
|
||||||
|
"This section lets you add links to external websites to the menu.":"This section lets you add links to external websites to the menu.",
|
||||||
"This setting will be used to display the website and send you emails in the correct language.": "This setting will be used to display the website and send you emails in the correct language.",
|
"This setting will be used to display the website and send you emails in the correct language.": "This setting will be used to display the website and send you emails in the correct language.",
|
||||||
"This user doesn't have any profiles": "This user doesn't have any profiles",
|
"This user doesn't have any profiles": "This user doesn't have any profiles",
|
||||||
"This user was not found": "This user was not found",
|
"This user was not found": "This user was not found",
|
||||||
|
|||||||
@@ -47,6 +47,7 @@
|
|||||||
"Add an instance": "Ajouter une instance",
|
"Add an instance": "Ajouter une instance",
|
||||||
"Add a contact": "Ajouter un contact",
|
"Add a contact": "Ajouter un contact",
|
||||||
"Add a new post": "Ajouter un nouveau billet",
|
"Add a new post": "Ajouter un nouveau billet",
|
||||||
|
"Add a new link": "Ajouter un nouveau lien",
|
||||||
"Add a note": "Ajouter une note",
|
"Add a note": "Ajouter une note",
|
||||||
"Add a recipient": "Ajouter un·e destinataire",
|
"Add a recipient": "Ajouter un·e destinataire",
|
||||||
"Add a todo": "Ajouter un todo",
|
"Add a todo": "Ajouter un todo",
|
||||||
@@ -337,6 +338,7 @@
|
|||||||
"Delete this conversation": "Supprimer cette conversation",
|
"Delete this conversation": "Supprimer cette conversation",
|
||||||
"Delete this discussion": "Supprimer cette discussion",
|
"Delete this discussion": "Supprimer cette discussion",
|
||||||
"Delete this identity": "Supprimer cette identité",
|
"Delete this identity": "Supprimer cette identité",
|
||||||
|
"Delete this link": "Supprimer ce lien",
|
||||||
"Delete your identity": "Supprimer votre identité",
|
"Delete your identity": "Supprimer votre identité",
|
||||||
"Delete {eventTitle}": "Supprimer {eventTitle}",
|
"Delete {eventTitle}": "Supprimer {eventTitle}",
|
||||||
"Delete {preferredUsername}": "Supprimer {preferredUsername}",
|
"Delete {preferredUsername}": "Supprimer {preferredUsername}",
|
||||||
@@ -448,6 +450,7 @@
|
|||||||
"Explore!": "Explorer !",
|
"Explore!": "Explorer !",
|
||||||
"Explore": "Explorer",
|
"Explore": "Explorer",
|
||||||
"Export": "Export",
|
"Export": "Export",
|
||||||
|
"External links":"Liens externes",
|
||||||
"External provider URL": "URL du fournisseur externe",
|
"External provider URL": "URL du fournisseur externe",
|
||||||
"External registration": "Inscription externe",
|
"External registration": "Inscription externe",
|
||||||
"Ex: mobilizon.fr": "Ex : mobilizon.fr",
|
"Ex: mobilizon.fr": "Ex : mobilizon.fr",
|
||||||
@@ -1289,6 +1292,7 @@
|
|||||||
"This profile is from another instance, the informations shown here may be incomplete.": "Ce profil provient d'une autre instance, les informations montrées ici peuvent être incomplètes.",
|
"This profile is from another instance, the informations shown here may be incomplete.": "Ce profil provient d'une autre instance, les informations montrées ici peuvent être incomplètes.",
|
||||||
"This profile is located on this instance, so you need to {access_the_corresponding_account} to suspend it.": "Ce profil se situe sur cette instance, vous devez donc {access_the_corresponding_account} afin de le suspendre.",
|
"This profile is located on this instance, so you need to {access_the_corresponding_account} to suspend it.": "Ce profil se situe sur cette instance, vous devez donc {access_the_corresponding_account} afin de le suspendre.",
|
||||||
"This profile was not found": "Ce profil n'a pas été trouvé",
|
"This profile was not found": "Ce profil n'a pas été trouvé",
|
||||||
|
"This section lets you add links to external websites to the menu.": "Cette section vous permet d'ajouter des liens vers des sites internets externes au menu.",
|
||||||
"This setting will be used to display the website and send you emails in the correct language.": "Ce paramètre sera utilisé pour l'affichage du site et pour vous envoyer des courriels dans la bonne langue.",
|
"This setting will be used to display the website and send you emails in the correct language.": "Ce paramètre sera utilisé pour l'affichage du site et pour vous envoyer des courriels dans la bonne langue.",
|
||||||
"This URL doesn't seem to be valid": "Cette URL ne semble pas être valide",
|
"This URL doesn't seem to be valid": "Cette URL ne semble pas être valide",
|
||||||
"This URL is not supported": "Cette URL n'est pas supportée",
|
"This URL is not supported": "Cette URL n'est pas supportée",
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ export interface IAdminSettings {
|
|||||||
contact: string;
|
contact: string;
|
||||||
instanceLogo: IMedia | null;
|
instanceLogo: IMedia | null;
|
||||||
instanceFavicon: IMedia | null;
|
instanceFavicon: IMedia | null;
|
||||||
|
externalUrls: { url: string; label: string; enabled: boolean }[];
|
||||||
defaultPicture: IMedia | null;
|
defaultPicture: IMedia | null;
|
||||||
primaryColor: string;
|
primaryColor: string;
|
||||||
secondaryColor: string;
|
secondaryColor: string;
|
||||||
|
|||||||
@@ -458,6 +458,47 @@
|
|||||||
</o-field>
|
</o-field>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section class="mt-4 mb-4 p-4 border rounded shadow-sm bg-white">
|
||||||
|
<h2>{{ t("External links") }}</h2>
|
||||||
|
<small>
|
||||||
|
{{
|
||||||
|
t(
|
||||||
|
"This section lets you add links to external websites to the menu."
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
</small>
|
||||||
|
<o-field>
|
||||||
|
<o-button :label="t('Add a new link')" @click="addLink" />
|
||||||
|
</o-field>
|
||||||
|
<div
|
||||||
|
class="mt-5 grid lg:grid-cols-[repeat(auto-fit,minmax(250px,0.5fr))] grid-cols-[repeat(auto-fit,minmax(250px,1fr))] gap-2"
|
||||||
|
v-if="settingsToWrite.externalUrls.length > 0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="bg-mbz-yellow-alt-100 p-5"
|
||||||
|
v-for="(link, index) in settingsToWrite.externalUrls"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<o-field :label="t('URL')" class="!mt-0"
|
||||||
|
><o-input expanded v-model="link.url" type="text"
|
||||||
|
/></o-field>
|
||||||
|
|
||||||
|
<o-field :label="t('Label')"
|
||||||
|
><o-input expanded v-model="link.label" type="text"
|
||||||
|
/></o-field>
|
||||||
|
|
||||||
|
<o-field
|
||||||
|
><o-checkbox v-model="link.enabled" :label="t('Enabled')"
|
||||||
|
/></o-field>
|
||||||
|
<o-field>
|
||||||
|
<o-button
|
||||||
|
:label="t('Delete this link')"
|
||||||
|
variant="danger"
|
||||||
|
@click="deleteLink(index)"
|
||||||
|
/></o-field>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
<o-button native-type="submit" variant="primary">{{
|
<o-button native-type="submit" variant="primary">{{
|
||||||
t("Save instance settings")
|
t("Save instance settings")
|
||||||
}}</o-button>
|
}}</o-button>
|
||||||
@@ -479,7 +520,7 @@ import {
|
|||||||
import { IAdminSettings, ILanguage } from "@/types/admin.model";
|
import { IAdminSettings, ILanguage } from "@/types/admin.model";
|
||||||
import RouteName from "@/router/name";
|
import RouteName from "@/router/name";
|
||||||
import { useMutation, useQuery } from "@vue/apollo-composable";
|
import { useMutation, useQuery } from "@vue/apollo-composable";
|
||||||
import { ref, computed, watch, inject } from "vue";
|
import { ref, computed, watch, inject, toRaw } from "vue";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import { useHead } from "@/utils/head";
|
import { useHead } from "@/utils/head";
|
||||||
import type { Notifier } from "@/plugins/notifier";
|
import type { Notifier } from "@/plugins/notifier";
|
||||||
@@ -515,6 +556,7 @@ const defaultAdminSettings: IAdminSettings = {
|
|||||||
registrationsOpen: false,
|
registrationsOpen: false,
|
||||||
registrationsModeration: false,
|
registrationsModeration: false,
|
||||||
instanceLanguages: [],
|
instanceLanguages: [],
|
||||||
|
externalUrls: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
const { onResult: onAdminSettingsResult } = useQuery<{
|
const { onResult: onAdminSettingsResult } = useQuery<{
|
||||||
@@ -556,9 +598,25 @@ useHead({
|
|||||||
const settingsToWrite = ref<IAdminSettings>(defaultAdminSettings);
|
const settingsToWrite = ref<IAdminSettings>(defaultAdminSettings);
|
||||||
|
|
||||||
watch(adminSettings, () => {
|
watch(adminSettings, () => {
|
||||||
settingsToWrite.value = { ...adminSettings.value };
|
// We need to use structuredClone to clone deep properties of adminSettings (like externalUrls)
|
||||||
|
// {... } only shadow clone, so externalUrls is not reactive doing this
|
||||||
|
if (adminSettings.value) {
|
||||||
|
settingsToWrite.value = structuredClone(toRaw(adminSettings.value));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const addLink = () => {
|
||||||
|
settingsToWrite.value.externalUrls.push({
|
||||||
|
url: "",
|
||||||
|
label: "",
|
||||||
|
enabled: false,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteLink = (index: number) => {
|
||||||
|
settingsToWrite.value.externalUrls.splice(index, 1);
|
||||||
|
};
|
||||||
|
|
||||||
const filteredLanguages = ref<string[]>([]);
|
const filteredLanguages = ref<string[]>([]);
|
||||||
|
|
||||||
const registrationsMode = computed({
|
const registrationsMode = computed({
|
||||||
@@ -614,14 +672,15 @@ const {
|
|||||||
onDone: saveAdminSettingsDone,
|
onDone: saveAdminSettingsDone,
|
||||||
onError: saveAdminSettingsError,
|
onError: saveAdminSettingsError,
|
||||||
} = useMutation(SAVE_ADMIN_SETTINGS, () => ({
|
} = useMutation(SAVE_ADMIN_SETTINGS, () => ({
|
||||||
// We need to update the cache because we just changed admin settings
|
|
||||||
// We want to update the related query ADMIN_SETTINGS
|
|
||||||
update(cache, { data }) {
|
update(cache, { data }) {
|
||||||
if (!data?.saveAdminSettings) {
|
if (!data?.saveAdminSettings) {
|
||||||
console.error("can't acces new admin settings");
|
console.error("can't acces new admin settings");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We need to update the cache because we just changed admin settings
|
||||||
|
// We want to update the related query ADMIN_SETTINGS
|
||||||
|
// Usefull if we comeback to this page
|
||||||
cache.writeQuery({
|
cache.writeQuery({
|
||||||
query: ADMIN_SETTINGS,
|
query: ADMIN_SETTINGS,
|
||||||
data: { adminSettings: data?.saveAdminSettings },
|
data: { adminSettings: data?.saveAdminSettings },
|
||||||
|
|||||||
Reference in New Issue
Block a user