How to set up admin settings in plugin

Don’t see why this isn’t all automatically set up when you create a plugin but anyhow…

I have a boolean contained in settings single-type in the root of my project which I’d like to move into a settings page of my plugin.

import React, { useEffect, useState } from 'react';

import notificationRequests from '../../api/notifications';

import { LoadingIndicatorPage, useNotification } from '@strapi/helper-plugin';

import { Box } from '@strapi/design-system/Box';
import { Stack } from '@strapi/design-system/Stack';
import { Button } from '@strapi/design-system/Button';
import { Grid, GridItem } from '@strapi/design-system/Grid';
import { HeaderLayout } from '@strapi/design-system/Layout';
import { ContentLayout } from '@strapi/design-system/Layout';
import { Typography } from '@strapi/design-system/Typography';
import { ToggleInput } from '@strapi/design-system/ToggleInput';

import Check from '@strapi/icons/Check';

const Settings = () => {
    const [settings, setSettings] = useState();
    const [isSaving, setIsSaving] = useState(false);
    const [isLoading, setIsLoading] = useState(true);
    const toggleNotification = useNotification();
  
    useEffect(() => {
    notificationRequests.getSettings().then(res => {
        console.log("HEHEHEH")
        setSettings(res.data.settings);
        setIsLoading(false);
      });
    }, [setSettings]);
  
    const handleSubmit = async () => {
      setIsSaving(true);
      const res = await notificationRequests.setSettings(settings);
      setSettings(res.data.settings);
      setIsSaving(false);
      toggleNotification({
        type: 'success',
        message: 'Settings successfully updated',
      });
    }
return (
    <>
      {isLoading ? (
        <LoadingIndicatorPage />
      ) : (
        <Typography as="h1" variant="alpha">
          Notification Plugin Homepage
        </Typography>
      )}
    </>
)
};
export default Settings;    ```

<i>This topic has been created from a Discord post (1283465834227826739) to give it more visibility.
It will be on Read-Only mode here.
<a href="https://discord.com/channels/811989166782021633/1283465834227826739/1283465834227826739">Join the conversation on Discord</a></i>
import axios from 'axios';

const notificationRequests = {

  getSettings: async () => {
    console.log("hello")
    return await axios.get(`/api/notifications-morph/settings`);
  },
  setSettings: async data => {
    return await axios.post(`/api/notifications-morph/settings`, data);
  },
};
export default notificationRequests;```
``` // server/routes/index.js
...
    {
      method: 'GET',
      path: '/notifications-plugin/settings',
      handler: 'settings.get',
      config: {
        policies: [],
      },
    },
    {
      method: 'POST',
      path: '/notifications-plugin/settings',
      handler: 'settings.update',
      config: {
        policies: [],
      },
    },```
```// server/controllers/settings.js
module.exports = {
    async get(ctx) {{
        const settings = await strapi.plugins['notifications-morph'].services.settings.find();
        ctx.send({ settings });
    }},
    
    async update(ctx) {{
        const settings = await strapi.plugins['notifications-morph'].services.settings.update(ctx.request.body);
        ctx.send({ settings });
    }},
};```

The AI says services should be like this? But im confused about when these fields appeared in the DB? If this is the approach? I have to add calls here every time I add a new button or field to settings?

Surprised you can’t just set up settings page using the content-type-builder tbh


const { createCoreService } = require('@strapi/strapi').factories;

module.exports = createCoreService('api::notifications.notifications', ({ strapi }) => ({
  async getSettings() {
    // Fetch the settings from the database...
    // This is just a placeholder. You'll need to replace this with your actual implementation.
    const settings = await strapi.query('settings', 'notifications').find();
    return settings;
  },

  async updateSettings(data) {
    // Update the settings in the database...
    // This is just a placeholder. You'll need to replace this with your actual implementation.
    const updatedSettings = await strapi.query('settings', 'notifications').update({ id: data.id }, data);
    return updatedSettings;
  },
}));```

The code you are doing looks pretty accurate. (FYI you can use the js) for color highlights

I’m not sure I understand your question about field and DB ?

in the plugin when you export a content-type Strapi will read it and generate the DB structure for it automatically.

Re: “github code hilight”. Is this just for readmes on Github or something else?

So I should set up a content-type for settings which stores all the options I add under the settings page?

→ You can add the langauge name (js) to the backquotes to add colors in discord (like in github) . Making things easier to read :smile:

→ You have 2 options

  • Create your own content-type for the settings
  • Use the core-store that store them (this is much simpler but less flexible)
 await strapi.store.set({
  type: 'plugin',
  name: 'pluginName',
  key: 'settings',
  value: settingsObject,
});


await strapi.store.get({
  type: 'plugin',
  name: 'pluginName',
  key: 'settings',
})

the value will be stored as json in the DB

Ah ok, I did try that but with javascript rather than js. I’ll know for the future :).

Ok I think I’ve applied that and ironed out some issues with my routes.

One thing that’s still an issue is I cannot see my plugin in the users and roles permissions page?

Also I was wondering if there was a reason that the settings page is not generated when you initially generate a plugin? This has taken quite a lot of work and digging to get set up and surely seems like something that most custom plugins might want to make use of

A lot of plugins are configured via files instead of the interface so we don’t provide a default settings setup but that is an interesting idea for a plugin example repo maybe.

For the permissions what are you looking for ?

If you can’t see your plugin in users permission, it is because you need to define in as a content api route api.video-strapi-plugin/src/server/routes/index.ts at main · apivideo/api.video-strapi-plugin · GitHub

Thanks. I have permissions for my plugin showing up, by setting its type as illustrated.

I’m still getting a 401 error when visiting the settings page of my plugin

    routes: [
      //  SETTINGS
      {
        method: 'GET',
        path: '/settings',
        handler: 'settings.get',
        config: {
          policies: [],
        },
      },
      {
        method: 'POST',
        path: '/settings',
        handler: 'settings.update',
        config: {
          policies: [],
        },
      }
    ],
  }```

I’ve put a console log in the get controller of settings and i can be sure its not reaching there

401 means its hitting the route correctly but is not authorised

I’ve tried adding a bootstrapi.js file as suggested by the AI

    const actions = [
      {
        section: 'plugins',
        displayName: 'Access Settings',
        uid: 'settings.read',
        pluginName: 'notifications-plugin',
      },
      {
        section: 'plugins',
        displayName: 'Update Settings',
        uid: 'settings.update',
        pluginName: 'notifications-plugin',
      },
    ];
  
    await strapi.admin.services.permission.actionProvider.registerMany(actions);
  };