Skip to content

Commit

Permalink
sandbox: add "custom links" to editor
Browse files Browse the repository at this point in the history
  • Loading branch information
matej21 committed Jan 17, 2022
1 parent 3de5383 commit d922664
Show file tree
Hide file tree
Showing 9 changed files with 441 additions and 85 deletions.
273 changes: 273 additions & 0 deletions packages/admin-sandbox/api/migrations/2022-01-17-164045-links.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,273 @@
{
"formatVersion": 3,
"modifications": [
{
"modification": "removeField",
"entityName": "ContentReference",
"fieldName": "url"
},
{
"modification": "createEnum",
"enumName": "LinkType",
"values": [
"internal",
"external"
]
},
{
"modification": "createEnum",
"enumName": "UrlType",
"values": [
"article",
"category",
"tag"
]
},
{
"modification": "createEntity",
"entity": {
"name": "Link",
"primary": "id",
"primaryColumn": "id",
"unique": {},
"fields": {
"id": {
"name": "id",
"columnName": "id",
"nullable": false,
"type": "Uuid",
"columnType": "uuid"
}
},
"tableName": "link"
}
},
{
"modification": "createEntity",
"entity": {
"name": "Url",
"primary": "id",
"primaryColumn": "id",
"unique": {},
"fields": {
"id": {
"name": "id",
"columnName": "id",
"nullable": false,
"type": "Uuid",
"columnType": "uuid"
}
},
"tableName": "url"
}
},
{
"modification": "createColumn",
"entityName": "Link",
"field": {
"name": "type",
"columnName": "type",
"nullable": false,
"type": "Enum",
"columnType": "LinkType"
}
},
{
"modification": "createColumn",
"entityName": "Link",
"field": {
"name": "externalLink",
"columnName": "external_link",
"nullable": true,
"type": "String",
"columnType": "text"
}
},
{
"modification": "createColumn",
"entityName": "Url",
"field": {
"name": "url",
"columnName": "url",
"nullable": false,
"type": "String",
"columnType": "text"
}
},
{
"modification": "createColumn",
"entityName": "Url",
"field": {
"name": "type",
"columnName": "type",
"nullable": false,
"type": "Enum",
"columnType": "UrlType"
}
},
{
"modification": "createRelation",
"entityName": "ContentReference",
"owningSide": {
"name": "link",
"nullable": true,
"type": "ManyHasOne",
"target": "Link",
"joiningColumn": {
"columnName": "link_id",
"onDelete": "restrict"
}
}
},
{
"modification": "createRelation",
"entityName": "Link",
"owningSide": {
"name": "internalLink",
"nullable": true,
"type": "ManyHasOne",
"target": "Url",
"joiningColumn": {
"columnName": "internal_link_id",
"onDelete": "set null"
}
}
},
{
"modification": "createRelation",
"entityName": "Url",
"owningSide": {
"name": "article",
"nullable": true,
"type": "OneHasOne",
"target": "Article",
"joiningColumn": {
"columnName": "article_id",
"onDelete": "cascade"
}
}
},
{
"modification": "createRelation",
"entityName": "Url",
"owningSide": {
"name": "category",
"nullable": true,
"type": "OneHasOne",
"target": "Category",
"joiningColumn": {
"columnName": "category_id",
"onDelete": "cascade"
}
}
},
{
"modification": "createRelation",
"entityName": "Url",
"owningSide": {
"name": "tag",
"nullable": true,
"type": "OneHasOne",
"target": "Tag",
"joiningColumn": {
"columnName": "tag_id",
"onDelete": "cascade"
}
}
},
{
"modification": "createUniqueConstraint",
"entityName": "Url",
"unique": {
"fields": [
"url"
],
"name": "unique_Url_url_a758c1"
}
},
{
"modification": "patchAclSchema",
"patch": [
{
"op": "add",
"path": "/roles/admin/entities/Link",
"value": {
"predicates": {},
"operations": {
"create": {
"id": true,
"type": true,
"internalLink": true,
"externalLink": true
},
"read": {
"id": true,
"type": true,
"internalLink": true,
"externalLink": true
},
"update": {
"id": true,
"type": true,
"internalLink": true,
"externalLink": true
},
"delete": true,
"customPrimary": true
}
}
},
{
"op": "add",
"path": "/roles/admin/entities/Url",
"value": {
"predicates": {},
"operations": {
"create": {
"id": true,
"url": true,
"type": true,
"article": true,
"category": true,
"tag": true
},
"read": {
"id": true,
"url": true,
"type": true,
"article": true,
"category": true,
"tag": true
},
"update": {
"id": true,
"url": true,
"type": true,
"article": true,
"category": true,
"tag": true
},
"delete": true,
"customPrimary": true
}
}
},
{
"op": "add",
"path": "/roles/admin/entities/ContentReference/operations/create/link",
"value": true
},
{
"op": "add",
"path": "/roles/admin/entities/ContentReference/operations/update/link",
"value": true
},
{
"op": "add",
"path": "/roles/admin/entities/ContentReference/operations/read/link",
"value": true
}
]
}
]
}
5 changes: 3 additions & 2 deletions packages/admin-sandbox/api/model/Content.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { SchemaDefinition as d } from '@contember/schema-definition'
import { BasicImage } from './Files'
import { Link } from './Link'

export class Content {
blocks: d.OneHasManyDefinition = d.oneHasMany(ContentBlock, 'content').orderBy('order')
Expand All @@ -15,7 +16,7 @@ export class ContentBlock {
export const ContentReferenceType = d.createEnum(
'image', // image
'quote', // primaryText, secondaryText
'link', // url
'link', // link
)

export class ContentReference {
Expand All @@ -24,5 +25,5 @@ export class ContentReference {
primaryText = d.stringColumn()
secondaryText = d.stringColumn()
image = d.manyHasOne(BasicImage)
url = d.stringColumn()
link = d.manyHasOne(Link)
}
10 changes: 10 additions & 0 deletions packages/admin-sandbox/api/model/Link.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { SchemaDefinition as d } from '@contember/schema-definition'
import { Url } from './Url'

export const LinkType = d.createEnum('internal', 'external')

export class Link {
type = d.enumColumn(LinkType).notNull()
internalLink = d.manyHasOne(Url).setNullOnDelete()
externalLink = d.stringColumn()
}
13 changes: 13 additions & 0 deletions packages/admin-sandbox/api/model/Url.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { SchemaDefinition as d } from '@contember/schema-definition'
import { Article, Category, Tag } from './Article'

export const UrlType = d.createEnum('article', 'category', 'tag')

@d.Unique('url')
export class Url {
url = d.stringColumn().notNull()
type = d.enumColumn(UrlType).notNull()
article = d.oneHasOne(Article).cascadeOnDelete()
category = d.oneHasOne(Category).cascadeOnDelete()
tag = d.oneHasOne(Tag).cascadeOnDelete()
}
2 changes: 2 additions & 0 deletions packages/admin-sandbox/api/model/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ export * from './Article'
export * from './Content'
export * from './Homepage'
export * from './Files'
export * from './Link'
export * from './One'
export * from './InputShowcase'
export * from './Locale'
export * from './UploadShowcase'
export * from './Url'
18 changes: 18 additions & 0 deletions packages/admin-sandbox/src/components/AnchorInsertHandler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { EditorTransforms, EditorWithBlocks, EntityAccessor } from '@contember/admin'

export const withAnchorsAsReference = (editor: EditorWithBlocks, { elementType, referenceType = elementType, updateReference }: {
elementType: string,
updateReference: (url: string, getAccessor: () => EntityAccessor) => void
referenceType?: string,
}) => {
const { normalizeNode } = editor
editor.normalizeNode = ([element, path]) => {
if ('type' in element && element.type === 'anchor' && 'href' in element && typeof element.href === 'string') {
const referenceId = editor.createElementReference(path, referenceType, getAccessor => {
updateReference(element.href as string, getAccessor)
}).id
return EditorTransforms.setNodes(editor, { referenceId, href: null, type: elementType }, { at: path })
}
normalizeNode([element, path])
}
}
Loading

0 comments on commit d922664

Please sign in to comment.