refactor: native feature management (#2350)
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
import { EditorFeatureDescription } from '../Feature/EditorFeatureDescription'
|
||||
import { FindNativeFeature } from '../Feature/Features'
|
||||
import { IframeComponentFeatureDescription } from '../Feature/IframeComponentFeatureDescription'
|
||||
import { FeatureIdentifier } from './../Feature/FeatureIdentifier'
|
||||
import { EditorIdentifier } from './EditorIdentifier'
|
||||
|
||||
@@ -15,13 +17,9 @@ export enum NoteType {
|
||||
}
|
||||
|
||||
export function noteTypeForEditorIdentifier(identifier: EditorIdentifier): NoteType {
|
||||
if (identifier === FeatureIdentifier.PlainEditor) {
|
||||
return NoteType.Plain
|
||||
} else if (identifier === FeatureIdentifier.SuperEditor) {
|
||||
return NoteType.Super
|
||||
}
|
||||
|
||||
const feature = FindNativeFeature(identifier as FeatureIdentifier)
|
||||
const feature = FindNativeFeature<EditorFeatureDescription | IframeComponentFeatureDescription>(
|
||||
identifier as FeatureIdentifier,
|
||||
)
|
||||
if (feature && feature.note_type) {
|
||||
return feature.note_type
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import { EditorFeatureDescription } from './EditorFeatureDescription'
|
||||
import { ThemeFeatureDescription } from './ThemeFeatureDescription'
|
||||
import { ComponentFeatureDescription } from './ComponentFeatureDescription'
|
||||
import { IframeComponentFeatureDescription } from './IframeComponentFeatureDescription'
|
||||
import { ClientFeatureDescription } from './ClientFeatureDescription'
|
||||
import { ServerFeatureDescription } from './ServerFeatureDescription'
|
||||
|
||||
export type AnyFeatureDescription =
|
||||
| ComponentFeatureDescription
|
||||
| EditorFeatureDescription
|
||||
| ThemeFeatureDescription
|
||||
| IframeComponentFeatureDescription
|
||||
| ClientFeatureDescription
|
||||
| ServerFeatureDescription
|
||||
@@ -0,0 +1,24 @@
|
||||
import { PermissionName } from '../Permission/PermissionName'
|
||||
import { FeatureIdentifier } from './FeatureIdentifier'
|
||||
import { ComponentFlag } from '../Component/ComponentFlag'
|
||||
import { RoleFields } from './RoleFields'
|
||||
|
||||
export type BaseFeatureDescription = RoleFields & {
|
||||
deletion_warning?: string
|
||||
deprecated?: boolean
|
||||
deprecation_message?: string
|
||||
description?: string
|
||||
expires_at?: number
|
||||
|
||||
/** Whether the client controls availability of this feature (such as the dark theme) */
|
||||
clientControlled?: boolean
|
||||
|
||||
flags?: ComponentFlag[]
|
||||
identifier: FeatureIdentifier
|
||||
marketing_url?: string
|
||||
name: string
|
||||
no_expire?: boolean
|
||||
no_mobile?: boolean
|
||||
thumbnail_url?: string
|
||||
permission_name: PermissionName
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { PermissionName } from '../Permission/PermissionName'
|
||||
import { FeatureIdentifier } from './FeatureIdentifier'
|
||||
import { RoleFields } from './RoleFields'
|
||||
|
||||
export type ClientFeatureDescription = RoleFields & {
|
||||
identifier: FeatureIdentifier
|
||||
permission_name: PermissionName
|
||||
description: string
|
||||
name: string
|
||||
deprecated?: boolean
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { ComponentArea } from '../Component/ComponentArea'
|
||||
import { BaseFeatureDescription } from './BaseFeatureDescription'
|
||||
|
||||
export type ComponentFeatureDescription = BaseFeatureDescription & {
|
||||
/** The relative path of the index.html file or the main css file if theme, within the component folder itself */
|
||||
index_path: string
|
||||
content_type: string
|
||||
area: ComponentArea
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { NoteType } from '../Component/NoteType'
|
||||
import { BaseFeatureDescription } from './BaseFeatureDescription'
|
||||
|
||||
export type EditorFeatureDescription = BaseFeatureDescription & {
|
||||
file_type: 'txt' | 'html' | 'md' | 'json'
|
||||
/** Whether an editor is interchangable with another editor that has the same file_type */
|
||||
interchangeable: boolean
|
||||
note_type: NoteType
|
||||
spellcheckControl: boolean
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
import { ComponentPermission } from '../Component/ComponentPermission'
|
||||
import { ComponentArea } from '../Component/ComponentArea'
|
||||
import { PermissionName } from '../Permission/PermissionName'
|
||||
import { FeatureIdentifier } from './FeatureIdentifier'
|
||||
import { ComponentFlag } from '../Component/ComponentFlag'
|
||||
import { NoteType } from '../Component/NoteType'
|
||||
import { ThemeDockIcon } from '../Component/ThemeDockIcon'
|
||||
|
||||
type RoleFields = {
|
||||
/** Server populated */
|
||||
role_name?: string
|
||||
|
||||
/** Statically populated. Non-influencing; used as a reference by other static consumers (such as email service) */
|
||||
availableInRoles: string[]
|
||||
}
|
||||
|
||||
export type BaseFeatureDescription = RoleFields & {
|
||||
deletion_warning?: string
|
||||
deprecated?: boolean
|
||||
deprecation_message?: string
|
||||
description?: string
|
||||
expires_at?: number
|
||||
|
||||
/** Whether the client controls availability of this feature (such as the dark theme) */
|
||||
clientControlled?: boolean
|
||||
|
||||
flags?: ComponentFlag[]
|
||||
identifier: FeatureIdentifier
|
||||
marketing_url?: string
|
||||
name?: string
|
||||
no_expire?: boolean
|
||||
no_mobile?: boolean
|
||||
thumbnail_url?: string
|
||||
permission_name: PermissionName
|
||||
}
|
||||
|
||||
export type ServerFeatureDescription = RoleFields & {
|
||||
name?: string
|
||||
identifier: FeatureIdentifier
|
||||
permission_name: PermissionName
|
||||
}
|
||||
|
||||
export type ClientFeatureDescription = RoleFields & {
|
||||
identifier: FeatureIdentifier
|
||||
permission_name: PermissionName
|
||||
description: string
|
||||
name: string
|
||||
}
|
||||
|
||||
export type ComponentFeatureDescription = BaseFeatureDescription & {
|
||||
/** The relative path of the index.html file or the main css file if theme, within the component folder itself */
|
||||
index_path: string
|
||||
content_type: string
|
||||
area: ComponentArea
|
||||
}
|
||||
|
||||
export type ThirdPartyFeatureDescription = ComponentFeatureDescription & {
|
||||
url: string
|
||||
}
|
||||
|
||||
export type IframeComponentFeatureDescription = ComponentFeatureDescription & {
|
||||
component_permissions: ComponentPermission[]
|
||||
}
|
||||
|
||||
export type EditorFeatureDescription = IframeComponentFeatureDescription & {
|
||||
file_type: 'txt' | 'html' | 'md' | 'json'
|
||||
/** Whether an editor is interchangable with another editor that has the same file_type */
|
||||
interchangeable: boolean
|
||||
note_type: NoteType
|
||||
spellcheckControl?: boolean
|
||||
}
|
||||
|
||||
export type ThemeFeatureDescription = ComponentFeatureDescription & {
|
||||
/** Some themes can be layered on top of other themes */
|
||||
layerable?: boolean
|
||||
dock_icon?: ThemeDockIcon
|
||||
isDark?: boolean
|
||||
}
|
||||
|
||||
export type FeatureDescription = BaseFeatureDescription &
|
||||
Partial<ComponentFeatureDescription & EditorFeatureDescription & ThemeFeatureDescription>
|
||||
@@ -1,14 +1,51 @@
|
||||
import { FeatureDescription } from './FeatureDescription'
|
||||
import { AnyFeatureDescription } from './AnyFeatureDescription'
|
||||
import { ThemeFeatureDescription } from './ThemeFeatureDescription'
|
||||
import { EditorFeatureDescription } from './EditorFeatureDescription'
|
||||
import { FeatureIdentifier } from './FeatureIdentifier'
|
||||
import { serverFeatures } from '../Lists/ServerFeatures'
|
||||
import { clientFeatures } from '../Lists/ClientFeatures'
|
||||
import { GetDeprecatedFeatures } from '../Lists/DeprecatedFeatures'
|
||||
import { experimentalFeatures } from '../Lists/ExperimentalFeatures'
|
||||
import { IframeEditors } from '../Lists/IframeEditors'
|
||||
import { themes } from '../Lists/Themes'
|
||||
import { nativeEditors } from '../Lists/NativeEditors'
|
||||
|
||||
export function GetFeatures(): FeatureDescription[] {
|
||||
return [...serverFeatures(), ...clientFeatures(), ...experimentalFeatures(), ...GetDeprecatedFeatures()]
|
||||
export function GetFeatures(): AnyFeatureDescription[] {
|
||||
return [
|
||||
...serverFeatures(),
|
||||
...clientFeatures(),
|
||||
...themes(),
|
||||
...nativeEditors(),
|
||||
...IframeEditors(),
|
||||
...experimentalFeatures(),
|
||||
...GetDeprecatedFeatures(),
|
||||
]
|
||||
}
|
||||
|
||||
export function FindNativeFeature(identifier: FeatureIdentifier): FeatureDescription | undefined {
|
||||
return GetFeatures().find((f) => f.identifier === identifier)
|
||||
export function FindNativeFeature<T extends AnyFeatureDescription>(identifier: FeatureIdentifier): T | undefined {
|
||||
return GetFeatures().find((f) => f.identifier === identifier) as T
|
||||
}
|
||||
|
||||
export function FindNativeTheme(identifier: FeatureIdentifier): ThemeFeatureDescription | undefined {
|
||||
return themes().find((t) => t.identifier === identifier)
|
||||
}
|
||||
|
||||
export function GetIframeAndNativeEditors(): EditorFeatureDescription[] {
|
||||
return [...IframeEditors(), ...nativeEditors()]
|
||||
}
|
||||
|
||||
export function GetSuperNoteFeature(): EditorFeatureDescription {
|
||||
return FindNativeFeature(FeatureIdentifier.SuperEditor) as EditorFeatureDescription
|
||||
}
|
||||
|
||||
export function GetPlainNoteFeature(): EditorFeatureDescription {
|
||||
return FindNativeFeature(FeatureIdentifier.PlainEditor) as EditorFeatureDescription
|
||||
}
|
||||
|
||||
export function GetNativeThemes(): ThemeFeatureDescription[] {
|
||||
return themes()
|
||||
}
|
||||
|
||||
export function GetDarkThemeFeature(): ThemeFeatureDescription {
|
||||
return themes().find((t) => t.identifier === FeatureIdentifier.DarkTheme) as ThemeFeatureDescription
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import { ComponentPermission } from '../Component/ComponentPermission'
|
||||
import { ComponentFeatureDescription } from './ComponentFeatureDescription'
|
||||
import { EditorFeatureDescription } from './EditorFeatureDescription'
|
||||
|
||||
export type IframeComponentFeatureDescription = (EditorFeatureDescription & ComponentFeatureDescription) & {
|
||||
component_permissions: ComponentPermission[]
|
||||
}
|
||||
7
packages/features/src/Domain/Feature/RoleFields.ts
Normal file
7
packages/features/src/Domain/Feature/RoleFields.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export type RoleFields = {
|
||||
/** Server populated */
|
||||
role_name?: string
|
||||
|
||||
/** Statically populated. Non-influencing; used as a reference by other static consumers (such as email service) */
|
||||
availableInRoles: string[]
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { PermissionName } from '../Permission/PermissionName'
|
||||
import { FeatureIdentifier } from './FeatureIdentifier'
|
||||
import { RoleFields } from './RoleFields'
|
||||
|
||||
export type ServerFeatureDescription = RoleFields & {
|
||||
name: string
|
||||
description?: string
|
||||
identifier: FeatureIdentifier
|
||||
permission_name: PermissionName
|
||||
deprecated?: boolean
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { ThemeDockIcon } from '../Component/ThemeDockIcon'
|
||||
import { ComponentFeatureDescription } from './ComponentFeatureDescription'
|
||||
|
||||
export type ThemeFeatureDescription = ComponentFeatureDescription & {
|
||||
/** Some themes can be layered on top of other themes */
|
||||
layerable?: boolean
|
||||
dock_icon?: ThemeDockIcon
|
||||
isDark?: boolean
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import { ComponentFeatureDescription } from './ComponentFeatureDescription'
|
||||
|
||||
export type ThirdPartyFeatureDescription = ComponentFeatureDescription & {
|
||||
url: string
|
||||
}
|
||||
28
packages/features/src/Domain/Feature/TypeGuards.ts
Normal file
28
packages/features/src/Domain/Feature/TypeGuards.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { ContentType } from '@standardnotes/domain-core'
|
||||
import { AnyFeatureDescription } from './AnyFeatureDescription'
|
||||
import { ThemeFeatureDescription } from './ThemeFeatureDescription'
|
||||
import { EditorFeatureDescription } from './EditorFeatureDescription'
|
||||
import { IframeComponentFeatureDescription } from './IframeComponentFeatureDescription'
|
||||
import { ComponentFeatureDescription } from './ComponentFeatureDescription'
|
||||
import { ComponentArea } from '../Component/ComponentArea'
|
||||
|
||||
export function isThemeFeatureDescription(feature: AnyFeatureDescription): feature is ThemeFeatureDescription {
|
||||
return 'content_type' in feature && feature.content_type === ContentType.TYPES.Theme
|
||||
}
|
||||
|
||||
export function isIframeComponentFeatureDescription(
|
||||
feature: AnyFeatureDescription,
|
||||
): feature is IframeComponentFeatureDescription {
|
||||
return (
|
||||
'content_type' in feature &&
|
||||
feature.content_type === ContentType.TYPES.Component &&
|
||||
[ComponentArea.Editor, ComponentArea.EditorStack].includes(feature.area)
|
||||
)
|
||||
}
|
||||
|
||||
export function isEditorFeatureDescription(feature: AnyFeatureDescription): feature is EditorFeatureDescription {
|
||||
return (
|
||||
(feature as EditorFeatureDescription).note_type != undefined ||
|
||||
(feature as ComponentFeatureDescription).area === ComponentArea.Editor
|
||||
)
|
||||
}
|
||||
10
packages/features/src/Domain/Feature/UIFeatureDescription.ts
Normal file
10
packages/features/src/Domain/Feature/UIFeatureDescription.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { ComponentFeatureDescription } from './ComponentFeatureDescription'
|
||||
import { EditorFeatureDescription } from './EditorFeatureDescription'
|
||||
import { IframeComponentFeatureDescription } from './IframeComponentFeatureDescription'
|
||||
import { ThemeFeatureDescription } from './ThemeFeatureDescription'
|
||||
|
||||
export type UIFeatureDescriptionTypes =
|
||||
| IframeComponentFeatureDescription
|
||||
| ThemeFeatureDescription
|
||||
| EditorFeatureDescription
|
||||
| ComponentFeatureDescription
|
||||
@@ -1,14 +1,10 @@
|
||||
import { FeatureDescription } from '../Feature/FeatureDescription'
|
||||
import { PermissionName } from '../Permission/PermissionName'
|
||||
import { FeatureIdentifier } from '../Feature/FeatureIdentifier'
|
||||
import { RoleName } from '@standardnotes/domain-core'
|
||||
import { themes } from './Themes'
|
||||
import { editors } from './Editors'
|
||||
import { ClientFeatureDescription } from '../Feature/ClientFeatureDescription'
|
||||
|
||||
export function clientFeatures(): FeatureDescription[] {
|
||||
export function clientFeatures(): ClientFeatureDescription[] {
|
||||
return [
|
||||
...themes(),
|
||||
...editors(),
|
||||
{
|
||||
name: 'Tag Nesting',
|
||||
availableInRoles: [RoleName.NAMES.PlusUser, RoleName.NAMES.ProUser],
|
||||
@@ -16,14 +12,7 @@ export function clientFeatures(): FeatureDescription[] {
|
||||
permission_name: PermissionName.TagNesting,
|
||||
description: 'Organize your tags into folders.',
|
||||
},
|
||||
{
|
||||
name: 'Super Notes',
|
||||
identifier: FeatureIdentifier.SuperEditor,
|
||||
availableInRoles: [RoleName.NAMES.PlusUser, RoleName.NAMES.ProUser],
|
||||
permission_name: PermissionName.SuperEditor,
|
||||
description:
|
||||
'A new way to edit notes. Type / to bring up the block selection menu, or @ to embed images or link other tags and notes. Type - then space to start a list, or [] then space to start a checklist. Drag and drop an image or file to embed it in your note. Cmd/Ctrl + F to bring up search and replace.',
|
||||
},
|
||||
|
||||
{
|
||||
name: 'Smart Filters',
|
||||
availableInRoles: [RoleName.NAMES.PlusUser, RoleName.NAMES.ProUser],
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
import { AnyFeatureDescription } from '../Feature/AnyFeatureDescription'
|
||||
import { EditorFeatureDescription } from '../Feature/EditorFeatureDescription'
|
||||
import { IframeComponentFeatureDescription } from '../Feature/IframeComponentFeatureDescription'
|
||||
import { ContentType, RoleName } from '@standardnotes/domain-core'
|
||||
import {
|
||||
EditorFeatureDescription,
|
||||
IframeComponentFeatureDescription,
|
||||
FeatureDescription,
|
||||
} from '../Feature/FeatureDescription'
|
||||
import { PermissionName } from '../Permission/PermissionName'
|
||||
import { FeatureIdentifier } from '../Feature/FeatureIdentifier'
|
||||
import { NoteType } from '../Component/NoteType'
|
||||
import { FillEditorComponentDefaults } from './Utilities/FillEditorComponentDefaults'
|
||||
import { FillIframeEditorDefaults } from './Utilities/FillEditorComponentDefaults'
|
||||
import { ComponentAction } from '../Component/ComponentAction'
|
||||
import { ComponentArea } from '../Component/ComponentArea'
|
||||
|
||||
export function GetDeprecatedFeatures(): FeatureDescription[] {
|
||||
const bold: EditorFeatureDescription = FillEditorComponentDefaults({
|
||||
export function GetDeprecatedFeatures(): AnyFeatureDescription[] {
|
||||
const bold: EditorFeatureDescription = FillIframeEditorDefaults({
|
||||
name: 'Alternative Rich Text',
|
||||
identifier: FeatureIdentifier.DeprecatedBoldEditor,
|
||||
note_type: NoteType.RichText,
|
||||
@@ -39,7 +37,7 @@ export function GetDeprecatedFeatures(): FeatureDescription[] {
|
||||
availableInRoles: [RoleName.NAMES.PlusUser, RoleName.NAMES.ProUser],
|
||||
})
|
||||
|
||||
const markdownBasic: EditorFeatureDescription = FillEditorComponentDefaults({
|
||||
const markdownBasic: EditorFeatureDescription = FillIframeEditorDefaults({
|
||||
name: 'Basic Markdown',
|
||||
identifier: FeatureIdentifier.DeprecatedMarkdownBasicEditor,
|
||||
note_type: NoteType.Markdown,
|
||||
@@ -52,7 +50,7 @@ export function GetDeprecatedFeatures(): FeatureDescription[] {
|
||||
availableInRoles: [RoleName.NAMES.PlusUser, RoleName.NAMES.ProUser],
|
||||
})
|
||||
|
||||
const markdownAlt: EditorFeatureDescription = FillEditorComponentDefaults({
|
||||
const markdownAlt: EditorFeatureDescription = FillIframeEditorDefaults({
|
||||
name: 'Markdown Alternative',
|
||||
identifier: FeatureIdentifier.DeprecatedMarkdownVisualEditor,
|
||||
note_type: NoteType.Markdown,
|
||||
@@ -66,7 +64,7 @@ export function GetDeprecatedFeatures(): FeatureDescription[] {
|
||||
availableInRoles: [RoleName.NAMES.PlusUser, RoleName.NAMES.ProUser],
|
||||
})
|
||||
|
||||
const markdownMinimist: EditorFeatureDescription = FillEditorComponentDefaults({
|
||||
const markdownMinimist: EditorFeatureDescription = FillIframeEditorDefaults({
|
||||
name: 'Minimal Markdown',
|
||||
identifier: FeatureIdentifier.DeprecatedMarkdownMinimistEditor,
|
||||
note_type: NoteType.Markdown,
|
||||
@@ -80,7 +78,7 @@ export function GetDeprecatedFeatures(): FeatureDescription[] {
|
||||
availableInRoles: [RoleName.NAMES.PlusUser, RoleName.NAMES.ProUser],
|
||||
})
|
||||
|
||||
const markdownMath: EditorFeatureDescription = FillEditorComponentDefaults({
|
||||
const markdownMath: EditorFeatureDescription = FillIframeEditorDefaults({
|
||||
name: 'Markdown with Math',
|
||||
identifier: FeatureIdentifier.DeprecatedMarkdownMathEditor,
|
||||
spellcheckControl: true,
|
||||
@@ -94,7 +92,7 @@ export function GetDeprecatedFeatures(): FeatureDescription[] {
|
||||
availableInRoles: [RoleName.NAMES.PlusUser, RoleName.NAMES.ProUser],
|
||||
})
|
||||
|
||||
const filesafe: IframeComponentFeatureDescription = FillEditorComponentDefaults({
|
||||
const filesafe: IframeComponentFeatureDescription = FillIframeEditorDefaults({
|
||||
name: 'FileSafe',
|
||||
identifier: FeatureIdentifier.DeprecatedFileSafe,
|
||||
component_permissions: [
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { FeatureDescription } from '../Feature/FeatureDescription'
|
||||
import { AnyFeatureDescription } from '../Feature/AnyFeatureDescription'
|
||||
|
||||
export function experimentalFeatures(): FeatureDescription[] {
|
||||
export function experimentalFeatures(): AnyFeatureDescription[] {
|
||||
return []
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { EditorFeatureDescription } from '../Feature/FeatureDescription'
|
||||
import { PermissionName } from '../Permission/PermissionName'
|
||||
import { FeatureIdentifier } from '../Feature/FeatureIdentifier'
|
||||
import { NoteType } from '../Component/NoteType'
|
||||
import { FillEditorComponentDefaults } from './Utilities/FillEditorComponentDefaults'
|
||||
import { FillIframeEditorDefaults } from './Utilities/FillEditorComponentDefaults'
|
||||
import { RoleName } from '@standardnotes/domain-core'
|
||||
import { IframeComponentFeatureDescription } from '../Feature/IframeComponentFeatureDescription'
|
||||
|
||||
export function editors(): EditorFeatureDescription[] {
|
||||
const code: EditorFeatureDescription = FillEditorComponentDefaults({
|
||||
export function IframeEditors(): IframeComponentFeatureDescription[] {
|
||||
const code = FillIframeEditorDefaults({
|
||||
name: 'Code',
|
||||
spellcheckControl: true,
|
||||
identifier: FeatureIdentifier.CodeEditor,
|
||||
@@ -22,7 +22,7 @@ export function editors(): EditorFeatureDescription[] {
|
||||
availableInRoles: [RoleName.NAMES.PlusUser, RoleName.NAMES.ProUser],
|
||||
})
|
||||
|
||||
const plus: EditorFeatureDescription = FillEditorComponentDefaults({
|
||||
const plus = FillIframeEditorDefaults({
|
||||
name: 'Rich Text',
|
||||
note_type: NoteType.RichText,
|
||||
file_type: 'html',
|
||||
@@ -35,7 +35,7 @@ export function editors(): EditorFeatureDescription[] {
|
||||
availableInRoles: [RoleName.NAMES.PlusUser, RoleName.NAMES.ProUser],
|
||||
})
|
||||
|
||||
const markdown: EditorFeatureDescription = FillEditorComponentDefaults({
|
||||
const markdown = FillIframeEditorDefaults({
|
||||
name: 'Markdown',
|
||||
identifier: FeatureIdentifier.MarkdownProEditor,
|
||||
note_type: NoteType.Markdown,
|
||||
@@ -48,7 +48,7 @@ export function editors(): EditorFeatureDescription[] {
|
||||
availableInRoles: [RoleName.NAMES.PlusUser, RoleName.NAMES.ProUser],
|
||||
})
|
||||
|
||||
const task: EditorFeatureDescription = FillEditorComponentDefaults({
|
||||
const task = FillIframeEditorDefaults({
|
||||
name: 'Checklist',
|
||||
identifier: FeatureIdentifier.TaskEditor,
|
||||
note_type: NoteType.Task,
|
||||
@@ -62,7 +62,7 @@ export function editors(): EditorFeatureDescription[] {
|
||||
availableInRoles: [RoleName.NAMES.PlusUser, RoleName.NAMES.ProUser],
|
||||
})
|
||||
|
||||
const tokenvault: EditorFeatureDescription = FillEditorComponentDefaults({
|
||||
const tokenvault = FillIframeEditorDefaults({
|
||||
name: 'Authenticator',
|
||||
note_type: NoteType.Authentication,
|
||||
file_type: 'json',
|
||||
@@ -75,7 +75,7 @@ export function editors(): EditorFeatureDescription[] {
|
||||
availableInRoles: [RoleName.NAMES.PlusUser, RoleName.NAMES.ProUser],
|
||||
})
|
||||
|
||||
const spreadsheets: EditorFeatureDescription = FillEditorComponentDefaults({
|
||||
const spreadsheets = FillIframeEditorDefaults({
|
||||
name: 'Spreadsheet',
|
||||
identifier: FeatureIdentifier.SheetsEditor,
|
||||
note_type: NoteType.Spreadsheet,
|
||||
32
packages/features/src/Domain/Lists/NativeEditors.ts
Normal file
32
packages/features/src/Domain/Lists/NativeEditors.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { RoleName } from '@standardnotes/domain-core'
|
||||
import { NoteType } from '../Component/NoteType'
|
||||
import { EditorFeatureDescription } from '../Feature/EditorFeatureDescription'
|
||||
import { FeatureIdentifier } from '../Feature/FeatureIdentifier'
|
||||
import { PermissionName } from '../Permission/PermissionName'
|
||||
|
||||
export function nativeEditors(): EditorFeatureDescription[] {
|
||||
return [
|
||||
{
|
||||
name: 'Super',
|
||||
note_type: NoteType.Super,
|
||||
identifier: FeatureIdentifier.SuperEditor,
|
||||
spellcheckControl: true,
|
||||
file_type: 'json',
|
||||
interchangeable: false,
|
||||
availableInRoles: [RoleName.NAMES.PlusUser, RoleName.NAMES.ProUser],
|
||||
permission_name: PermissionName.SuperEditor,
|
||||
description:
|
||||
'The best way to edit notes. Type / to bring up the block selection menu, or @ to embed images or link other tags and notes. Type - then space to start a list, or [] then space to start a checklist. Drag and drop an image or file to embed it in your note. Cmd/Ctrl + F to bring up search and replace.',
|
||||
},
|
||||
{
|
||||
name: 'Plain Text',
|
||||
note_type: NoteType.Plain,
|
||||
spellcheckControl: true,
|
||||
file_type: 'txt',
|
||||
interchangeable: true,
|
||||
identifier: FeatureIdentifier.PlainEditor,
|
||||
availableInRoles: [RoleName.NAMES.CoreUser, RoleName.NAMES.PlusUser, RoleName.NAMES.ProUser],
|
||||
permission_name: PermissionName.PlainEditor,
|
||||
},
|
||||
]
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ServerFeatureDescription } from '../Feature/FeatureDescription'
|
||||
import { ServerFeatureDescription } from '../Feature/ServerFeatureDescription'
|
||||
import { PermissionName } from '../Permission/PermissionName'
|
||||
import { FeatureIdentifier } from '../Feature/FeatureIdentifier'
|
||||
import { RoleName } from '@standardnotes/domain-core'
|
||||
@@ -42,16 +42,19 @@ export function serverFeatures(): ServerFeatureDescription[] {
|
||||
availableInRoles: [RoleName.NAMES.PlusUser, RoleName.NAMES.ProUser],
|
||||
},
|
||||
{
|
||||
name: 'Files maximum storage tier',
|
||||
identifier: FeatureIdentifier.FilesMaximumStorageTier,
|
||||
permission_name: PermissionName.FilesMaximumStorageTier,
|
||||
availableInRoles: [RoleName.NAMES.ProUser],
|
||||
},
|
||||
{
|
||||
name: 'Files low storage tier',
|
||||
identifier: FeatureIdentifier.FilesLowStorageTier,
|
||||
permission_name: PermissionName.FilesLowStorageTier,
|
||||
availableInRoles: [RoleName.NAMES.PlusUser],
|
||||
},
|
||||
{
|
||||
name: 'Files medium storage tier',
|
||||
identifier: FeatureIdentifier.SubscriptionSharing,
|
||||
permission_name: PermissionName.SubscriptionSharing,
|
||||
availableInRoles: [RoleName.NAMES.ProUser],
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ThemeFeatureDescription } from '../Feature/FeatureDescription'
|
||||
import { ThemeFeatureDescription } from '../Feature/ThemeFeatureDescription'
|
||||
import { PermissionName } from '../Permission/PermissionName'
|
||||
import { FeatureIdentifier } from '../Feature/FeatureIdentifier'
|
||||
import { FillThemeComponentDefaults } from './Utilities/FillThemeComponentDefaults'
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import { ContentType } from '@standardnotes/domain-core'
|
||||
|
||||
import { ComponentAction } from '../../Component/ComponentAction'
|
||||
import { EditorFeatureDescription } from '../../Feature/FeatureDescription'
|
||||
import { EditorFeatureDescription } from '../../Feature/EditorFeatureDescription'
|
||||
import { IframeComponentFeatureDescription } from '../../Feature/IframeComponentFeatureDescription'
|
||||
import { ComponentArea } from '../../Component/ComponentArea'
|
||||
|
||||
export type RequiredEditorFields = Pick<EditorFeatureDescription, 'availableInRoles'>
|
||||
|
||||
export function FillEditorComponentDefaults(
|
||||
component: Partial<EditorFeatureDescription> & RequiredEditorFields,
|
||||
): EditorFeatureDescription {
|
||||
export function FillIframeEditorDefaults(
|
||||
component: Partial<IframeComponentFeatureDescription> & RequiredEditorFields,
|
||||
): IframeComponentFeatureDescription {
|
||||
if (!component.index_path) {
|
||||
component.index_path = 'dist/index.html'
|
||||
}
|
||||
@@ -31,5 +32,5 @@ export function FillEditorComponentDefaults(
|
||||
component.interchangeable = true
|
||||
}
|
||||
|
||||
return component as EditorFeatureDescription
|
||||
return component as IframeComponentFeatureDescription
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { ContentType } from '@standardnotes/domain-core'
|
||||
|
||||
import { ThemeFeatureDescription } from '../../Feature/FeatureDescription'
|
||||
import { ThemeFeatureDescription } from '../../Feature/ThemeFeatureDescription'
|
||||
import { ComponentArea } from '../../Component/ComponentArea'
|
||||
|
||||
type RequiredThemeFields = Pick<ThemeFeatureDescription, 'availableInRoles'>
|
||||
|
||||
@@ -22,6 +22,7 @@ export enum PermissionName {
|
||||
NoteHistory30Days = 'server:note-history-30-days',
|
||||
NoteHistory365Days = 'server:note-history-365-days',
|
||||
NoteHistoryUnlimited = 'server:note-history-unlimited',
|
||||
PlainEditor = 'editor:plain',
|
||||
PlusEditor = 'editor:plus',
|
||||
SheetsEditor = 'editor:sheets',
|
||||
SignInAlerts = 'server:sign-in-alerts',
|
||||
|
||||
@@ -1,6 +1,17 @@
|
||||
export * from './Feature/FeatureDescription'
|
||||
export * from './Feature/AnyFeatureDescription'
|
||||
export * from './Feature/FeatureIdentifier'
|
||||
export * from './Feature/Features'
|
||||
export * from './Feature/TypeGuards'
|
||||
|
||||
export * from './Feature/ThirdPartyFeatureDescription'
|
||||
export * from './Feature/ClientFeatureDescription'
|
||||
export * from './Feature/ServerFeatureDescription'
|
||||
export * from './Feature/IframeComponentFeatureDescription'
|
||||
export * from './Feature/ComponentFeatureDescription'
|
||||
export * from './Feature/BaseFeatureDescription'
|
||||
export * from './Feature/EditorFeatureDescription'
|
||||
export * from './Feature/ThemeFeatureDescription'
|
||||
export * from './Feature/UIFeatureDescription'
|
||||
|
||||
export * from './Permission/Permission'
|
||||
export * from './Permission/PermissionName'
|
||||
|
||||
Reference in New Issue
Block a user