fix
This commit is contained in:
parent
1b7d94f7c9
commit
ae7c35b871
|
|
@ -83,7 +83,7 @@ export const Form: FC<FMProps> = (props) => {
|
||||||
fm.size.height = e.contentRect.height;
|
fm.size.height = e.contentRect.height;
|
||||||
fm.size.width = e.contentRect.width;
|
fm.size.width = e.contentRect.width;
|
||||||
|
|
||||||
if (fm.status === "ready" && !isEditor) fm.status = "resizing";
|
// if (fm.status === "ready" && !isEditor) fm.status = "resizing";
|
||||||
|
|
||||||
if (fm.props.layout === "auto") {
|
if (fm.props.layout === "auto") {
|
||||||
if (fm.size.width > 650) {
|
if (fm.size.width > 650) {
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import { getFilter } from "../filter/utils/get-filter";
|
||||||
import { Skeleton } from "../ui/skeleton";
|
import { Skeleton } from "../ui/skeleton";
|
||||||
import "./TableList.css";
|
import "./TableList.css";
|
||||||
import { sortTree } from "./utils/sort-tree";
|
import { sortTree } from "./utils/sort-tree";
|
||||||
|
import { call_prasi_events } from "../../..";
|
||||||
|
|
||||||
type OnRowClick = (arg: {
|
type OnRowClick = (arg: {
|
||||||
row: any;
|
row: any;
|
||||||
|
|
@ -209,6 +210,9 @@ export const TableList: FC<TableListProp> = ({
|
||||||
|
|
||||||
const orderBy = local.sort.orderBy || undefined;
|
const orderBy = local.sort.orderBy || undefined;
|
||||||
const where = filterWhere(filter_name, __props);
|
const where = filterWhere(filter_name, __props);
|
||||||
|
|
||||||
|
call_prasi_events("tablelist", "where", [where]);
|
||||||
|
|
||||||
const load_args: any = {
|
const load_args: any = {
|
||||||
async reload() {},
|
async reload() {},
|
||||||
orderBy,
|
orderBy,
|
||||||
|
|
@ -384,7 +388,6 @@ export const TableList: FC<TableListProp> = ({
|
||||||
const width = parseInt(getProp(child, "width", {}));
|
const width = parseInt(getProp(child, "width", {}));
|
||||||
if (type === "checkbox") {
|
if (type === "checkbox") {
|
||||||
const on_click = getProp(child, "opt__on_click", "");
|
const on_click = getProp(child, "opt__on_click", "");
|
||||||
console.log({ on_click });
|
|
||||||
columns.push({
|
columns.push({
|
||||||
key,
|
key,
|
||||||
name,
|
name,
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@ export { generateRelation } from "@/comps/form/gen/gen-rel";
|
||||||
export { genTableEdit } from "@/comps/form/gen/gen-table-edit";
|
export { genTableEdit } from "@/comps/form/gen/gen-table-edit";
|
||||||
export { generateMasterDetail } from "@/comps/md/gen/md-gen";
|
export { generateMasterDetail } from "@/comps/md/gen/md-gen";
|
||||||
export { parseGenField } from "@/gen/utils";
|
export { parseGenField } from "@/gen/utils";
|
||||||
|
|
||||||
/** ETC */
|
/** ETC */
|
||||||
export { filterModifier } from "@/comps/filter/utils/filter-modifier";
|
export { filterModifier } from "@/comps/filter/utils/filter-modifier";
|
||||||
export { generateField } from "@/comps/form/gen/gen-field";
|
export { generateField } from "@/comps/form/gen/gen-field";
|
||||||
|
|
@ -75,6 +76,8 @@ export { prasi_gen } from "@/gen/prasi_gen";
|
||||||
export { FormatValue } from "@/utils/format-value";
|
export { FormatValue } from "@/utils/format-value";
|
||||||
export { GetValue } from "@/utils/get-value";
|
export { GetValue } from "@/utils/get-value";
|
||||||
export { password } from "@/utils/password";
|
export { password } from "@/utils/password";
|
||||||
|
export { prasi_events, call_prasi_events } from "lib/utils/prasi-events";
|
||||||
|
|
||||||
/** Session */
|
/** Session */
|
||||||
export { Login } from "@/preset/login/Login";
|
export { Login } from "@/preset/login/Login";
|
||||||
export { generateLogin } from "@/preset/login/utils/generate";
|
export { generateLogin } from "@/preset/login/utils/generate";
|
||||||
|
|
@ -102,7 +105,6 @@ export { PanelHeader } from "@/comps/tab/parts/PanelHead";
|
||||||
/*Popup*/
|
/*Popup*/
|
||||||
export { Popup } from "@/comps/popup/PopUp";
|
export { Popup } from "@/comps/popup/PopUp";
|
||||||
|
|
||||||
// Detail
|
|
||||||
export { Detail } from "@/comps/custom/Detail";
|
export { Detail } from "@/comps/custom/Detail";
|
||||||
export { ButtonUpload } from "@/preset/profile/ButtonUpload";
|
export { ButtonUpload } from "@/preset/profile/ButtonUpload";
|
||||||
export { Profile } from "@/preset/profile/Profile";
|
export { Profile } from "@/preset/profile/Profile";
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import get from "lodash.get";
|
import { get as kget, set as kset } from "@/utils/idb-keyval";
|
||||||
|
|
||||||
const single = {} as Record<
|
const single = {} as Record<
|
||||||
string,
|
string,
|
||||||
|
|
@ -30,15 +30,6 @@ const single = {} as Record<
|
||||||
}
|
}
|
||||||
>;
|
>;
|
||||||
|
|
||||||
const load_single = async (table: string) => {
|
|
||||||
if (!single[table]) {
|
|
||||||
single[table] = {
|
|
||||||
cols: await db._schema.columns(table as any),
|
|
||||||
rels: await db._schema.rels(table as any),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return single[table];
|
|
||||||
};
|
|
||||||
export const gen_prop_fields = async (gen_table: string, depth?: number) => {
|
export const gen_prop_fields = async (gen_table: string, depth?: number) => {
|
||||||
if (typeof db === "undefined") return ["- No Database -"];
|
if (typeof db === "undefined") return ["- No Database -"];
|
||||||
|
|
||||||
|
|
@ -49,127 +40,33 @@ export const gen_prop_fields = async (gen_table: string, depth?: number) => {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
id_site = window.location.hostname;
|
id_site = window.location.hostname;
|
||||||
}
|
}
|
||||||
const schema = getSchemaOnStorage(id_site, gen_table);
|
return await loadSchemaLayer(
|
||||||
if (!schema) {
|
id_site,
|
||||||
console.log({depth})
|
typeof depth === "undefined" ? 3 : depth,
|
||||||
const result = await load_layer_schema(
|
{},
|
||||||
typeof depth === "undefined" ? 3 : depth,
|
gen_table
|
||||||
{},
|
);
|
||||||
gen_table
|
|
||||||
);
|
|
||||||
// const { cols, rels } = await load_single(gen_table);
|
|
||||||
// if (cols) {
|
|
||||||
// for (const [k, v] of Object.entries(cols) as any) {
|
|
||||||
// result.push({
|
|
||||||
// value: JSON.stringify({
|
|
||||||
// name: k,
|
|
||||||
// is_pk: v.is_pk,
|
|
||||||
// type: v.db_type || v.type,
|
|
||||||
// optional: v.optional,
|
|
||||||
// }),
|
|
||||||
// label: k,
|
|
||||||
// checked: v.is_pk,
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (rels) {
|
|
||||||
// for (const [k, v] of Object.entries(rels)) {
|
|
||||||
// let options = [] as any;
|
|
||||||
// const to = v.to;
|
|
||||||
// const from = v.from;
|
|
||||||
// const parent_name = k;
|
|
||||||
// const parent_rel = v;
|
|
||||||
// if (to) {
|
|
||||||
// const { cols, rels } = await load_single(to.table);
|
|
||||||
// // if (cols) {
|
|
||||||
// // for (const [k, v] of Object.entries(cols)) {
|
|
||||||
// // options.push({
|
|
||||||
// // value: JSON.stringify({
|
|
||||||
// // name: k,
|
|
||||||
// // is_pk: v.is_pk,
|
|
||||||
// // type: v.db_type || v.type,
|
|
||||||
// // optional: v.optional,
|
|
||||||
// // }),
|
|
||||||
// // label: k,
|
|
||||||
// // checked: v.is_pk,
|
|
||||||
// // });
|
|
||||||
// // }
|
|
||||||
// // }
|
|
||||||
// // if (rels) {
|
|
||||||
// // for (const [k, v] of Object.entries(rels)) {
|
|
||||||
// // let sub_opt = [];
|
|
||||||
// // const to = v.to;
|
|
||||||
// // const from = v.from;
|
|
||||||
// // const { cols } = await load_single(v.to.table);
|
|
||||||
// // for (const [k, v] of Object.entries(cols)) {
|
|
||||||
// // sub_opt.push({
|
|
||||||
// // value: JSON.stringify({
|
|
||||||
// // name: k,
|
|
||||||
// // is_pk: v.is_pk,
|
|
||||||
// // type: v.db_type || v.type,
|
|
||||||
// // optional: v.optional,
|
|
||||||
// // }),
|
|
||||||
// // label: k,
|
|
||||||
// // checked: v.is_pk,
|
|
||||||
// // });
|
|
||||||
// // }
|
|
||||||
// // options.push({
|
|
||||||
// // value: JSON.stringify({
|
|
||||||
// // name: k,
|
|
||||||
// // is_pk: false,
|
|
||||||
// // type: v.type,
|
|
||||||
// // optional: true,
|
|
||||||
// // relation: { from, to },
|
|
||||||
// // }),
|
|
||||||
// // label: k,
|
|
||||||
// // options: sub_opt,
|
|
||||||
// // checked:
|
|
||||||
// // parent_rel.type === "has-many" &&
|
|
||||||
// // parent_rel.from.table === v.to.table,
|
|
||||||
// // });
|
|
||||||
// // }
|
|
||||||
// // }
|
|
||||||
// }
|
|
||||||
// result.push({
|
|
||||||
// value: JSON.stringify({
|
|
||||||
// name: k,
|
|
||||||
// is_pk: false,
|
|
||||||
// type: v.type,
|
|
||||||
// optional: true,
|
|
||||||
// relation: { from, to },
|
|
||||||
// }),
|
|
||||||
// label: k,
|
|
||||||
// options,
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
try {
|
|
||||||
saveSchemaOnStorage(result, id_site, gen_table);
|
|
||||||
} catch (e: any) {
|
|
||||||
console.error(e.message);
|
|
||||||
}
|
|
||||||
console.log({result})
|
|
||||||
return result;
|
|
||||||
} else {
|
|
||||||
console.log({schema})
|
|
||||||
return schema;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
const load_layer_schema = async (depth: number, arg: any, table: string) => {
|
|
||||||
|
const loadSchemaLayer = async (
|
||||||
|
id_site: string,
|
||||||
|
depth: number,
|
||||||
|
arg: any,
|
||||||
|
table: string
|
||||||
|
) => {
|
||||||
let current_depth = 1;
|
let current_depth = 1;
|
||||||
console.log({ depth, current_depth, arg, table });
|
const result = await get_layer(id_site, depth, current_depth, arg, table);
|
||||||
const result = await get_layer(depth, current_depth, arg, table);
|
|
||||||
console.log({ result });
|
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
const get_layer = async (
|
const get_layer = async (
|
||||||
|
id_site: string,
|
||||||
depth: number,
|
depth: number,
|
||||||
current: number,
|
current: number,
|
||||||
arg: any,
|
arg: any,
|
||||||
table: string
|
table: string
|
||||||
) => {
|
) => {
|
||||||
const { cols, rels } = await load_single(table);
|
const { cols, rels } = await loadSingle(id_site, table);
|
||||||
console.log({cols, rels , table})
|
|
||||||
const options = [];
|
const options = [];
|
||||||
if (cols) {
|
if (cols) {
|
||||||
for (const [k, v] of Object.entries(cols)) {
|
for (const [k, v] of Object.entries(cols)) {
|
||||||
|
|
@ -192,6 +89,7 @@ const get_layer = async (
|
||||||
const to = v.to;
|
const to = v.to;
|
||||||
const from = v.from;
|
const from = v.from;
|
||||||
const r_rels = (await get_layer(
|
const r_rels = (await get_layer(
|
||||||
|
id_site,
|
||||||
depth,
|
depth,
|
||||||
current + 1,
|
current + 1,
|
||||||
arg,
|
arg,
|
||||||
|
|
@ -214,32 +112,39 @@ const get_layer = async (
|
||||||
}
|
}
|
||||||
return options;
|
return options;
|
||||||
};
|
};
|
||||||
const saveSchemaOnStorage = (res: any, id_site: string, table: string) => {
|
|
||||||
let schemaSite = null;
|
const loadSingle = async (id_site: string, table: string) => {
|
||||||
let schema_master_detail: Record<string, any> = {};
|
const ls_key = `schema-md-${id_site}`;
|
||||||
const keys = `schema-md-${id_site}`;
|
const idb_key = `${id_site}-${table}`;
|
||||||
try {
|
let cached_raw = localStorage.getItem(ls_key);
|
||||||
let smd = localStorage.getItem(keys) as string;
|
let cached_keys: string[] = [];
|
||||||
schemaSite = JSON.parse(smd);
|
if (cached_raw) {
|
||||||
} catch (error) {}
|
try {
|
||||||
try {
|
let res = JSON.parse(cached_raw);
|
||||||
schema_master_detail = {
|
if (!Array.isArray(res)) {
|
||||||
...schemaSite,
|
localStorage.setItem(ls_key, JSON.stringify([]));
|
||||||
[table]: JSON.stringify(res),
|
res = [];
|
||||||
};
|
}
|
||||||
localStorage.setItem(keys, JSON.stringify(schema_master_detail));
|
cached_keys = res;
|
||||||
} catch (e: any) {
|
} catch (e) {}
|
||||||
console.error(e.message);
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
const getSchemaOnStorage = (id_site: string, table: string) => {
|
let cached = null;
|
||||||
const keys = `schema-md-${id_site}`;
|
if (cached_keys.includes(table)) {
|
||||||
let schemaSite = null;
|
cached = await kget(idb_key);
|
||||||
try {
|
}
|
||||||
let smd = localStorage.getItem(keys) as string;
|
|
||||||
schemaSite = JSON.parse(smd);
|
if (!single[table]) {
|
||||||
} catch (error) {}
|
if (cached) {
|
||||||
const schema = get(schemaSite, `${table}`);
|
single[table] = cached;
|
||||||
if (schema) return JSON.parse(schema);
|
} else {
|
||||||
return null;
|
single[table] = {
|
||||||
|
cols: await db._schema.columns(table as any),
|
||||||
|
rels: await db._schema.rels(table as any),
|
||||||
|
};
|
||||||
|
await kset(idb_key, single[table]);
|
||||||
|
localStorage.setItem(ls_key, JSON.stringify([...cached_keys, table]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return single[table];
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ export const Menu: FC<MenuProp> = (props) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cx("c-overflow-y-auto c-relative c-h-full c-w-full ")}>
|
<div className={cx("c-overflow-y-auto c-relative c-h-full c-w-full ")}>
|
||||||
<div className="c-absolute c-inset-0 c-flex c-flex-col c-flex-grow c-px-3 c-py-4 ">
|
<div className="sidebar-menu c-absolute c-inset-0 c-flex c-flex-col c-flex-grow c-px-3 c-py-4 ">
|
||||||
<SideBar
|
<SideBar
|
||||||
data={menu}
|
data={menu}
|
||||||
local={local}
|
local={local}
|
||||||
|
|
@ -155,7 +155,7 @@ export const SideBar: FC<{
|
||||||
) {
|
) {
|
||||||
navigate(menu.value);
|
navigate(menu.value);
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 500);
|
||||||
}
|
}
|
||||||
local.render();
|
local.render();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,259 @@
|
||||||
|
export function promisifyRequest<T = undefined>(
|
||||||
|
request: IDBRequest<T> | IDBTransaction
|
||||||
|
): Promise<T> {
|
||||||
|
return new Promise<T>((resolve, reject) => {
|
||||||
|
// @ts-ignore - file size hacks
|
||||||
|
request.oncomplete = request.onsuccess = () => resolve(request.result);
|
||||||
|
// @ts-ignore - file size hacks
|
||||||
|
request.onabort = request.onerror = () => reject(request.error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createStore(dbName: string, storeName: string): UseStore {
|
||||||
|
const request = indexedDB.open(dbName);
|
||||||
|
request.onupgradeneeded = () => request.result.createObjectStore(storeName);
|
||||||
|
const dbp = promisifyRequest(request);
|
||||||
|
|
||||||
|
return (txMode, callback) =>
|
||||||
|
dbp.then((db) =>
|
||||||
|
callback(db.transaction(storeName, txMode).objectStore(storeName))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export type UseStore = <T>(
|
||||||
|
txMode: IDBTransactionMode,
|
||||||
|
callback: (store: IDBObjectStore) => T | PromiseLike<T>
|
||||||
|
) => Promise<T>;
|
||||||
|
|
||||||
|
let defaultGetStoreFunc: UseStore | undefined;
|
||||||
|
|
||||||
|
function defaultGetStore() {
|
||||||
|
if (!defaultGetStoreFunc) {
|
||||||
|
defaultGetStoreFunc = createStore("keyval-store", "keyval");
|
||||||
|
}
|
||||||
|
return defaultGetStoreFunc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a value by its key.
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @param customStore Method to get a custom store. Use with caution (see the docs).
|
||||||
|
*/
|
||||||
|
export function get<T = any>(
|
||||||
|
key: IDBValidKey,
|
||||||
|
customStore = defaultGetStore()
|
||||||
|
): Promise<T | undefined> {
|
||||||
|
return customStore("readonly", (store) => promisifyRequest(store.get(key)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a value with a key.
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @param value
|
||||||
|
* @param customStore Method to get a custom store. Use with caution (see the docs).
|
||||||
|
*/
|
||||||
|
export function set(
|
||||||
|
key: IDBValidKey,
|
||||||
|
value: any,
|
||||||
|
customStore = defaultGetStore()
|
||||||
|
): Promise<void> {
|
||||||
|
return customStore("readwrite", (store) => {
|
||||||
|
store.put(value, key);
|
||||||
|
return promisifyRequest(store.transaction);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set multiple values at once. This is faster than calling set() multiple times.
|
||||||
|
* It's also atomic – if one of the pairs can't be added, none will be added.
|
||||||
|
*
|
||||||
|
* @param entries Array of entries, where each entry is an array of `[key, value]`.
|
||||||
|
* @param customStore Method to get a custom store. Use with caution (see the docs).
|
||||||
|
*/
|
||||||
|
export function setMany(
|
||||||
|
entries: [IDBValidKey, any][],
|
||||||
|
customStore = defaultGetStore()
|
||||||
|
): Promise<void> {
|
||||||
|
return customStore("readwrite", (store) => {
|
||||||
|
entries.forEach((entry) => store.put(entry[1], entry[0]));
|
||||||
|
return promisifyRequest(store.transaction);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get multiple values by their keys
|
||||||
|
*
|
||||||
|
* @param keys
|
||||||
|
* @param customStore Method to get a custom store. Use with caution (see the docs).
|
||||||
|
*/
|
||||||
|
export function getMany<T = any>(
|
||||||
|
keys: IDBValidKey[],
|
||||||
|
customStore = defaultGetStore()
|
||||||
|
): Promise<T[]> {
|
||||||
|
return customStore("readonly", (store) =>
|
||||||
|
Promise.all(keys.map((key) => promisifyRequest(store.get(key))))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a value. This lets you see the old value and update it as an atomic operation.
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @param updater A callback that takes the old value and returns a new value.
|
||||||
|
* @param customStore Method to get a custom store. Use with caution (see the docs).
|
||||||
|
*/
|
||||||
|
export function update<T = any>(
|
||||||
|
key: IDBValidKey,
|
||||||
|
updater: (oldValue: T | undefined) => T,
|
||||||
|
customStore = defaultGetStore()
|
||||||
|
): Promise<void> {
|
||||||
|
return customStore(
|
||||||
|
"readwrite",
|
||||||
|
(store) =>
|
||||||
|
// Need to create the promise manually.
|
||||||
|
// If I try to chain promises, the transaction closes in browsers
|
||||||
|
// that use a promise polyfill (IE10/11).
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
|
store.get(key).onsuccess = function () {
|
||||||
|
try {
|
||||||
|
store.put(updater(this.result), key);
|
||||||
|
resolve(promisifyRequest(store.transaction));
|
||||||
|
} catch (err) {
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a particular key from the store.
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @param customStore Method to get a custom store. Use with caution (see the docs).
|
||||||
|
*/
|
||||||
|
export function del(
|
||||||
|
key: IDBValidKey,
|
||||||
|
customStore = defaultGetStore()
|
||||||
|
): Promise<void> {
|
||||||
|
return customStore("readwrite", (store) => {
|
||||||
|
store.delete(key);
|
||||||
|
return promisifyRequest(store.transaction);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete multiple keys at once.
|
||||||
|
*
|
||||||
|
* @param keys List of keys to delete.
|
||||||
|
* @param customStore Method to get a custom store. Use with caution (see the docs).
|
||||||
|
*/
|
||||||
|
export function delMany(
|
||||||
|
keys: IDBValidKey[],
|
||||||
|
customStore = defaultGetStore()
|
||||||
|
): Promise<void> {
|
||||||
|
return customStore("readwrite", (store: IDBObjectStore) => {
|
||||||
|
keys.forEach((key: IDBValidKey) => store.delete(key));
|
||||||
|
return promisifyRequest(store.transaction);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear all values in the store.
|
||||||
|
*
|
||||||
|
* @param customStore Method to get a custom store. Use with caution (see the docs).
|
||||||
|
*/
|
||||||
|
export function clear(customStore = defaultGetStore()): Promise<void> {
|
||||||
|
return customStore("readwrite", (store) => {
|
||||||
|
store.clear();
|
||||||
|
return promisifyRequest(store.transaction);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function eachCursor(
|
||||||
|
store: IDBObjectStore,
|
||||||
|
callback: (cursor: IDBCursorWithValue) => void
|
||||||
|
): Promise<void> {
|
||||||
|
store.openCursor().onsuccess = function () {
|
||||||
|
if (!this.result) return;
|
||||||
|
callback(this.result);
|
||||||
|
this.result.continue();
|
||||||
|
};
|
||||||
|
return promisifyRequest(store.transaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all keys in the store.
|
||||||
|
*
|
||||||
|
* @param customStore Method to get a custom store. Use with caution (see the docs).
|
||||||
|
*/
|
||||||
|
export function keys<KeyType extends IDBValidKey>(
|
||||||
|
customStore = defaultGetStore()
|
||||||
|
): Promise<KeyType[]> {
|
||||||
|
return customStore("readonly", (store) => {
|
||||||
|
// Fast path for modern browsers
|
||||||
|
if (store.getAllKeys) {
|
||||||
|
return promisifyRequest(
|
||||||
|
store.getAllKeys() as unknown as IDBRequest<KeyType[]>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const items: KeyType[] = [];
|
||||||
|
|
||||||
|
return eachCursor(store, (cursor) =>
|
||||||
|
items.push(cursor.key as KeyType)
|
||||||
|
).then(() => items);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all values in the store.
|
||||||
|
*
|
||||||
|
* @param customStore Method to get a custom store. Use with caution (see the docs).
|
||||||
|
*/
|
||||||
|
export function values<T = any>(customStore = defaultGetStore()): Promise<T[]> {
|
||||||
|
return customStore("readonly", (store) => {
|
||||||
|
// Fast path for modern browsers
|
||||||
|
if (store.getAll) {
|
||||||
|
return promisifyRequest(store.getAll() as IDBRequest<T[]>);
|
||||||
|
}
|
||||||
|
|
||||||
|
const items: T[] = [];
|
||||||
|
|
||||||
|
return eachCursor(store, (cursor) => items.push(cursor.value as T)).then(
|
||||||
|
() => items
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all entries in the store. Each entry is an array of `[key, value]`.
|
||||||
|
*
|
||||||
|
* @param customStore Method to get a custom store. Use with caution (see the docs).
|
||||||
|
*/
|
||||||
|
export function entries<KeyType extends IDBValidKey, ValueType = any>(
|
||||||
|
customStore = defaultGetStore()
|
||||||
|
): Promise<[KeyType, ValueType][]> {
|
||||||
|
return customStore("readonly", (store) => {
|
||||||
|
// Fast path for modern browsers
|
||||||
|
// (although, hopefully we'll get a simpler path some day)
|
||||||
|
if (store.getAll && store.getAllKeys) {
|
||||||
|
return Promise.all([
|
||||||
|
promisifyRequest(
|
||||||
|
store.getAllKeys() as unknown as IDBRequest<KeyType[]>
|
||||||
|
),
|
||||||
|
promisifyRequest(store.getAll() as IDBRequest<ValueType[]>),
|
||||||
|
]).then(([keys, values]) => keys.map((key, i) => [key, values[i]]));
|
||||||
|
}
|
||||||
|
|
||||||
|
const items: [KeyType, ValueType][] = [];
|
||||||
|
|
||||||
|
return customStore("readonly", (store) =>
|
||||||
|
eachCursor(store, (cursor) =>
|
||||||
|
items.push([cursor.key as KeyType, cursor.value])
|
||||||
|
).then(() => items)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
import { FMLocal } from "../..";
|
||||||
|
|
||||||
|
const events = {
|
||||||
|
form: {
|
||||||
|
where: async (fm: FMLocal, where: any) => {},
|
||||||
|
before_update: async (fm: FMLocal) => {},
|
||||||
|
after_update: async (fm: FMLocal) => {},
|
||||||
|
before_insert: async (fm: FMLocal) => {},
|
||||||
|
after_insert: async (fm: FMLocal) => {},
|
||||||
|
before_load: async (fm: FMLocal) => {},
|
||||||
|
after_load: async (fm: FMLocal) => {},
|
||||||
|
},
|
||||||
|
tablelist: { where: async (where: any) => {} },
|
||||||
|
};
|
||||||
|
|
||||||
|
let w = null as any;
|
||||||
|
if (typeof window !== "undefined") {
|
||||||
|
w = window;
|
||||||
|
if (!w.prasi_events) {
|
||||||
|
w.prasi_events = events;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type PRASI_EVENT = typeof events;
|
||||||
|
export const prasi_events: PRASI_EVENT = w.prasi_events;
|
||||||
|
export const call_prasi_events = async <
|
||||||
|
K extends keyof PRASI_EVENT,
|
||||||
|
L extends keyof PRASI_EVENT[K]
|
||||||
|
>(
|
||||||
|
k: K,
|
||||||
|
l: L,
|
||||||
|
args: any[]
|
||||||
|
) => {
|
||||||
|
const fn = prasi_events?.[k]?.[l] as any;
|
||||||
|
|
||||||
|
if (fn) {
|
||||||
|
await fn(...args);
|
||||||
|
}
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue