3
0

Add base multi page layout implementation

This commit is contained in:
Jože Fortun
2023-03-22 20:08:12 +01:00
parent 4f77edce5e
commit e2e284ce0a
24 changed files with 1175 additions and 363 deletions

View File

@@ -4,6 +4,7 @@ export * from './types/revision'
export * from './types/module-field'
export { Namespace } from './types/namespace'
export { Page } from './types/page'
export { PageLayout } from './types/page-layout'
export * from './types/page-block'
export { RecordValidator } from './validators/record'
export { getModuleFromYaml } from './helpers'

View File

@@ -235,8 +235,6 @@ export class Module {
if (IsOf(m, 'config')) {
this.config = merge({}, this.config, m.config)
// Remove when we improve duplicate detection, for now its always enabled
}
if (IsOf(m, 'labels')) {

View File

@@ -27,16 +27,18 @@ interface PageBlockMeta {
export type PageBlockInput = PageBlock | Partial<PageBlock>
const defaultXYWH = [0, 2000, 3, 3]
const defaultXYWH = [0, 0, 20, 15]
export class PageBlock {
// blockID is auto generated by the server in order to support resource translations
public blockID = NoID;
public kind = ''
public title = '';
public description = '';
// blockID is auto generated by the server in order to support resource translations
public blockID = '0';
xywh: number[] = defaultXYWH
kind = ''
public xywh: number[] = defaultXYWH
public options = {}

View File

@@ -0,0 +1,106 @@
import { merge } from 'lodash'
import { Apply, CortezaID, ISO8601Date, NoID } from '../../cast'
import { PageBlock } from './page-block/base'
import { Button } from './page-block/types'
export type PageLayoutInput = PageLayout | Partial<PageLayout>
interface PageLayoutConfig {
visibility: Visibility;
actions: Action[];
}
interface Action {
actionID: string;
kind: string;
placement: string;
params: unknown;
meta: unknown;
}
interface Visibility {
expression: string;
roles: string[];
}
interface Meta {
title: string;
description: string;
}
export class PageLayout {
public pageLayoutID = NoID;
public namespaceID = NoID;
public pageID = NoID
public handle = '';
public weight = 0;
public blocks: (Partial<PageBlock>)[] = [];
public config: PageLayoutConfig = {
visibility: {
expression: '',
roles: [],
},
actions: [],
}
public meta: Meta = {
title: '',
description: ''
};
public createdAt?: Date = undefined;
public updatedAt?: Date = undefined;
public deletedAt?: Date = undefined;
public ownedBy = NoID;
constructor (pl?: PageLayoutInput) {
this.apply(pl)
}
apply (pl?: PageLayoutInput): void {
if (!pl) return
Apply(this, pl, CortezaID, 'pageLayoutID', 'namespaceID', 'pageID', 'ownedBy')
Apply(this, pl, String, 'handle')
Apply(this, pl, ISO8601Date, 'createdAt', 'updatedAt', 'deletedAt')
this.blocks = (pl.blocks || []).map(({ blockID, xywh }) => ({ blockID, xywh }))
if (pl.meta) {
this.meta = { ...this.meta, ...pl.meta }
}
if (pl.config) {
this.config = merge({}, this.config, pl.config)
}
}
clone (): PageLayout {
return new PageLayout(JSON.parse(JSON.stringify(this)))
}
/**
* Returns resource ID
*/
get resourceID (): string {
return `${this.resourceType}:${this.pageLayoutID}`
}
/**
* Resource type
*/
get resourceType (): string {
return 'compose:page-layout'
}
export (): PageLayoutInput {
return {
blocks: this.blocks,
meta: this.meta,
}
}
}

View File

@@ -1,12 +1,14 @@
import { Apply, CortezaID, ISO8601Date, NoID } from '../../cast'
import { IsOf, AreObjectsOf } from '../../guards'
import { PageBlock, PageBlockMaker } from './page-block'
import { Button } from './page-block/types'
import { merge } from 'lodash'
interface PartialPage extends Partial<Omit<Page, 'children' | 'blocks' | 'createdAt' | 'updatedAt' | 'deletedAt'>> {
interface PartialPage extends Partial<Omit<Page, 'children' | 'meta' | 'blocks' |'createdAt' | 'updatedAt' | 'deletedAt'>> {
children?: Array<PartialPage>;
blocks?: (Partial<PageBlock>)[];
blocks?: PageBlock[];
meta?: object;
createdAt?: string|number|Date;
updatedAt?: string|number|Date;
@@ -14,15 +16,6 @@ interface PartialPage extends Partial<Omit<Page, 'children' | 'blocks' | 'create
}
interface PageConfig {
buttons: {
submit: Button;
delete: Button;
new: Button;
edit: Button;
clone: Button;
back: Button;
};
attachments: [];
navItem: {
icon: {
type: string;
@@ -47,20 +40,11 @@ export class Page {
public visible = false;
public children?: Array<Page>
public children?: Page[];
public blocks: (InstanceType<typeof PageBlock>)[] = [];
public blocks: PageBlock[] = [];
public config: PageConfig = {
buttons: {
submit: { enabled: true },
delete: { enabled: true },
new: { enabled: true },
edit: { enabled: true },
clone: { enabled: true },
back: { enabled: true },
},
attachments: [],
navItem: {
icon: {
type: '',
@@ -69,6 +53,7 @@ export class Page {
expanded: false,
},
}
public meta: object = {};
public createdAt?: Date = undefined;
public updatedAt?: Date = undefined;
@@ -95,10 +80,7 @@ export class Page {
Apply(this, i, Boolean, 'visible')
if (i.blocks) {
this.blocks = []
if (AreObjectsOf<PageBlock>(i.blocks, 'kind') && AreObjectsOf<PageBlock>(i.blocks, 'xywh')) {
this.blocks = i.blocks.map((b: { kind: string }) => PageBlockMaker(b))
}
this.blocks = i.blocks.map(block => PageBlockMaker(block))
}
if (i.children) {
@@ -108,8 +90,12 @@ export class Page {
}
}
if (i.config) {
this.config = i.config
if (IsOf(i, 'config')) {
this.config = merge({}, this.config, i.config)
}
if (IsOf(i, 'meta')) {
this.meta = merge({}, this.meta, i.meta)
}
if (IsOf(i, 'labels')) {