0
Fork 0
mirror of https://github.com/penpot/penpot-plugins.git synced 2025-01-06 14:50:21 -05:00

feat(table-plugin): enhancement save config

This commit is contained in:
María Valderrama 2024-08-21 13:52:07 +02:00
parent 0ea57f15d9
commit 07af57d0ea
4 changed files with 115 additions and 22 deletions

View file

@ -1,4 +1,4 @@
<div>
<div [formGroup]="form">
<p class="text body-s">Import a data file (CSV)</p>
<div class="error" *ngIf="fileError">
<img
@ -32,7 +32,7 @@
<div class="checkbox-container">
<input
[(ngModel)]="tableOptions.borders"
formControlName="borders"
class="checkbox-input"
type="checkbox"
id="tableBorders"
@ -43,7 +43,7 @@
</div>
<div class="checkbox-container">
<input
[(ngModel)]="tableOptions.alternateRows"
formControlName="alternateRows"
class="checkbox-input"
type="checkbox"
id="alternateRow"
@ -53,7 +53,7 @@
</div>
<div class="checkbox-container">
<input
[(ngModel)]="tableOptions.filledHeaderRow"
formControlName="filledHeaderRow"
class="checkbox-input"
type="checkbox"
id="filledHeaderRow"
@ -63,7 +63,7 @@
</div>
<div class="checkbox-container">
<input
[(ngModel)]="tableOptions.filledHeaderColumn"
formControlName="filledHeaderColumn"
class="checkbox-input"
type="checkbox"
id="filledHeaderColumn"

View file

@ -1,14 +1,19 @@
import { Component, inject } from '@angular/core';
import { ActivatedRoute, RouterModule } from '@angular/router';
import { toSignal } from '@angular/core/rxjs-interop';
import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
import { CommonModule } from '@angular/common';
import type { Cell, PluginMessageEvent, TableOptions } from '../app/model';
import type {
Cell,
PluginMessageEvent,
TableConfigEvent,
TableOptions,
} from '../app/model';
import { filter, fromEvent, map, merge, take } from 'rxjs';
import { FormsModule } from '@angular/forms';
import { FormBuilder, ReactiveFormsModule, FormGroup } from '@angular/forms';
@Component({
standalone: true,
imports: [RouterModule, CommonModule, FormsModule],
imports: [RouterModule, CommonModule, ReactiveFormsModule],
selector: 'app-root',
templateUrl: './app.component.html',
styleUrl: './app.component.css',
@ -17,19 +22,22 @@ import { FormsModule } from '@angular/forms';
},
})
export class AppComponent {
private readonly fb = inject(FormBuilder);
public table: string[][] = [];
public cells = [...Array(48).keys()];
public selectedRow = 0;
public selectedColumn = 0;
public selectedCell: Cell | undefined;
public tableOptions: TableOptions = {
filledHeaderRow: true,
filledHeaderColumn: false,
borders: true,
alternateRows: true,
};
public fileError = false;
public form: FormGroup = this.fb.group({
filledHeaderRow: [false],
filledHeaderColumn: [false],
borders: [false],
alternateRows: [false],
});
route = inject(ActivatedRoute);
messages$ = fromEvent<MessageEvent<PluginMessageEvent>>(window, 'message');
@ -51,6 +59,10 @@ export class AppComponent {
)
);
constructor() {
this.initConfig();
}
onSelectFile(event: Event) {
const target = event.target as HTMLInputElement;
if (
@ -71,7 +83,7 @@ export class AppComponent {
content: {
import: this.table,
type: 'import',
options: this.tableOptions,
options: this.form.value,
},
type: 'table',
});
@ -87,7 +99,7 @@ export class AppComponent {
content: {
new: { column: data.column, row: data.row },
type: 'new',
options: this.tableOptions,
options: this.form.value,
},
type: 'table',
});
@ -117,6 +129,54 @@ export class AppComponent {
};
}
private initConfig(): void {
this.messages$
.pipe(
filter(
(event) =>
event.data.type === 'tableconfig' &&
event.data.content.type === 'retrieve'
),
take(1),
map((event) => {
const data = (event.data as TableConfigEvent).content.options;
return data;
})
)
.subscribe((data) => {
if (data) {
this.form.patchValue(data, { emitEvent: false });
} else {
this.form.patchValue({
filledHeaderRow: true,
filledHeaderColumn: false,
borders: true,
alternateRows: true,
});
}
});
this.form.valueChanges
.pipe(takeUntilDestroyed())
.subscribe((options: TableOptions) => {
this.sendMessage({
type: 'tableconfig',
content: {
type: 'save',
options,
},
});
});
this.sendMessage({
type: 'tableconfig',
content: {
type: 'retrieve',
},
});
}
private sendMessage(message: PluginMessageEvent): void {
parent.postMessage(message, '*');
}

View file

@ -5,6 +5,14 @@ export interface InitPluginEvent {
};
}
export interface TableConfigEvent {
type: 'tableconfig';
content: {
type: 'save' | 'retrieve';
options?: TableOptions;
};
}
export interface TablePluginEvent {
type: 'table';
content: {
@ -23,7 +31,8 @@ export interface ThemePluginEvent {
export type PluginMessageEvent =
| InitPluginEvent
| TablePluginEvent
| ThemePluginEvent;
| ThemePluginEvent
| TableConfigEvent;
export type Cell = { column: number; row: number };

View file

@ -6,11 +6,9 @@ penpot.ui.open('TABLE PLUGIN', `?theme=${penpot.getTheme()}`, {
height: 610,
});
penpot.on('themechange', (theme) => {
penpot.ui.sendMessage({ type: 'theme', content: theme });
});
penpot.ui.onMessage<PluginMessageEvent>((message) => {
pluginData(message);
if (message.type === 'table') {
let numRows = 0;
let numCols = 0;
@ -217,3 +215,29 @@ function createFlexCell(
}
}
}
function pluginData(message: PluginMessageEvent) {
if (message.type === 'tableconfig') {
const { type, options } = message.content;
const page = penpot.getPage();
if (type === 'save') {
page?.setPluginData('table-plugin', JSON.stringify(options));
} else if (message.content.type === 'retrieve') {
const data = page?.getPluginData('table-plugin');
const options = data ? JSON.parse(data) : null;
sendMessage({
type: 'tableconfig',
content: {
type: 'retrieve',
options,
},
});
}
}
}
function sendMessage(message: PluginMessageEvent) {
penpot.ui.sendMessage(message);
}