Difference between revisions of "Editing Admin Pages"

From SocialStack
Line 1: Line 1:
The administration panel in SocialStack is just a set of pages as well meaning they are editable in [[Editing pages|the same way as your frontend]]. These pages are primarily automatically generated by the modules in your project through the [[Installing Admin Pages|InstallAdminPages]] call which is provided by default and commented out in the *Service.cs file by the [[Generate|generate command]]. However, there are occasionally times when you're creating a reusable module where you would like your module to manipulate the administration panel page automatically, such as extend it or entirely replace it with something custom. There are a few ways you can do this.
The administration panel in SocialStack is just a set of pages as well meaning they are editable in [[Editing pages|the same way as your frontend]] and you can create them directly as well. The only thing required of an admin panel page is its URL starts with /en-admin/. These pages are primarily automatically generated by the modules in your project through the [[Installing Admin Pages|InstallAdminPages]] call which is provided by default and commented out in the *Service.cs file by the [[Generate|generate command]]. However, there are occasionally times when you're creating a reusable module where you would like your module to manipulate the administration panel page automatically, such as extend it or entirely replace it with something custom. There are a few ways you can do this.
 
= Components an admin panel page can use =
 
To avoid bloating the frontend of a site with components that only admins will use, SocialStack splits components in to 3 groups:
 
* Email: email only components.
* UI: frontend only components.
* Admin: admin only components.
 
Simply put, an admin panel page can use all of them. You can make a page purely out of email group components if you wanted. This is because the underlying HTML generator for /en-admin/* pages specifically adds a js script tag for all 3 groups; if you view source on an en-admin page, you'll see the 3 main.js links there.


= Installing some other page =
= Installing some other page =

Revision as of 15:24, 17 November 2022

The administration panel in SocialStack is just a set of pages as well meaning they are editable in the same way as your frontend and you can create them directly as well. The only thing required of an admin panel page is its URL starts with /en-admin/. These pages are primarily automatically generated by the modules in your project through the InstallAdminPages call which is provided by default and commented out in the *Service.cs file by the generate command. However, there are occasionally times when you're creating a reusable module where you would like your module to manipulate the administration panel page automatically, such as extend it or entirely replace it with something custom. There are a few ways you can do this.

Components an admin panel page can use

To avoid bloating the frontend of a site with components that only admins will use, SocialStack splits components in to 3 groups:

  • Email: email only components.
  • UI: frontend only components.
  • Admin: admin only components.

Simply put, an admin panel page can use all of them. You can make a page purely out of email group components if you wanted. This is because the underlying HTML generator for /en-admin/* pages specifically adds a js script tag for all 3 groups; if you view source on an en-admin page, you'll see the 3 main.js links there.

Installing some other page

You can leave the default InstallAdminPages commented out and instead create pages directly. This is done via calling Install on the PageService, typically in the Events.Service.AfterStart event handler. For the page to be treated as part of the admin panel, all it needs is a URL that starts with /en-admin/ - aside from that its content is whatever you need it to be:


// Inside your services constructor, for a service which would like to install pages.
// You can either inject PageService and use it, or more typically, use AfterStart:

Events.Service.AfterStart.AddEventListener((Context context, object sender) => {

    // This route is suggested rather than dependency injection
    // Because some projects (particularly fully headless and micro instances) don't have a page service installed.
    var pageService = Services.Get<PageService>();

    pageService.Install(
		new Page()
		{
			Url = "/en-admin/custom-page/",
			Title = "My custom admin panel page",
			BodyJson = @"{
							""t"": ""Admin/Layouts/Default"",
							""c"": ""Hello world! This is the content of a new admin panel page. Use Admin/Tile to get one or more tiles in your layout.""
						}"
		});

    return new ValueTask<object>(sender);
});

Injecting JSON into the default page

Alternatively you can manipulate the JSON of the default admin panel pages. This is how, for example, the password reset module injects a "generate link" tile onto the user edit page. In order to allow multiple extensions to manipulate the same page (and again the user edit page is likely to be popular for this kind of extension), the API represents the about-to-be-created page with an in memory structure of the JSON which you can manipulate as needed. That manipulation is done by the Events.Page.BeforeAdminPageInstall event.

Events.Page.BeforeAdminPageInstall.AddEventListener((Context context, Pages.Page page, CanvasRenderer.CanvasNode canvas, Type contentType, AdminPageType pageType) =>
{
		if (contentType == typeof(User) && pageType == AdminPageType.Single)
		{
			// Installing user admin page for a particular user.
			// Add the reset box into the user admin page (as a child of the autoform):
			var tile = new CanvasNode("Admin/Tile");
			tile.AppendChild(new CanvasNode("Admin/PasswordResetButton").With("userId", new {
					name = "user.id",
					type = "urlToken"
			}));
					
			canvas.AppendChild(
				tile
			);
		}

		return new ValueTask<Pages.Page>(page);
});

You could of course just straight swap the whole JSON with something else but doing so would be unfriendly towards other extensions so do try to keep others in mind by generally keeping a consistent structure.