Migrate Event Badges to V3 and implement Core Management pages

- Completed V3 migration for Event Badge CRUD operations
- Implemented User module V3 logic and editable fields
- Created management routes for Accounts, Sites, Users, and Lookups
- Updated Site Domain logic to use 'fqdn' and show 'access_key'
- Modernized Core Dashboard with navigation cards
- Restored Dexie User table definition
This commit is contained in:
Scott Idem
2026-01-06 13:38:47 -05:00
parent 1b318eeb8b
commit 00e80af3a1
29 changed files with 3800 additions and 218 deletions

View File

@@ -53,7 +53,8 @@ export interface Site_Domain {
site_id: string;
site_id_random: string;
domain: string;
fqdn: string;
access_key?: null | string;
enable: null | boolean;
enable_from?: null | Date;
@@ -557,7 +558,8 @@ const properties_to_save__site_domain = [
'site_domain_id_random',
'site_id',
'site_id_random',
'domain',
'fqdn',
'access_key',
'enable',
'enable_from',
'enable_to',
@@ -605,7 +607,7 @@ async function _process_generic_props<T extends Record<string, any>>({
const priority = processed_obj.priority ? 1 : 0;
const sort = processed_obj.sort ?? '0';
const updated = processed_obj.updated_on ?? processed_obj.created_on;
const name = processed_obj.name ?? processed_obj.domain ?? '';
const name = processed_obj.name ?? processed_obj.fqdn ?? '';
(processed_obj as any).tmp_sort_1 = `${group}_${priority}_${sort}_${updated}`;
(processed_obj as any).tmp_sort_2 = `${group}_${priority}_${sort}_${name}_${updated}`;

View File

@@ -0,0 +1,19 @@
export const editable_fields__user = [
'username',
'name',
'email',
'allow_auth_key',
'super',
'manager',
'administrator',
'verified',
'public',
'enable',
'enable_from',
'enable_to',
'hide',
'priority',
'sort',
'group',
'notes'
];

View File

@@ -0,0 +1,379 @@
import type { key_val } from '$lib/stores/ae_stores';
import { api } from '$lib/api/api';
import { db_save_ae_obj_li__ae_obj } from '$lib/ae_core/core__idb_dexie';
import { db_core } from '$lib/ae_core/db_core';
const ae_promises: key_val = {};
export interface User {
id: string;
user_id: string;
user_id_random: string;
username: string;
name: string;
email: string;
allow_auth_key: boolean;
super: boolean;
manager: boolean;
administrator: boolean;
verified: boolean;
public: boolean;
person_id?: string;
person_id_random?: string;
enable: null | boolean;
enable_from?: null | Date;
enable_to?: null | Date;
hide?: null | boolean;
priority?: null | boolean;
sort?: null | number;
group?: null | string;
notes?: null | string;
created_on: Date;
updated_on?: null | Date;
tmp_sort_1?: string;
tmp_sort_2?: string;
}
// Updated 2026-01-06
export async function load_ae_obj_id__user({
api_cfg,
user_id,
view = 'default',
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any;
user_id: string;
view?: string;
params?: key_val;
try_cache?: boolean;
log_lvl?: number;
}) {
if (log_lvl) {
console.log(`*** load_ae_obj_id__user() *** user_id=${user_id}`);
}
ae_promises.load__user_obj = await api
.get_ae_obj_v3({
api_cfg,
obj_type: 'user',
obj_id: user_id,
view,
params,
log_lvl
})
.then(async function (result) {
if (result) {
if (try_cache) {
const processed_obj_li = await process_ae_obj__user_props({
obj_li: [result],
log_lvl
});
await db_save_ae_obj_li__ae_obj({
db_instance: db_core,
table_name: 'user',
obj_li: processed_obj_li,
properties_to_save: properties_to_save,
log_lvl
});
}
return result;
} else {
return null;
}
});
return ae_promises.load__user_obj;
}
// Updated 2026-01-06
export async function load_ae_obj_li__user({
api_cfg,
qry_str = null,
enabled = 'enabled',
hidden = 'not_hidden',
view = 'default',
limit = 99,
offset = 0,
order_by_li = { username: 'ASC' },
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any;
qry_str?: string | null;
enabled?: 'enabled' | 'all' | 'not_enabled';
hidden?: 'hidden' | 'all' | 'not_hidden';
view?: string;
limit?: number;
offset?: number;
order_by_li?: Record<string, 'ASC' | 'DESC'>;
params?: key_val;
try_cache?: boolean;
log_lvl?: number;
}) {
let promise;
if (qry_str) {
const search_query: any = { q: qry_str };
promise = api.search_ae_obj_v3({
api_cfg,
obj_type: 'user',
search_query,
enabled,
hidden,
view,
limit,
offset,
order_by_li,
log_lvl
});
} else {
promise = api.get_ae_obj_li_v3({
api_cfg,
obj_type: 'user',
enabled,
hidden,
view,
limit,
offset,
order_by_li,
log_lvl
});
}
ae_promises.load__user_obj_li = await promise.then(async function (result_li) {
if (result_li) {
if (try_cache) {
const processed_obj_li = await process_ae_obj__user_props({
obj_li: result_li,
log_lvl
});
await db_save_ae_obj_li__ae_obj({
db_instance: db_core,
table_name: 'user',
obj_li: processed_obj_li,
properties_to_save: properties_to_save,
log_lvl
});
}
return result_li;
} else {
return [];
}
});
return ae_promises.load__user_obj_li;
}
// Updated 2026-01-06
export async function create_ae_obj__user({
api_cfg,
data_kv,
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any;
data_kv: key_val;
params?: key_val;
try_cache?: boolean;
log_lvl?: number;
}) {
const result = await api.create_ae_obj_v3({
api_cfg,
obj_type: 'user',
fields: data_kv,
params,
log_lvl
});
if (result && try_cache) {
const processed_obj_li = await process_ae_obj__user_props({
obj_li: [result],
log_lvl
});
await db_save_ae_obj_li__ae_obj({
db_instance: db_core,
table_name: 'user',
obj_li: processed_obj_li,
properties_to_save: properties_to_save,
log_lvl
});
}
return result;
}
// Updated 2026-01-06
export async function update_ae_obj__user({
api_cfg,
user_id,
data_kv,
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any;
user_id: string;
data_kv: key_val;
params?: key_val;
try_cache?: boolean;
log_lvl?: number;
}) {
const result = await api.update_ae_obj_v3({
api_cfg,
obj_type: 'user',
obj_id: user_id,
fields: data_kv,
params,
log_lvl
});
if (result && try_cache) {
const processed_obj_li = await process_ae_obj__user_props({
obj_li: [result],
log_lvl
});
await db_save_ae_obj_li__ae_obj({
db_instance: db_core,
table_name: 'user',
obj_li: processed_obj_li,
properties_to_save: properties_to_save,
log_lvl
});
}
return result;
}
// Updated 2026-01-06
export async function delete_ae_obj_id__user({
api_cfg,
user_id,
method = 'delete',
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any;
user_id: string;
method?: 'delete' | 'soft_delete' | 'disable' | 'hide';
params?: key_val;
try_cache?: boolean;
log_lvl?: number;
}) {
const result = await api.delete_ae_obj_v3({
api_cfg,
obj_type: 'user',
obj_id: user_id,
method,
params,
log_lvl
});
if (try_cache) {
await db_core.user.delete(user_id);
}
return result;
}
const properties_to_save = [
'id',
'user_id',
'user_id_random',
'username',
'name',
'email',
'allow_auth_key',
'super',
'manager',
'administrator',
'verified',
'public',
'person_id',
'person_id_random',
'enable',
'enable_from',
'enable_to',
'hide',
'priority',
'sort',
'group',
'notes',
'created_on',
'updated_on',
'tmp_sort_1',
'tmp_sort_2'
];
async function _process_generic_props<T extends Record<string, any>>({
obj_li,
obj_type,
log_lvl = 0,
specific_processor
}: {
obj_li: T[];
obj_type: string;
log_lvl?: number;
specific_processor?: (obj: T) => Promise<T> | T;
}): Promise<T[]> {
if (!obj_li || obj_li.length === 0) return [];
const processed_obj_li: T[] = [];
for (const original_obj of obj_li) {
let processed_obj = { ...original_obj };
for (const key in processed_obj) {
if (key.endsWith('_random')) {
const newKey = key.slice(0, -7);
(processed_obj as any)[newKey] = processed_obj[key];
}
}
const randomIdKey = `${obj_type}_id_random`;
if (processed_obj[randomIdKey]) {
(processed_obj as any).id = processed_obj[randomIdKey];
}
const group = processed_obj.group ?? '0';
const priority = processed_obj.priority ? 1 : 0;
const sort = processed_obj.sort ?? '0';
const updated = processed_obj.updated_on ?? processed_obj.created_on;
const name = processed_obj.username ?? processed_obj.name ?? '';
(processed_obj as any).tmp_sort_1 = `${group}_${priority}_${sort}_${updated}`;
(processed_obj as any).tmp_sort_2 = `${group}_${priority}_${sort}_${name}_${updated}`;
if (specific_processor) {
processed_obj = await Promise.resolve(specific_processor(processed_obj));
}
processed_obj_li.push(processed_obj as T);
}
return processed_obj_li;
}
export async function process_ae_obj__user_props({
obj_li,
log_lvl = 0
}: {
obj_li: any[];
log_lvl?: number;
}) {
return _process_generic_props({
obj_li,
obj_type: 'user',
log_lvl
});
}

View File

@@ -132,14 +132,47 @@ export interface Person {
address_country_alpha_2_code?: null | string; // ISO 3166-1 alpha-2 country code
}
// Updated 2026-01-06
export interface User {
id: string;
user_id: string;
user_id_random: string;
username: string;
name: string;
email: string;
allow_auth_key: boolean;
super: boolean;
manager: boolean;
administrator: boolean;
verified: boolean;
public: boolean;
person_id?: string;
person_id_random?: string;
enable: null | boolean;
hide?: null | boolean;
priority?: null | boolean;
sort?: null | number;
group?: null | string;
notes?: null | string;
created_on: Date;
updated_on?: null | Date;
tmp_sort_1?: string;
tmp_sort_2?: string;
}
// Updated 2026-01-06
export class MySubClassedDexie extends Dexie {
file!: Table<File>;
person!: Table<Person>;
user!: Table<User>;
account!: Table<any>;
site!: Table<any>;
site_domain!: Table<any>;
// user!: Table<User>;
constructor() {
super('ae_core_db');
@@ -165,6 +198,12 @@ export class MySubClassedDexie extends Dexie {
agree,
enable, hide, priority, sort, group, created_on, updated_on`,
user: `
id, user_id, user_id_random,
username, name, email,
super, manager, administrator,
enable, hide, priority, sort, group, created_on, updated_on`,
account: `
id, account_id, account_id_random,
code, name,