Skip to content

Commit

Permalink
Frontend fixes (#231)
Browse files Browse the repository at this point in the history
* Temp

* Fixes editors.

* Reuse hooks.
  • Loading branch information
SebastianStehle committed Apr 5, 2024
1 parent 1196e5f commit b2fd7b5
Show file tree
Hide file tree
Showing 54 changed files with 1,323 additions and 413 deletions.
2 changes: 1 addition & 1 deletion backend/src/Notifo.Domain/Liquid/LiquidApp.cs
Expand Up @@ -19,6 +19,6 @@ public sealed class LiquidApp(App app)
public static void Describe(LiquidProperties properties)
{
properties.AddString("name",
"The name of the app.");
"The name of the app. Cannot be null or undefined.");
}
}
13 changes: 8 additions & 5 deletions backend/src/Notifo.Domain/Liquid/LiquidNotificationBase.cs
Expand Up @@ -52,18 +52,21 @@ public abstract class LiquidNotificationBase
protected static void DescribeBase(LiquidProperties properties)
{
properties.AddString("subject",
"The notification subject.");
"The notification subject. Cannot be null or undefined.");

properties.AddString("body",
"The notification body. Can be null.");
"The notification body. Can be null or undefined.");

properties.AddString("linkUrl",
"The link URL. Can be null.");
"The link URL. Can be null or undefined.");

properties.AddString("linkText",
"The link text that can be set when a linkUrl is set. Can be null or undefined.");

properties.AddString("imageSmall",
"The URL to the small image. Optimized for the current use case (e.g. emails). Can be null.");
"The URL to the small image. Optimized for the current use case (e.g. emails). Can be null or undefined.");

properties.AddString("imageLarge",
"The URL to the large image. Optimized for the current use case (e.g. emails). Can be null.");
"The URL to the large image. Optimized for the current use case (e.g. emails). Can be null or undefined.");
}
}
2 changes: 2 additions & 0 deletions backend/src/Notifo.Domain/Liquid/LiquidPropertiesProvider.cs
Expand Up @@ -5,6 +5,8 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================

#pragma warning disable CA1822 // Mark members as static

namespace Notifo.Domain.Liquid;

public sealed class LiquidPropertiesProvider
Expand Down
5 changes: 2 additions & 3 deletions backend/src/Notifo.Domain/Liquid/LiquidProperty.cs
Expand Up @@ -36,11 +36,10 @@ public void AddBoolean(string path, string? description = null)

public void AddObject(string path, Action inner, string? description = null)
{
pathStack.Push(path);

Add(new LiquidProperty(FullPath(path), LiquidPropertyType.Object, description));
inner();

pathStack.Push(path);
inner();
pathStack.Pop();
}

Expand Down
6 changes: 3 additions & 3 deletions backend/src/Notifo.Domain/Liquid/LiquidUser.cs
Expand Up @@ -23,12 +23,12 @@ public sealed class LiquidUser(User user)
public static void Describe(LiquidProperties properties)
{
properties.AddString("fullName",
"The full name of the user.");
"The full name of the user. Can be null or undefined.");

properties.AddString("emailAddress",
"The email address of the user.");
"The email address of the user. Can be null or undefined.");

properties.AddString("phoneNumber",
"The phone number of the user.");
"The phone number of the user. Can be null or undefined.");
}
}
4 changes: 4 additions & 0 deletions backend/src/Notifo.Domain/Utils/UtilsServiceExtensions.cs
Expand Up @@ -5,6 +5,7 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================

using Notifo.Domain.Liquid;
using Notifo.Domain.Utils;

namespace Microsoft.Extensions.DependencyInjection;
Expand All @@ -15,5 +16,8 @@ public static void AddMyUtils(this IServiceCollection services)
{
services.AddSingletonAs<ImageFormatter>()
.As<IImageFormatter>();

services.AddSingletonAs<LiquidPropertiesProvider>()
.AsSelf();
}
}
Expand Up @@ -9,6 +9,7 @@
using Notifo.Areas.Api.Controllers.ChannelTemplates.Dtos;
using Notifo.Domain.ChannelTemplates;
using Notifo.Domain.Identity;
using Notifo.Domain.Liquid;
using Notifo.Infrastructure;
using Notifo.Infrastructure.Reflection;
using Notifo.Pipeline;
Expand All @@ -20,10 +21,12 @@ namespace Notifo.Areas.Api.Controllers.ChannelTemplates;
public abstract class ChannelTemplatesController<T, TDto> : BaseController where T : class, new() where TDto : class, new()
{
private readonly IChannelTemplateStore<T> channelTemplateStore;
private readonly LiquidPropertiesProvider propertiesProvider;

protected ChannelTemplatesController(IChannelTemplateStore<T> channelTemplateStore)
protected ChannelTemplatesController(IChannelTemplateStore<T> channelTemplateStore, LiquidPropertiesProvider propertiesProvider)
{
this.channelTemplateStore = channelTemplateStore;
this.propertiesProvider = propertiesProvider;
}

/// <summary>
Expand All @@ -47,6 +50,26 @@ public async Task<ListResponseDto<ChannelTemplateDto>> GetTemplates(string appId
return response;
}

/// <summary>
/// Get the template properties.
/// </summary>
/// <param name="appId">The id of the app where the templates belong to.</param>
/// <response code="200">Channel templates properties returned.</response>.
/// <response code="404">App not found.</response>
[HttpGet("properties")]
[AppPermission(NotifoRoles.AppAdmin)]
public ListResponseDto<TemplatePropertyDto> GetProperties(string appId)
{
var properties = propertiesProvider.GetProperties();

var response = new ListResponseDto<TemplatePropertyDto>();

response.Items.AddRange(properties.OrderBy(x => x.Path).Select(TemplatePropertyDto.FromDomainObject));
response.Total = 0;

return response;
}

/// <summary>
/// Get the channel template by id.
/// </summary>
Expand Down
@@ -0,0 +1,34 @@
// ==========================================================================
// Notifo.io
// ==========================================================================
// Copyright (c) Sebastian Stehle
// All rights reserved. Licensed under the MIT license.
// ==========================================================================

using Notifo.Domain.Liquid;
using Notifo.Infrastructure.Reflection;

namespace Notifo.Areas.Api.Controllers.ChannelTemplates.Dtos;

public sealed class TemplatePropertyDto
{
/// <summary>
/// The property path.
/// </summary>
public string Path { get; set; }

/// <summary>
/// The data ty.
/// </summary>
public LiquidPropertyType Type { get; set; }

/// <summary>
/// The optional description.
/// </summary>
public string? Description { get; set; }

public static TemplatePropertyDto FromDomainObject(LiquidProperty source)
{
return SimpleMapper.Map(source, new TemplatePropertyDto());
}
}
Expand Up @@ -9,15 +9,16 @@
using Notifo.Areas.Api.Controllers.ChannelTemplates.Dtos;
using Notifo.Domain.Channels.Email;
using Notifo.Domain.ChannelTemplates;
using Notifo.Domain.Liquid;

namespace Notifo.Areas.Api.Controllers.ChannelTemplates;

[Route("api/apps/{appId:notEmpty}/email-templates")]
[ApiExplorerSettings(GroupName = "EmailTemplates")]
public sealed class EmailTemplatesController : ChannelTemplatesController<EmailTemplate, EmailTemplateDto>
{
public EmailTemplatesController(IChannelTemplateStore<EmailTemplate> channelTemplateStore)
: base(channelTemplateStore)
public EmailTemplatesController(IChannelTemplateStore<EmailTemplate> channelTemplateStore, LiquidPropertiesProvider propertiesProvider)
: base(channelTemplateStore, propertiesProvider)
{
}
}
Expand Up @@ -9,15 +9,16 @@
using Notifo.Areas.Api.Controllers.ChannelTemplates.Dtos;
using Notifo.Domain.Channels.Messaging;
using Notifo.Domain.ChannelTemplates;
using Notifo.Domain.Liquid;

namespace Notifo.Areas.Api.Controllers.ChannelTemplates;

[Route("api/apps/{appId:notEmpty}/messaging-templates")]
[ApiExplorerSettings(GroupName = "MessagingTemplates")]
public sealed class MessagingTemplatesController : ChannelTemplatesController<MessagingTemplate, MessagingTemplateDto>
{
public MessagingTemplatesController(IChannelTemplateStore<MessagingTemplate> channelTemplateStore)
: base(channelTemplateStore)
public MessagingTemplatesController(IChannelTemplateStore<MessagingTemplate> channelTemplateStore, LiquidPropertiesProvider propertiesProvider)
: base(channelTemplateStore, propertiesProvider)
{
}
}
Expand Up @@ -9,15 +9,16 @@
using Notifo.Areas.Api.Controllers.ChannelTemplates.Dtos;
using Notifo.Domain.Channels.Sms;
using Notifo.Domain.ChannelTemplates;
using Notifo.Domain.Liquid;

namespace Notifo.Areas.Api.Controllers.ChannelTemplates;

[Route("api/apps/{appId:notEmpty}/sms-templates")]
[ApiExplorerSettings(GroupName = "SmsTemplates")]
public sealed class SmsTemplatesController : ChannelTemplatesController<SmsTemplate, SmsTemplateDto>
{
public SmsTemplatesController(IChannelTemplateStore<SmsTemplate> channelTemplateStore)
: base(channelTemplateStore)
public SmsTemplatesController(IChannelTemplateStore<SmsTemplate> channelTemplateStore, LiquidPropertiesProvider propertiesProvider)
: base(channelTemplateStore, propertiesProvider)
{
}
}
28 changes: 14 additions & 14 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions frontend/package.json
Expand Up @@ -32,8 +32,8 @@
"react-popper": "2.3.0",
"react-push-preview": "^0.1.9",
"react-redux": "8.1.3",
"react-router": "6.19.0",
"react-router-dom": "6.19.0",
"react-router": "6.22.3",
"react-router-dom": "6.22.3",
"react-router-redux": "4.0.8",
"react-split": "2.0.14",
"react-toastify": "^9.1.3",
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/app/framework/index.ts
Expand Up @@ -11,6 +11,7 @@ export * from './model';
export * from './react/ApiValue';
export * from './react/ClickOutside';
export * from './react/Code';
export * from './react/CodeEditor';
export * from './react/Confirm';
export * from './react/DropZone';
export * from './react/ErrorBoundary';
Expand All @@ -20,7 +21,6 @@ export * from './react/FormControlError';
export * from './react/FormError';
export * from './react/Gist';
export * from './react/hooks';
export * from './react/Marker';
export * from './react/Icon';
export * from './react/IFrame';
export * from './react/LanguageSelector';
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/app/framework/react/Code.tsx
Expand Up @@ -40,6 +40,7 @@ export const Code = (props: CodeProps) => {
const editor = CodeMirror.fromTextArea(textarea, {
foldGutter: true,
gutters: [
'CodeMirror-lint-markers',
'CodeMirror-linenumbers',
'CodeMirror-foldgutter',
],
Expand All @@ -48,6 +49,7 @@ export const Code = (props: CodeProps) => {
lineNumbers: true,
lineSeparator: undefined,
lineWrapping: false,
theme: 'material',
readOnly: true,
tabindex: 0,
tabSize: 2,
Expand Down
28 changes: 28 additions & 0 deletions frontend/src/app/framework/react/CodeEditor.stories.tsx
@@ -0,0 +1,28 @@
/*
* Notifo.io
*
* @license
* Copyright (c) Sebastian Stehle. All rights reserved.
*/

import type { Meta, StoryObj } from '@storybook/react';
import * as React from 'react';
import { CodeEditor } from './CodeEditor';

const meta: Meta<typeof CodeEditor> = {
component: CodeEditor,
render: args => {
// eslint-disable-next-line react-hooks/rules-of-hooks
const [value, setValue] = React.useState('Code');

return (
<CodeEditor {...args} value={value} onChange={setValue} />
);

},
};

export default meta;
type Story = StoryObj<typeof CodeEditor>;

export const Default: Story = {};

0 comments on commit b2fd7b5

Please sign in to comment.