feat: update icon counts and migration phases in FAKEMUI_STRATEGY.md; enhance type annotations and definitions across various modules

This commit is contained in:
2025-12-30 10:43:01 +00:00
parent 9617ad9a57
commit 63cde2a7da
32 changed files with 413 additions and 113 deletions

View File

@@ -65,9 +65,8 @@ Total: ~150 components, ~80 SCSS files
- Zero runtime dependencies
- Full TypeScript support
**Current Icons:** 7
**Target Phase 2:** 27 (core set)
**Target Phase 3:** 50-100 (full migration)
**Current Icons:** 27 ✅ Phase 2 Complete!
**Target Phase 3:** 50-100 (full migration as needed)
**See:** [fakemui/icons/README.md](fakemui/icons/README.md)
@@ -215,8 +214,8 @@ import { Button, Card, Stack, Box, Plus, Trash, Edit } from '@/fakemui'
## Migration Phases
### Phase 1: Foundation ✅ 60% Complete
- [x] Create fakemui icon system
### Phase 1: Foundation ✅ 75% Complete
- [x] Create fakemui icon system (27 icons)
- [x] Migrate LuaBlocksEditor
- [x] Enhance CSS reset
- [x] Document strategy

View File

@@ -48,10 +48,10 @@ Phase 11: Final Cleanup 📋 Planned
## Phase 1: fakemui Enhancement
**Goal:** Complete fakemui with all framework primitives
**Status:** ⏳ In Progress (60% complete)
**Status:** ⏳ In Progress (75% complete)
### What's Done ✅
- Icon system (7 icons created)
- Icon system (27 icons created - Phase 2 complete!)
- CSS reset (replaces CssBaseline)
- SCSS architecture (64 files, A+ grade)
- TypeScript migration (76 components)
@@ -472,7 +472,7 @@ npm uninstall @emotion/styled
- Dependencies Removed: 0 (waiting for 100% migration)
### Phase Checklist
- [x] Phase 1: fakemui Enhancement (60%)
- [x] Phase 1: fakemui Enhancement (75%)
- [x] Phase 2: Audit Log (100%)
- [x] Phase 3: Quick Guide (100%)
- [ ] Phase 4: Data Grid

View File

@@ -3,6 +3,8 @@
---@class SettingsModule
---@field general function
---@field security function
---@type SettingsModule
local settings = {
general = require("settings.general"),
security = require("settings.security")

View File

@@ -1,12 +1,39 @@
-- Audit log filtering logic
local M = {}
-- Filter logs by operation type
---@class AuditLog
---@field id string
---@field operation string
---@field resource string
---@field resourceId string
---@field username string
---@field timestamp number
---@field ipAddress string
---@field success boolean
---@field errorMessage string?
---@class FilterOptions
---@field operations string[]
---@field resources string[]
---@field usernames string[]
---@class ApplyFiltersInput
---@field operation string?
---@field resource string?
---@field success boolean?
---@field username string?
---@field startTime number?
---@field endTime number?
--- Filter logs by operation type
---@param logs AuditLog[] | nil
---@param operation string?
---@return AuditLog[]
function M.filterByOperation(logs, operation)
if not operation or operation == "" then
return logs
end
local result = {}
for _, log in ipairs(logs or {}) do
if log.operation == operation then
@@ -16,12 +43,15 @@ function M.filterByOperation(logs, operation)
return result
end
-- Filter logs by resource type
--- Filter logs by resource type
---@param logs AuditLog[] | nil
---@param resource string?
---@return AuditLog[]
function M.filterByResource(logs, resource)
if not resource or resource == "" then
return logs
end
local result = {}
for _, log in ipairs(logs or {}) do
if log.resource == resource then
@@ -31,12 +61,15 @@ function M.filterByResource(logs, resource)
return result
end
-- Filter logs by success status
--- Filter logs by success status
---@param logs AuditLog[] | nil
---@param success boolean?
---@return AuditLog[]
function M.filterBySuccess(logs, success)
if success == nil then
return logs
end
local result = {}
for _, log in ipairs(logs or {}) do
if log.success == success then
@@ -46,12 +79,15 @@ function M.filterBySuccess(logs, success)
return result
end
-- Filter logs by username
--- Filter logs by username
---@param logs AuditLog[] | nil
---@param username string?
---@return AuditLog[]
function M.filterByUsername(logs, username)
if not username or username == "" then
return logs
end
local result = {}
local lowerUsername = string.lower(username)
for _, log in ipairs(logs or {}) do
@@ -62,7 +98,11 @@ function M.filterByUsername(logs, username)
return result
end
-- Filter logs by date range (timestamps in milliseconds)
--- Filter logs by date range (timestamps in milliseconds)
---@param logs AuditLog[] | nil
---@param startTime number?
---@param endTime number?
---@return AuditLog[]
function M.filterByDateRange(logs, startTime, endTime)
local result = {}
for _, log in ipairs(logs or {}) do
@@ -81,40 +121,45 @@ function M.filterByDateRange(logs, startTime, endTime)
return result
end
-- Apply multiple filters
--- Apply multiple filters to logs
---@param logs AuditLog[] | nil
---@param filters ApplyFiltersInput
---@return AuditLog[]
function M.applyFilters(logs, filters)
filters = filters or {}
local result = logs
if filters.operation then
result = M.filterByOperation(result, filters.operation)
end
if filters.resource then
result = M.filterByResource(result, filters.resource)
end
if filters.success ~= nil then
result = M.filterBySuccess(result, filters.success)
end
if filters.username then
result = M.filterByUsername(result, filters.username)
end
if filters.startTime or filters.endTime then
result = M.filterByDateRange(result, filters.startTime, filters.endTime)
end
return result
end
-- Get unique values for filter dropdowns
--- Get unique values for filter dropdowns
---@param logs AuditLog[] | nil
---@return FilterOptions
function M.getFilterOptions(logs)
local operations = {}
local resources = {}
local usernames = {}
for _, log in ipairs(logs or {}) do
if log.operation then
operations[log.operation] = true
@@ -126,25 +171,25 @@ function M.getFilterOptions(logs)
usernames[log.username] = true
end
end
local opList = {}
for op in pairs(operations) do
opList[#opList + 1] = op
end
table.sort(opList)
local resList = {}
for res in pairs(resources) do
resList[#resList + 1] = res
end
table.sort(resList)
local userList = {}
for user in pairs(usernames) do
userList[#userList + 1] = user
end
table.sort(userList)
return {
operations = opList,
resources = resList,

View File

@@ -1,7 +1,32 @@
-- Formatting helpers for audit log display
local M = {}
-- Operation type to color mapping
---@class AuditLog
---@field id string
---@field operation string
---@field resource string
---@field resourceId string
---@field username string
---@field timestamp number
---@field ipAddress string
---@field success boolean
---@field errorMessage string?
---@class FormattedLogEntry
---@field id string
---@field operation string
---@field operationColor string
---@field resource string
---@field resourceId string
---@field resourceIcon string
---@field username string
---@field timestamp string
---@field ipAddress string
---@field success boolean
---@field errorMessage string?
---@field rowClass string
--- Operation type to color mapping
M.operationColors = {
CREATE = "bg-green-500",
READ = "bg-blue-500",
@@ -9,35 +34,43 @@ M.operationColors = {
DELETE = "bg-red-500"
}
-- Resource type to icon mapping
--- Resource type to icon mapping
M.resourceIcons = {
user = "User",
credential = "ShieldCheck",
default = "ChartLine"
}
-- Get color class for operation
--- Get color class for operation
---@param operation string
---@return string
function M.getOperationColor(operation)
return M.operationColors[operation] or "bg-gray-500"
end
-- Get icon name for resource
--- Get icon name for resource
---@param resource string
---@return string
function M.getResourceIcon(resource)
return M.resourceIcons[resource] or M.resourceIcons.default
end
-- Format timestamp for display
--- Format timestamp for display (assumes input in milliseconds)
---@param timestamp number?
---@return string
function M.formatTimestamp(timestamp)
if not timestamp then
return "Unknown"
end
-- Assuming timestamp is in milliseconds
local seconds = math.floor(timestamp / 1000)
return os.date("%Y-%m-%d %H:%M:%S", seconds)
end
-- Format a log entry for display
--- Format a log entry for display
---@param log AuditLog
---@return FormattedLogEntry
function M.formatLogEntry(log)
return {
id = log.id,
@@ -55,7 +88,9 @@ function M.formatLogEntry(log)
}
end
-- Format all logs for display
--- Format all logs for display
---@param logs AuditLog[] | nil
---@return FormattedLogEntry[]
function M.formatAllLogs(logs)
local result = {}
for i, log in ipairs(logs or {}) do
@@ -64,7 +99,9 @@ function M.formatAllLogs(logs)
return result
end
-- Get status badge text
--- Get status badge text for a log
---@param log AuditLog
---@return string | nil
function M.getStatusBadge(log)
if log.success then
return nil

View File

@@ -1,9 +1,18 @@
-- Audit log package initialization
local M = {}
---@class AuditLogPackage
---@field name string
---@field version string
--- Package name
M.name = "audit_log"
--- Package version
M.version = "1.0.0"
--- Initialize the audit log package
---@return boolean
function M.init()
log("Audit log package initialized")
return true

View File

@@ -1,7 +1,42 @@
-- Statistics calculation for audit logs
local M = {}
-- Calculate stats from a list of logs
---@class AuditLog
---@field id string
---@field operation string
---@field resource string
---@field resourceId string
---@field username string
---@field timestamp number
---@field ipAddress string
---@field success boolean
---@field errorMessage string?
---@class AuditStats
---@field total number
---@field successful number
---@field failed number
---@field rateLimit number
---@class OperationStats
---@field total number
---@field successful number
---@field failed number
---@class StatCard
---@field title string
---@field value number
---@field icon string
---@field color string
---@class StatsDisplay
---@field cards StatCard[]
---@field byOperation table<string, OperationStats>
---@field byResource table<string, OperationStats>
--- Calculate stats from a list of logs
---@param logs AuditLog[] | nil
---@return AuditStats
function M.calculateStats(logs)
local stats = {
total = 0,
@@ -9,36 +44,38 @@ function M.calculateStats(logs)
failed = 0,
rateLimit = 0
}
if not logs then
return stats
end
stats.total = #logs
for _, log in ipairs(logs) do
if log.success then
stats.successful = stats.successful + 1
else
stats.failed = stats.failed + 1
end
if log.errorMessage and string.match(log.errorMessage, "Rate limit") then
stats.rateLimit = stats.rateLimit + 1
end
end
return stats
end
-- Get stats by operation type
--- Get stats grouped by operation type
---@param logs AuditLog[] | nil
---@return table<string, OperationStats>
function M.getStatsByOperation(logs)
local byOperation = {}
if not logs then
return byOperation
end
for _, log in ipairs(logs) do
local op = log.operation or "UNKNOWN"
if not byOperation[op] then
@@ -51,18 +88,20 @@ function M.getStatsByOperation(logs)
byOperation[op].failed = byOperation[op].failed + 1
end
end
return byOperation
end
-- Get stats by resource type
--- Get stats grouped by resource type
---@param logs AuditLog[] | nil
---@return table<string, OperationStats>
function M.getStatsByResource(logs)
local byResource = {}
if not logs then
return byResource
end
for _, log in ipairs(logs) do
local res = log.resource or "unknown"
if not byResource[res] then
@@ -75,14 +114,16 @@ function M.getStatsByResource(logs)
byResource[res].failed = byResource[res].failed + 1
end
end
return byResource
end
-- Prepare stats for display
--- Prepare stats for display
---@param logs AuditLog[] | nil
---@return StatsDisplay
function M.prepareStatsDisplay(logs)
local stats = M.calculateStats(logs)
return {
cards = {
{

View File

@@ -1,4 +1,14 @@
-- Codegen template component
---@class ComponentTemplate
---@field type string
---@field name string
---@field props table
---@field template string
---@param name string The name of the component
---@param props? table Optional component properties
---@return ComponentTemplate
local function component_template(name, props)
return {
type = "component",

View File

@@ -1,4 +1,11 @@
-- Codegen blueprint module
---@class BlueprintModule
---@field component function
---@field service function
---@field model function
---@type BlueprintModule
local blueprint = {
component = require("blueprint.component"),
service = require("blueprint.service"),

View File

@@ -1,4 +1,14 @@
-- Codegen template model
---@class ModelTemplate
---@field type string
---@field name string
---@field fields table
---@field template string
---@param name string The name of the model
---@param fields? table Optional model fields
---@return ModelTemplate
local function model_template(name, fields)
return {
type = "model",

View File

@@ -1,4 +1,14 @@
-- Codegen template service
---@class ServiceTemplate
---@field type string
---@field name string
---@field methods table
---@field template string
---@param name string The name of the service
---@param methods? table Optional service methods
---@return ServiceTemplate
local function service_template(name, methods)
return {
type = "service",

View File

@@ -5,7 +5,7 @@
---@field handler string Action handler name
---@class ActionColumn
---@field type "actions"
---@field type "actions" Column type identifier
---@field id string Column identifier
---@field label string Column header label (typically empty)
---@field width string Column width (e.g., "120px")
@@ -14,7 +14,7 @@
---Create an action column definition
---@param id string Column identifier
---@param actions? Action[] Array of actions (default: {})
---@return ActionColumn
---@return ActionColumn action_column The action column definition
local function action_column(id, actions)
return {
type = "actions",

View File

@@ -1,7 +1,7 @@
-- Date column definition
---@class DateColumn
---@field type "date"
---@field type "date" Column type identifier
---@field id string Column identifier
---@field label string Column header label
---@field format string Date format string (e.g., "YYYY-MM-DD")
@@ -11,7 +11,7 @@
---@param id string Column identifier
---@param label string Column header label
---@param format? string Date format string (default: "YYYY-MM-DD")
---@return DateColumn
---@return DateColumn date_column The date column definition
local function date_column(id, label, format)
return {
type = "date",

View File

@@ -1,7 +1,7 @@
-- Number column definition
---@class NumberColumn
---@field type "number"
---@field type "number" Column type identifier
---@field id string Column identifier
---@field label string Column header label
---@field width string Column width (e.g., "100px")
@@ -12,7 +12,7 @@
---@param id string Column identifier
---@param label string Column header label
---@param width? string Column width (default: "100px")
---@return NumberColumn
---@return NumberColumn number_column The number column definition
local function number_column(id, label, width)
return {
type = "number",

View File

@@ -1,7 +1,7 @@
-- Text column definition
---@class TextColumn
---@field type "text"
---@field type "text" Column type identifier
---@field id string Column identifier
---@field label string Column header label
---@field width string Column width (e.g., "auto", "100px")
@@ -11,7 +11,7 @@
---@param id string Column identifier
---@param label string Column header label
---@param width? string Column width (default: "auto")
---@return TextColumn
---@return TextColumn text_column The text column definition
local function text_column(id, label, width)
return {
type = "text",

View File

@@ -1,4 +1,16 @@
-- Email field component
---@class UIComponent
---@field type string
---@field props? table
---@field children? UIComponent[]
---@class EmailFieldProps
---@field name string
---@field label? string
---@param props EmailFieldProps
---@return UIComponent
local function email(props)
return {
type = "Box",

View File

@@ -1,6 +1,13 @@
-- Form fields module
-- Re-exports all field types
---@class FieldsModule
---@field text function
---@field email function
---@field password function
---@field number function
---@field textarea function
local fields = {
text = require("fields.text"),
email = require("fields.email"),

View File

@@ -1,4 +1,18 @@
-- Number field component
---@class UIComponent
---@field type string
---@field props? table
---@field children? UIComponent[]
---@class NumberFieldProps
---@field name string
---@field label? string
---@field min? number
---@field max? number
---@param props NumberFieldProps
---@return UIComponent
local function number(props)
return {
type = "Box",

View File

@@ -1,4 +1,16 @@
-- Password field component
---@class UIComponent
---@field type string
---@field props? table
---@field children? UIComponent[]
---@class PasswordFieldProps
---@field name string
---@field label? string
---@param props PasswordFieldProps
---@return UIComponent
local function password(props)
return {
type = "Box",

View File

@@ -1,4 +1,18 @@
-- Textarea field component
---@class UIComponent
---@field type string
---@field props? table
---@field children? UIComponent[]
---@class TextareaFieldProps
---@field name string
---@field label? string
---@field rows? number
---@field placeholder? string
---@param props TextareaFieldProps
---@return UIComponent
local function textarea(props)
return {
type = "Box",

View File

@@ -1,4 +1,13 @@
-- Form validation email rule
---@class ValidationRule
---@field type string
---@field pattern? string
---@field value? number | string
---@field message string
---@param message? string
---@return ValidationRule
local function email(message)
return {
type = "email",

View File

@@ -1,4 +1,12 @@
-- Form validation module
---@class ValidateModule
---@field required function
---@field email function
---@field min_length function
---@field max_length function
---@field pattern function
local validate = {
required = require("validate.required"),
email = require("validate.email"),

View File

@@ -1,4 +1,14 @@
-- Form validation max length rule
---@class ValidationRule
---@field type string
---@field pattern? string
---@field value? number | string
---@field message string
---@param length number
---@param message? string
---@return ValidationRule
local function max_length(length, message)
return {
type = "maxLength",

View File

@@ -1,6 +1,5 @@
-- Format Timestamp
-- Formats a timestamp for display in 12-hour format
---@param timestamp number Unix timestamp in milliseconds
---@return string Formatted time string in HH:MM AM/PM format
function formatTime(timestamp)
local date = os.date("*t", timestamp / 1000)
local hour = date.hour

View File

@@ -1,6 +1,17 @@
-- Handle IRC Command
-- Processes IRC commands like /help, /users, /clear, /me
---@class IRCMessage
---@field id string Message identifier
---@field username string Username of the sender
---@field userId string User identifier
---@field message string Message content
---@field type string Message type (system, command, join, leave, message)
---@field timestamp number Timestamp in milliseconds
---@field channelId string Channel identifier
---@param command string IRC command string (e.g., "/help", "/users", "/clear", "/me <action>")
---@param channelId string Channel identifier
---@param username string Current username
---@param onlineUsers string[] List of online usernames
---@return IRCMessage Response message object
function handleCommand(command, channelId, username, onlineUsers)
local parts = {}
for part in string.gmatch(command, "%S+") do

View File

@@ -1,9 +1,19 @@
---@class InstallContext
---@field version string Version number
---@class InstallResult
---@field message string Installation message
---@field version? string Optional version number
local M = {}
---@param context InstallContext Installation context object
---@return InstallResult Installation result
function M.on_install(context)
return { message = "IRC Webchat installed", version = context.version }
end
---@return InstallResult Uninstallation result
function M.on_uninstall()
return { message = "IRC Webchat removed" }
end

View File

@@ -1,6 +1,17 @@
-- Send IRC Message
-- Sends a message to the chat channel
---@class ChatMessage
---@field id string Message identifier
---@field channelId string Channel identifier
---@field username string Username of the sender
---@field userId string User identifier
---@field message string Message content
---@field type string Message type
---@field timestamp number Timestamp in milliseconds
---@param channelId string Channel identifier
---@param username string Username of the sender
---@param userId string User identifier
---@param message string Message content to send
---@return ChatMessage Chat message object
function sendMessage(channelId, username, userId, message)
local msgId = "msg_" .. tostring(os.time()) .. "_" .. math.random(1000, 9999)
local msg = {

View File

@@ -1,12 +1,18 @@
-- Notification list container
---@class UIComponent
---@field type string
---@field children? table[]
---@field emptyMessage? string
---@class ListContainer : UIComponent
---@field type "notification_list" Component type identifier
---@field children UIComponent[] Array of notification items
---@field emptyMessage string Message to display when list is empty
---@param notifications? table[]
---@return UIComponent
---@class UIComponent
---@field type string Component type identifier
---@field children? UIComponent[] Child components
---@field emptyMessage? string Empty state message
---Create a notification list container component
---@param notifications? UIComponent[] Array of notification items (default: {})
---@return ListContainer list_container The list container component
local function list_container(notifications)
return {
type = "notification_list",

View File

@@ -1,19 +1,23 @@
-- Notification list item component
---@class UIComponent
---@field type string
---@field id string|number
---@field title string
---@field message string
---@field timestamp string|number
---@field read boolean
---@class ListItem : UIComponent
---@field type "notification_item" Component type identifier
---@field id string|number Unique notification identifier
---@field title string Notification title
---@field message string Notification message content
---@field timestamp string|number Notification timestamp
---@field read boolean Read status
---@param id string|number
---@param title string
---@param message string
---@param timestamp string|number
---@param read? boolean
---@return UIComponent
---@class UIComponent
---@field type string Component type identifier
---Create a notification list item component
---@param id string|number Unique notification identifier
---@param title string Notification title
---@param message string Notification message content
---@param timestamp string|number Notification timestamp
---@param read? boolean Read status (default: false)
---@return ListItem list_item The list item component
local function list_item(id, title, message, timestamp, read)
return {
type = "notification_item",

View File

@@ -1,15 +1,16 @@
-- Error toast notification
---@class Toast
---@field type string
---@field variant "info"|"success"|"warning"|"error"
---@field message string
---@field duration number
---@field icon string
---@field type "toast" Component type identifier
---@field variant "info"|"success"|"warning"|"error" Toast variant type
---@field message string Toast message content
---@field duration number Display duration in milliseconds
---@field icon string Icon name
---@param message string
---@param duration? number
---@return Toast
---Create an error toast notification
---@param message string Toast message content
---@param duration? number Display duration in milliseconds (default: 5000)
---@return Toast error The error toast notification
local function error(message, duration)
return {
type = "toast",

View File

@@ -1,15 +1,16 @@
-- Info toast notification
---@class Toast
---@field type string
---@field variant "info"|"success"|"warning"|"error"
---@field message string
---@field duration number
---@field icon string
---@field type "toast" Component type identifier
---@field variant "info"|"success"|"warning"|"error" Toast variant type
---@field message string Toast message content
---@field duration number Display duration in milliseconds
---@field icon string Icon name
---@param message string
---@param duration? number
---@return Toast
---Create an info toast notification
---@param message string Toast message content
---@param duration? number Display duration in milliseconds (default: 3000)
---@return Toast info The info toast notification
local function info(message, duration)
return {
type = "toast",

View File

@@ -1,15 +1,16 @@
-- Warning toast notification
---@class Toast
---@field type string
---@field variant "info"|"success"|"warning"|"error"
---@field message string
---@field duration number
---@field icon string
---@field type "toast" Component type identifier
---@field variant "info"|"success"|"warning"|"error" Toast variant type
---@field message string Toast message content
---@field duration number Display duration in milliseconds
---@field icon string Icon name
---@param message string
---@param duration? number
---@return Toast
---Create a warning toast notification
---@param message string Toast message content
---@param duration? number Display duration in milliseconds (default: 4000)
---@return Toast warning The warning toast notification
local function warning(message, duration)
return {
type = "toast",