Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

- **DOMTable class** for creating HTML table structures
- `createTable()` - Create table element
- `createTableHead()` - Create thead element
- `createTableBody()` - Create tbody element
- `createTableFoot()` - Create tfoot element
- `createTableRow()` - Create tr element
- `createTableHeader()` - Create th element with scope support
- `createTableCell()` - Create td element with colspan/rowspan support
- `createCaption()` - Create caption element

- **DOMMedia class** for creating media elements
- `createImage()` - Create img element with src, alt, width, height, and loading attributes

- **DOMSemantic class** for creating semantic HTML5 elements
- `createArticle()` - Create article element
- `createSection()` - Create section element
- `createNav()` - Create nav element
- `createHeader()` - Create header element
- `createFooter()` - Create footer element
- `createAside()` - Create aside element
- `createMain()` - Create main element

- **Enhanced DOMNested class** with additional list types
- `createOrderedList()` - Create ol element
- `createDefinitionList()` - Create dl element
- `createDefinitionTerm()` - Create dt element
- `createDefinitionDescription()` - Create dd element

- **Enhanced DOMInput class** with select dropdown support
- `createSelect()` - Create select element with onChange handler support
- `createOption()` - Create option element with value and selected attributes
- `createOptgroup()` - Create optgroup element for grouping options

- **Example plugin** (`examples/dom_elements_plugin.ts`) demonstrating all new DOM element capabilities

- **Comprehensive test coverage** for all new DOM classes and methods
- Unit tests for DOMTable, DOMMedia, DOMSemantic
- Enhanced tests for DOMNested and DOMInput
- Integration tests demonstrating real-world usage

### Changed

- Updated README.md with comprehensive documentation of new DOM element capabilities
- Updated index.ts to export new DOM classes (DOMTable, DOMMedia, DOMSemantic)

### Technical Details

- All new DOM classes extend the base DOM class and follow existing architecture patterns
- Full TypeScript type safety with strict mode enabled
- JSDoc documentation with @uiName tags for all public methods
- CSS-in-JS integration via goober for styling support
- Custom attributes support for all new elements
- Event handler support for interactive elements
- Maintains backward compatibility with existing DOM classes

## [1.0.15] - Previous Release

- Initial release with core DOM classes (DOMText, DOMButton, DOMInput, DOMLink, DOMNested, DOMMisc)
- Plugin framework with FDO_SDK base class
- IPC communication system
- Storage backends (StoreDefault, StoreJson)
- Logging and system integration utilities
101 changes: 100 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,102 @@
# SDK for FlexDevOPs Application modules

Information about how to test example plugin is at examples/example_plugin.ts
## Overview

The FDO SDK provides a comprehensive toolkit for building application modules (plugins) for the FlexDevOps (FDO) desktop application ecosystem. This SDK enables developers to create modular extensions with rich UI capabilities using server-side HTML generation.

## Features

### DOM Element Generation

The SDK provides extensive DOM element creation capabilities through specialized classes:

- **DOMTable**: Create HTML tables with thead, tbody, tfoot, tr, th, td, and caption elements
- **DOMMedia**: Create media elements including images with accessibility support
- **DOMSemantic**: Create semantic HTML5 elements (article, section, nav, header, footer, aside, main)
- **DOMNested**: Create container elements including ordered lists (ol), definition lists (dl, dt, dd), and more
- **DOMInput**: Create form inputs including select dropdowns with options and optgroups
- **DOMText**: Create text elements (headings, paragraphs, spans, etc.)
- **DOMButton**: Create button elements with event handlers
- **DOMLink**: Create anchor elements
- **DOMMisc**: Create miscellaneous elements like horizontal rules

All DOM classes support:
- Custom CSS styling via goober CSS-in-JS
- Custom classes and inline styles
- Custom HTML attributes
- Event handlers
- Accessibility attributes

### Plugin Framework

- **FDO_SDK Base Class**: Abstract base class with lifecycle hooks (init, render)
- **IPC Communication**: Message-based communication between plugin workers and main application
- **Data Persistence**: Multiple storage backends (in-memory, JSON file-based)
- **System Integration**: Logging, file operations, and privilege elevation

## Getting Started

### Installation

```bash
npm install @anikitenko/fdo-sdk
```

### Creating a Plugin

```typescript
import { FDO_SDK, FDOInterface, PluginMetadata } from "@anikitenko/fdo-sdk";

export default class MyPlugin extends FDO_SDK implements FDOInterface {
private readonly _metadata: PluginMetadata = {
name: "My Plugin",
version: "1.0.0",
author: "Your Name",
description: "Plugin description",
icon: "icon.png"
};

get metadata(): PluginMetadata {
return this._metadata;
}

init(): void {
this.log("MyPlugin initialized!");
}

render(): string {
return "<div>Hello World</div>";
}
}
```

### Example Usage

See `examples/example_plugin.ts` for a basic plugin example.

See `examples/dom_elements_plugin.ts` for comprehensive examples of using the new DOM element creation capabilities including tables, media, semantic HTML, lists, and form controls.

## Development

### Building

```bash
npm run build # Build webpack bundle
npm run build:types # Generate TypeScript declarations
```

### Testing

```bash
npm test # Run Jest tests
```

## Documentation

- Full API documentation is available in the TypeScript declaration files
- All public methods include JSDoc comments with usage examples
- See the `examples/` directory for working plugin implementations

## License

ISC
125 changes: 125 additions & 0 deletions examples/dom_elements_plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import { FDO_SDK, FDOInterface, PluginMetadata, DOMTable, DOMMedia, DOMSemantic, DOMNested, DOMInput } from "../src";

/**
* Example plugin demonstrating the new DOM element creation capabilities.
* This plugin showcases tables, media elements, semantic HTML5 structures,
* ordered/definition lists, and select dropdowns.
*/
export default class DOMElementsExamplePlugin extends FDO_SDK implements FDOInterface {
private readonly _metadata: PluginMetadata = {
name: "DOM Elements Example",
version: "1.0.0",
author: "FDO SDK Team",
description: "Example plugin demonstrating new DOM element creation capabilities",
icon: "dom-icon.png"
};

get metadata(): PluginMetadata {
return this._metadata;
}

init(): void {
this.log("DOM Elements Example Plugin initialized!");
}

render(): string {
const domTable = new DOMTable();
const domMedia = new DOMMedia();
const domSemantic = new DOMSemantic();
const domNested = new DOMNested();
const domInput = new DOMInput("example-select", {});

const tableHeader1 = domTable.createTableHeader(["Name"], {}, undefined, { scope: "col" });
const tableHeader2 = domTable.createTableHeader(["Age"], {}, undefined, { scope: "col" });
const tableHeader3 = domTable.createTableHeader(["Role"], {}, undefined, { scope: "col" });
const headerRow = domTable.createTableRow([tableHeader1, tableHeader2, tableHeader3]);
const thead = domTable.createTableHead([headerRow]);

const cell1 = domTable.createTableCell(["John Doe"]);
const cell2 = domTable.createTableCell(["30"]);
const cell3 = domTable.createTableCell(["Developer"]);
const dataRow1 = domTable.createTableRow([cell1, cell2, cell3]);

const cell4 = domTable.createTableCell(["Jane Smith"]);
const cell5 = domTable.createTableCell(["28"]);
const cell6 = domTable.createTableCell(["Designer"]);
const dataRow2 = domTable.createTableRow([cell4, cell5, cell6]);

const tbody = domTable.createTableBody([dataRow1, dataRow2]);
const caption = domTable.createCaption(["Employee Directory"]);
const table = domTable.createTable([caption, thead, tbody], { classes: ["employee-table"] });

const image = domMedia.createImage(
"/assets/logo.png",
"Company Logo",
{ classes: ["logo-image"] },
undefined,
{ width: "200", height: "100", loading: "lazy" }
);

const header = domSemantic.createHeader(["<h1>Welcome to FDO SDK</h1>"]);
const nav = domSemantic.createNav([
"<a href='/'>Home</a>",
"<a href='/docs'>Documentation</a>",
"<a href='/examples'>Examples</a>"
]);
const article = domSemantic.createArticle([
"<h2>New DOM Elements</h2>",
"<p>This plugin demonstrates the new DOM element creation capabilities.</p>"
]);
const aside = domSemantic.createAside(["<h3>Quick Links</h3><ul><li>API Reference</li></ul>"]);
const footer = domSemantic.createFooter(["<p>&copy; 2025 FDO SDK</p>"]);

const listItem1 = domNested.createListItem(["Install the SDK"]);
const listItem2 = domNested.createListItem(["Create your plugin"]);
const listItem3 = domNested.createListItem(["Build and test"]);
const orderedList = domNested.createOrderedList([listItem1, listItem2, listItem3], { classes: ["steps-list"] });

const term1 = domNested.createDefinitionTerm(["FDO"]);
const desc1 = domNested.createDefinitionDescription(["FlexDevOps - A desktop application framework"]);
const term2 = domNested.createDefinitionTerm(["SDK"]);
const desc2 = domNested.createDefinitionDescription(["Software Development Kit"]);
const definitionList = domNested.createDefinitionList([term1, desc1, term2, desc2], { classes: ["glossary"] });

const option1 = new DOMInput("", {}).createOption("Select an option", "", true);
const option2 = new DOMInput("", {}).createOption("Option A", "a");
const option3 = new DOMInput("", {}).createOption("Option B", "b");
const option4 = new DOMInput("", {}).createOption("Option C", "c");
const select = domInput.createSelect([option1, option2, option3, option4], () => {
console.log("Selection changed");
});

const groupOpt1 = new DOMInput("", {}).createOption("Item 1", "1");
const groupOpt2 = new DOMInput("", {}).createOption("Item 2", "2");
const optgroup1 = new DOMInput("", {}).createOptgroup("Group 1", [groupOpt1, groupOpt2]);

const groupOpt3 = new DOMInput("", {}).createOption("Item 3", "3");
const groupOpt4 = new DOMInput("", {}).createOption("Item 4", "4");
const optgroup2 = new DOMInput("", {}).createOptgroup("Group 2", [groupOpt3, groupOpt4]);

const groupedSelect = new DOMInput("grouped-select", {}).createSelect([optgroup1, optgroup2]);

const mainContent = domSemantic.createMain([
header,
nav,
"<h2>Example 1: Data Table</h2>",
table,
"<h2>Example 2: Image</h2>",
image,
"<h2>Example 3: Semantic Structure</h2>",
article,
aside,
"<h2>Example 4: Ordered List</h2>",
orderedList,
"<h2>Example 5: Definition List</h2>",
definitionList,
"<h2>Example 6: Select Dropdown</h2>",
select,
"<h2>Example 7: Grouped Select</h2>",
groupedSelect,
footer
]);

return mainContent;
}
}
17 changes: 17 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,23 @@
export default {
preset: 'ts-jest',
testEnvironment: 'node',
// Collect coverage for source files and report in lcov + text formats
collectCoverage: true,
coverageDirectory: '<rootDir>/coverage',
coverageReporters: ['text', 'lcov'],
collectCoverageFrom: [
'src/**/*.{ts,js}',
'!src/**/*.d.ts',
'!src/**/index.{ts,js}'
],
coverageThreshold: {
global: {
branches: 80,
functions: 80,
lines: 80,
statements: 80
}
},
transform: {
"^.+\\.ts$": "ts-jest", // TS handled by ts-jest
"^.+\\.js$": "babel-jest", // JS (e.g., pify) handled by babel
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"type": "git",
"url": "https://github.com/anikitenko/fdo-sdk.git"
},
"version": "1.0.15",
"version": "1.0.16",
"description": "SDK for FlexDevOPs (FDO) application modules",
"keywords": [
"fdo",
Expand All @@ -26,10 +26,12 @@
"files": [
"dist"
],
"scripts": {
"scripts": {
"build": "webpack --config webpack.config.cjs",
"build:types": "tsc --emitDeclarationOnly",
"test": "jest"
"test": "jest",
"test:coverage": "jest --coverage",
"coverage:open": "npx opn coverage/lcov-report/index.html || true"
},
"devDependencies": {
"@babel/core": "^7.26.10",
Expand Down
Loading