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:
parent
0ea57f15d9
commit
07af57d0ea
4 changed files with 115 additions and 22 deletions
|
@ -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"
|
||||
|
|
|
@ -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, '*');
|
||||
}
|
||||
|
|
|
@ -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 };
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue