Skip to content

Commit

Permalink
Create a separate theme config system
Browse files Browse the repository at this point in the history
  • Loading branch information
Pierstoval committed Oct 30, 2023
1 parent 86171bc commit d3d5449
Show file tree
Hide file tree
Showing 24 changed files with 200 additions and 90 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ import booksCrud from './booksCrud';
export const dashboard = new DashboardDefinition({
// Some metadata related to your admin panel
admin: {
defaultLocale: 'en',
defaultLocale: 'en',
head: {
brandName: '{ Your company/brand name }',
appName: '{ Your app name }'
Expand Down Expand Up @@ -144,12 +144,14 @@ export const booksCrud = new CrudDefinition(
stateProvider: new CallbackStateProvider(function (operation, requestParameters = {}) {
console.info('TODO: return actual data, like from an API');

return null;
return Promise.resolve(null);
}),

// See below about state processors and providers.
stateProcessor: new CallbackStateProcessor(function (data, operation, requestParameters = {}) {
console.info('TODO: process new, edit or delete data based on the current operation');

return Promise.resolve();
})
}
);
Expand Down
20 changes: 10 additions & 10 deletions src/lib/Crud/Operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,18 @@ export type OperationCallbackName = 'submit' | string;
export type OperationCallback = (event: Event) => unknown | void;
export type OperationEventCallback = [event: OperationCallbackName, callback: OperationCallback];

export type TemplateComponent<T> = ComponentType<
SvelteComponent<{
dashboard: DashboardDefinition<T>;
crud: CrudDefinition<T>;
crudOperation: CrudOperation<T>;
}>
>;
export type TemplateComponent = ComponentType;
// SvelteComponent<{
// dashboard: DashboardDefinition<unknown>;
// crud: CrudDefinition<unknown>;
// operation: CrudOperation<unknown>;
// requestParameters: KeyValueObject;
// }>

export interface CrudOperation<T> {
readonly name: CrudOperationName;
readonly label: string;
readonly displayComponent: TemplateComponent<T>;
readonly displayComponent: TemplateComponent;
readonly fields: Array<Field<Options>>;
readonly actions: Array<Action>;
readonly eventHandlers: Array<OperationEventCallback>;
Expand All @@ -38,7 +38,7 @@ export interface CrudOperation<T> {

export class BaseCrudOperation<T> implements CrudOperation<T> {
public readonly name: CrudOperationName;
public readonly displayComponent: TemplateComponent<T>;
public readonly displayComponent: TemplateComponent;
public readonly fields: Array<Field<Options>>;
public readonly label: string;
public readonly actions: Array<Action>;
Expand All @@ -48,7 +48,7 @@ export class BaseCrudOperation<T> implements CrudOperation<T> {
constructor(
name: CrudOperationName,
label: string,
displayComponent: TemplateComponent<T>,
displayComponent: TemplateComponent,
fields: Array<Field<Options>>,
actions: Array<Action> = [],
eventHandlers: Array<OperationEventCallback> = [],
Expand Down
4 changes: 2 additions & 2 deletions src/lib/Dashboard/definition.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { MenuLink } from '$lib/Menu/MenuLinks';
import type { Dictionaries } from '$lib/admin_i18n';
import type { CrudDefinition } from '$lib/Crud/definition';
import {type AdminConfig, emptyAdminConfig} from '$lib/config/adminConfig';
import { type AdminConfig, emptyAdminConfig } from '$lib/config/adminConfig';

export type DashboardDefinitionOptions<T> = {
adminConfig: Partial<AdminConfig>;
Expand All @@ -23,7 +23,7 @@ export class DashboardDefinition<T> {
public readonly options = {};

constructor(options: DashboardDefinitionOptions<T>) {
this.adminConfig = {...emptyAdminConfig(), ...options.adminConfig};
this.adminConfig = { ...emptyAdminConfig(), ...options.adminConfig };
this.cruds = options.cruds;
this.sideMenu = options.sideMenu || [];
this.topLeftMenu = options.topLeftMenu || [];
Expand Down
4 changes: 2 additions & 2 deletions src/lib/Dashboard/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ describe(
() => {
it('can be instantiated with simple config', () => {
const dashboard = new DashboardDefinition<Book>({
adminConfig: emptyAdminConfig(),
adminConfig: {},
cruds: [
new CrudDefinition<Book>('books', {
label: { singular: 'Book', plural: 'Books' },
operations: [new List([])],
stateProvider: new CallbackStateProvider<Book>(() => null),
stateProvider: new CallbackStateProvider<Book>(() => Promise.resolve(null)),
stateProcessor: new CallbackStateProcessor<Book>(() => {})
})
]
Expand Down
2 changes: 2 additions & 0 deletions src/lib/FieldDefinitions/TabsField.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { ComponentType } from 'svelte';
import type { FieldInterface } from '$lib/FieldDefinitions/Field';
import TabsFieldComponent from '$lib/themes/carbon/FormFieldsComponents/TabsField.svelte';
import type { Options } from '$lib/FieldDefinitions/Options';
import CrudViewField from '$lib/themes/carbon/Crud/CrudViewField.svelte';

export type TabOptions = Options & {
headerType: 'default' | 'container';
Expand All @@ -13,6 +14,7 @@ export class TabsField implements FieldInterface<TabOptions> {
public readonly fields: Array<FieldInterface<Options>>;
public readonly options: Partial<TabOptions>;
public readonly formComponent: ComponentType = TabsFieldComponent;
public readonly viewComponent: ComponentType = CrudViewField;

constructor(
name: string,
Expand Down
4 changes: 2 additions & 2 deletions src/lib/Menu/stores.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import {writable} from "svelte/store";
import { writable } from 'svelte/store';

export const sideMenuOpen = writable(true);
export const sideMenuOpen = writable(false);
10 changes: 7 additions & 3 deletions src/lib/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,18 @@ export abstract class DefaultAction implements Action {
}

export class CallbackAction extends DefaultAction {
private readonly _callback: (item?: object|undefined) => void;
private readonly _callback: (item?: object | undefined) => void;

constructor(label: string, icon: Optional<ActionIcon>, callback: (item?: object|undefined) => void) {
constructor(
label: string,
icon: Optional<ActionIcon>,
callback: (item?: object | undefined) => void
) {
super(label, icon);
this._callback = callback;
}

public call(item?: object|undefined): void {
public call(item?: object | undefined): void {
return this._callback.call(null, item);
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/lib/config/adminConfig.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import type { ThemeConfig } from '$lib/themes/ThemeConfig.ts';
import carbon from '$lib/themes/carbon';

export type AdminConfig = {
theme: ThemeConfig;
defaultLocale: string;
autoCloseSideMenu: boolean;
head: {
Expand All @@ -9,6 +13,7 @@ export type AdminConfig = {

export function emptyAdminConfig(): AdminConfig {
return {
theme: carbon,
defaultLocale: 'en',
autoCloseSideMenu: false,
head: {
Expand Down
41 changes: 41 additions & 0 deletions src/lib/themes/ThemeConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import type { ComponentType } from 'svelte';

export type ThemeConfig = {
dashboard: ComponentType;
dataTable: ComponentType;
adminLayout: ComponentType;
crud: {
view: ComponentType;
new: ComponentType;
list: ComponentType;
edit: ComponentType;
delete: ComponentType;
form: ComponentType;
viewField: ComponentType;
formField: ComponentType;
tabsForms: ComponentType;
};
viewFields: {
checkboxViewField: ComponentType;
defaultViewField: ComponentType;
tabsView: ComponentType;
urlViewField: ComponentType;
viewLabel: ComponentType;
};
formFields: {
checkbox: ComponentType;
default: ComponentType;
number: ComponentType;
tabsField: ComponentType;
textarea: ComponentType;
text: ComponentType;
toggle: ComponentType;
url: ComponentType;
};
menu: {
sideMenu: ComponentType;
topLeftMenu: ComponentType;
topMenu: ComponentType;
topRightMenu: ComponentType;
};
};
6 changes: 4 additions & 2 deletions src/lib/themes/carbon/Crud/CrudDelete.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
import { CallbackAction, UrlAction } from '$lib/actions';
import { type CrudOperation, Delete } from '$lib/Crud/Operations';
import type { KeyValueObject } from '$lib/genericTypes';
import type { DashboardDefinition } from '$lib';
export let crud: CrudDefinition<object>;
export let operation: CrudOperation<object>;
export let dashboard: DashboardDefinition<unknown>;
export let operation: CrudOperation<unknown>;
export let crud: CrudDefinition<unknown>;
export let requestParameters: KeyValueObject = {};
const data = crud.options.stateProvider.provide(operation, requestParameters);
Expand Down
4 changes: 3 additions & 1 deletion src/lib/themes/carbon/Crud/CrudEdit.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@
import type { CrudOperation } from '$lib/Crud/Operations';
import type { KeyValueObject } from '$lib/genericTypes';
import type { StateProviderResult } from '$lib/State/Provider';
import type { DashboardDefinition } from '$lib';
export let crud: CrudDefinition<unknown>;
export let dashboard: DashboardDefinition<unknown>;
export let operation: CrudOperation<unknown>;
export let crud: CrudDefinition<unknown>;
export let requestParameters: KeyValueObject = {};
let defaultData: StateProviderResult<unknown> = crud.options.stateProvider.provide(
Expand Down
4 changes: 3 additions & 1 deletion src/lib/themes/carbon/Crud/CrudList.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@
import { _ } from 'svelte-i18n';
import { onMount } from 'svelte';
import type { DashboardDefinition } from '$lib';
export let crud: CrudDefinition<unknown>;
export let dashboard: DashboardDefinition<unknown>;
export let operation: CrudOperation<unknown>;
export let crud: CrudDefinition<unknown>;
export let requestParameters: KeyValueObject = {};
const actions = operation.actions;
Expand Down
2 changes: 2 additions & 0 deletions src/lib/themes/carbon/Crud/CrudNew.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
import type { CrudOperation } from '../../../Crud/Operations';
import type { CrudDefinition } from '../../../Crud/definition';
import type { KeyValueObject } from '../../../genericTypes';
import type { DashboardDefinition } from '../../../Dashboard/definition';
export let dashboard: DashboardDefinition<unknown>;
export let operation: CrudOperation<unknown>;
export let crud: CrudDefinition<unknown>;
export let requestParameters: KeyValueObject = {};
Expand Down
3 changes: 2 additions & 1 deletion src/lib/themes/carbon/Crud/CrudView.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
import type { CrudOperation } from '$lib/Crud/Operations';
import type { KeyValueObject } from '$lib/genericTypes';
import { type CrudDefinition, TabsField } from '$lib';
import { type CrudDefinition, type DashboardDefinition, TabsField } from '$lib';
import type { FieldInterface } from '$lib/FieldDefinitions/Field';
import type { Options } from '$lib/FieldDefinitions/Options';
import type { StateProviderResult } from '$lib/State/Provider';
import TabsView from '$lib/themes/carbon/ViewFieldsComponents/TabsView.svelte';
import CrudViewField from '$lib/themes/carbon/Crud/CrudViewField.svelte';
export let dashboard: DashboardDefinition<unknown>;
export let operation: CrudOperation<unknown>;
export let crud: CrudDefinition<unknown>;
export let requestParameters: KeyValueObject = {};
Expand Down
25 changes: 15 additions & 10 deletions src/lib/themes/carbon/Icon.svelte
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
<script lang="ts">
import type {ActionIcon} from "$lib/actions.ts";
import {SvelteComponent} from "svelte";
import type { ActionIcon } from '$lib/actions';
import { SvelteComponent } from 'svelte';
export let icon: ActionIcon;
export let icon: ActionIcon;
if (!(icon instanceof SvelteComponent) && typeof icon !== 'function' && typeof icon !== 'string') {
console.error(`Wrong icon type: ${typeof icon}`);
}
if (
!(icon instanceof SvelteComponent) &&
typeof icon !== 'function' &&
typeof icon !== 'string' &&
typeof icon.$$render === 'undefined'
) {
console.error(`Wrong icon type: ${typeof icon}`, icon);
}
</script>

{#if icon instanceof SvelteComponent || typeof icon === 'function'}
<svelte:component this={icon} />
{#if icon instanceof SvelteComponent || typeof icon === 'function' || typeof icon.$$render !== 'undefined'}
<svelte:component this={icon} />
{:else if typeof icon === 'string'}
{icon}
{icon}
{:else}
{icon.toString()}
{icon.toString()}
{/if}
2 changes: 1 addition & 1 deletion src/lib/themes/carbon/Layout/AdminLayout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@

<slot name="side_menu">
{#if side_menu_links.length}
<SideMenu autoClose={adminConfig?.autoCloseSideMenu || false} links={side_menu_links} />
<SideMenu links={side_menu_links} />
{/if}
</slot>

Expand Down
4 changes: 2 additions & 2 deletions src/lib/themes/carbon/Menu/SideMenu.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@
import { _ } from 'svelte-i18n';
import { Divider, Submenu } from '$lib/Menu/MenuLinks';
import { sideMenuOpen } from "$lib/Menu/stores.ts";
import { sideMenuOpen } from '$lib/Menu/stores';
import { type Action, CallbackAction, UrlAction } from '$lib/actions';
import Icon from '../Icon.svelte';
export let links: Array<Action> = [];
</script>

<SideNav rail={autoClose} bind:isOpen={$sideMenuOpen}>
<SideNav rail={autoClose} isOpen={$sideMenuOpen}>
<SideNavItems>
{#each links as link}
{#if link instanceof Submenu}
Expand Down
4 changes: 2 additions & 2 deletions src/lib/themes/carbon/Menu/TopMenu.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
import TopLeftMenu from '$lib/themes/carbon/Menu/TopLeftMenu.svelte';
import TopRightMenu from '$lib/themes/carbon/Menu/TopRightMenu.svelte';
import type { MenuLink } from '$lib/Menu/MenuLinks';
import { type AdminConfig, emptyAdminConfig } from '$lib/config/adminConfig';
import { type AdminConfig } from '$lib/config/adminConfig';
export let left_links: Array<MenuLink> = [];
export let right_links: Array<MenuLink> = [];
export let adminConfig: AdminConfig = emptyAdminConfig();
import { sideMenuOpen } from "$lib/Menu/stores.ts";
import { sideMenuOpen } from '$lib/Menu/stores';
</script>

<Header
Expand Down
35 changes: 0 additions & 35 deletions src/lib/themes/carbon/index.js

This file was deleted.

Loading

0 comments on commit d3d5449

Please sign in to comment.