nexus-shared 3.1.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2268 -446
- package/LICENSE +21 -21
- package/README.md +1705 -1084
- package/dist/Client.Index.d.ts +17 -0
- package/dist/Client.Index.js +17 -0
- package/dist/Components/Documents/DocumentFrame.d.ts +50 -0
- package/dist/Components/Documents/DocumentFrame.js +83 -0
- package/dist/Components/Documents/Menu.d.ts +4 -0
- package/dist/Components/Documents/Menu.js +40 -24
- package/dist/Components/Documents/PrintDocument.d.ts +95 -0
- package/dist/Components/Documents/PrintDocument.js +62 -0
- package/dist/Components/Documents/Tabs.d.ts +59 -0
- package/dist/Components/Documents/Tabs.js +70 -0
- package/dist/Components/Forms/ApiForm.js +19 -2
- package/dist/Components/Forms/Crud.d.ts +2 -2
- package/dist/Components/Forms/Crud.js +871 -377
- package/dist/Components/Forms/CrudActions.d.ts +136 -0
- package/dist/Components/Forms/CrudActions.js +184 -0
- package/dist/Components/Forms/CrudHistory.d.ts +66 -0
- package/dist/Components/Forms/CrudHistory.js +140 -0
- package/dist/Components/Forms/CrudNarrowPicker.d.ts +31 -0
- package/dist/Components/Forms/CrudNarrowPicker.js +180 -0
- package/dist/Components/Forms/CrudParts.d.ts +30 -2
- package/dist/Components/Forms/CrudParts.js +56 -5
- package/dist/Components/Forms/CrudRowForms.d.ts +26 -0
- package/dist/Components/Forms/CrudRowForms.js +114 -0
- package/dist/Components/Forms/CrudScopes.d.ts +28 -0
- package/dist/Components/Forms/CrudScopes.js +76 -0
- package/dist/Components/Forms/CrudTree.d.ts +90 -0
- package/dist/Components/Forms/CrudTree.js +363 -0
- package/dist/Components/Forms/CrudWorkspace.d.ts +63 -0
- package/dist/Components/Forms/CrudWorkspace.js +169 -0
- package/dist/Components/Forms/ExcelImport.js +3 -3
- package/dist/Components/Forms/Form.d.ts +4 -4
- package/dist/Components/Forms/Form.js +125 -16
- package/dist/Components/Forms/FormLeaveGuard.d.ts +44 -0
- package/dist/Components/Forms/FormLeaveGuard.js +65 -0
- package/dist/Components/Forms/RecordFlows.d.ts +50 -0
- package/dist/Components/Forms/RecordFlows.js +282 -0
- package/dist/Components/Forms/SubmitForm.d.ts +37 -2
- package/dist/Components/Forms/SubmitForm.js +195 -10
- package/dist/Components/Inputs/CheckBox.js +1 -1
- package/dist/Components/Inputs/ChoiceField.d.ts +21 -1
- package/dist/Components/Inputs/ChoiceField.js +28 -2
- package/dist/Components/Inputs/CodeBox.d.ts +69 -0
- package/dist/Components/Inputs/CodeBox.js +316 -0
- package/dist/Components/Inputs/DatePicker.js +4 -1
- package/dist/Components/Inputs/DateRangePicker.js +4 -1
- package/dist/Components/Inputs/DateTimePicker.js +4 -1
- package/dist/Components/Inputs/Dropdown.d.ts +13 -0
- package/dist/Components/Inputs/Dropdown.js +8 -5
- package/dist/Components/Inputs/DropdownParts.d.ts +3 -1
- package/dist/Components/Inputs/DropdownParts.js +16 -4
- package/dist/Components/Inputs/Field.d.ts +7 -1
- package/dist/Components/Inputs/Field.js +2 -2
- package/dist/Components/Inputs/GroupForm.d.ts +6 -6
- package/dist/Components/Inputs/GroupForm.js +10 -11
- package/dist/Components/Inputs/InputRenderer.d.ts +9 -6
- package/dist/Components/Inputs/InputRenderer.js +39 -31
- package/dist/Components/Inputs/NumberBox.js +4 -2
- package/dist/Components/Inputs/PictureInput.d.ts +41 -0
- package/dist/Components/Inputs/PictureInput.js +70 -0
- package/dist/Components/Inputs/RadioGroup.d.ts +16 -3
- package/dist/Components/Inputs/RadioGroup.js +8 -3
- package/dist/Components/Inputs/RowsInput.d.ts +1 -1
- package/dist/Components/Inputs/RowsInput.js +18 -3
- package/dist/Components/Inputs/TabularForm.d.ts +5 -5
- package/dist/Components/Inputs/TabularForm.js +29 -29
- package/dist/Components/Inputs/TextArea.d.ts +6 -0
- package/dist/Components/Inputs/TextArea.js +14 -2
- package/dist/Components/Inputs/TextBox.js +4 -1
- package/dist/Components/Inputs/TextBoxTypes.d.ts +6 -0
- package/dist/Components/Inputs/TextBoxTypes.js +17 -0
- package/dist/Components/Inputs/TimePicker.js +4 -1
- package/dist/Components/Inputs/TreeView.d.ts +107 -6
- package/dist/Components/Inputs/TreeView.js +513 -30
- package/dist/Components/Layouts/MessageBox.d.ts +15 -2
- package/dist/Components/Layouts/MessageBox.js +56 -7
- package/dist/Components/Layouts/Popup.d.ts +13 -6
- package/dist/Components/Layouts/Popup.js +37 -9
- package/dist/Components/Layouts/PopupDock.d.ts +3 -1
- package/dist/Components/Layouts/PopupDock.js +2 -1
- package/dist/Components/Layouts/PopupHost.js +5 -4
- package/dist/Components/Layouts/ThemePicker.d.ts +3 -2
- package/dist/Components/Layouts/ThemePicker.js +16 -4
- package/dist/Components/Viewers/DataTable.js +205 -61
- package/dist/Components/Viewers/DataTableFilters.d.ts +1 -1
- package/dist/Components/Viewers/DataTableFilters.js +17 -2
- package/dist/Components/Viewers/DataTableParts.d.ts +46 -12
- package/dist/Components/Viewers/DataTableParts.js +62 -21
- package/dist/Components/Viewers/OwnerFiles.d.ts +175 -0
- package/dist/Components/Viewers/OwnerFiles.js +589 -0
- package/dist/Components/Viewers/QrCodeImage.d.ts +22 -0
- package/dist/Components/Viewers/QrCodeImage.js +15 -0
- package/dist/Components/Viewers/RecordCards.d.ts +16 -0
- package/dist/Components/Viewers/RecordCards.js +509 -0
- package/dist/Helpers/ApiModules.d.ts +3 -34
- package/dist/Helpers/ApiModules.js +3 -3
- package/dist/Helpers/ApiRoutes.d.ts +68 -26
- package/dist/Helpers/ApiRoutes.js +31 -27
- package/dist/Helpers/ArrayHelpers.d.ts +0 -0
- package/dist/Helpers/ArrayHelpers.js +2 -0
- package/dist/Helpers/BusyHooks.d.ts +6 -0
- package/dist/Helpers/BusyHooks.js +39 -0
- package/dist/Helpers/CodeHelpers.d.ts +97 -0
- package/dist/Helpers/CodeHelpers.js +332 -0
- package/dist/Helpers/CrudBackend.d.ts +114 -6
- package/dist/Helpers/CrudBackend.js +214 -11
- package/dist/Helpers/CrudColumns.d.ts +98 -0
- package/dist/Helpers/CrudColumns.js +160 -0
- package/dist/Helpers/CrudDetailsTabs.d.ts +58 -0
- package/dist/Helpers/CrudDetailsTabs.js +126 -0
- package/dist/Helpers/CrudHelpers.d.ts +130 -6
- package/dist/Helpers/CrudHelpers.js +304 -12
- package/dist/Helpers/CrudNarrowPick.d.ts +83 -0
- package/dist/Helpers/CrudNarrowPick.js +157 -0
- package/dist/Helpers/CrudRowForms.d.ts +15 -0
- package/dist/Helpers/CrudRowForms.js +43 -0
- package/dist/Helpers/CrudScopes.d.ts +32 -0
- package/dist/Helpers/CrudScopes.js +79 -0
- package/dist/Helpers/DropdownHelpers.d.ts +3 -1
- package/dist/Helpers/DropdownHelpers.js +6 -2
- package/dist/Helpers/ExcelHelpers.d.ts +1 -1
- package/dist/Helpers/ExcelHelpers.js +12 -11
- package/dist/Helpers/FileAdapter.d.ts +78 -0
- package/dist/Helpers/FileAdapter.js +102 -0
- package/dist/Helpers/FilePrimaries.d.ts +48 -0
- package/dist/Helpers/FilePrimaries.js +138 -0
- package/dist/Helpers/FormConfirm.d.ts +32 -0
- package/dist/Helpers/FormConfirm.js +40 -0
- package/dist/Helpers/FormStore.d.ts +90 -5
- package/dist/Helpers/FormStore.js +318 -22
- package/dist/Helpers/InputConditions.d.ts +50 -0
- package/dist/Helpers/InputConditions.js +168 -0
- package/dist/Helpers/InputMemory.d.ts +106 -0
- package/dist/Helpers/InputMemory.js +385 -0
- package/dist/Helpers/InputNarrowing.d.ts +18 -0
- package/dist/Helpers/InputNarrowing.js +67 -0
- package/dist/Helpers/InputParamsHelpers.d.ts +44 -1
- package/dist/Helpers/InputParamsHelpers.js +162 -71
- package/dist/Helpers/MessageBuilder.js +2 -0
- package/dist/Helpers/NexusDriveAdapter.d.ts +55 -0
- package/dist/Helpers/NexusDriveAdapter.js +207 -0
- package/dist/Helpers/NexusHelpers.d.ts +0 -0
- package/dist/Helpers/NexusHelpers.js +1 -0
- package/dist/Helpers/NumberHelpers.d.ts +95 -0
- package/dist/Helpers/NumberHelpers.js +126 -0
- package/dist/Helpers/Permissions.js +2 -1
- package/dist/Helpers/QrCode.d.ts +26 -0
- package/dist/Helpers/QrCode.js +463 -0
- package/dist/Helpers/RecordCards.d.ts +205 -0
- package/dist/Helpers/RecordCards.js +378 -0
- package/dist/Helpers/RequestCache.d.ts +47 -0
- package/dist/Helpers/RequestCache.js +132 -0
- package/dist/Helpers/RowsStore.d.ts +37 -2
- package/dist/Helpers/RowsStore.js +128 -10
- package/dist/Helpers/ServerPreview.d.ts +69 -0
- package/dist/Helpers/ServerPreview.js +99 -0
- package/dist/Helpers/TableColumns.js +4 -3
- package/dist/Helpers/TableExport.d.ts +7 -1
- package/dist/Helpers/TableExport.js +21 -15
- package/dist/Helpers/TableFilters.d.ts +1 -1
- package/dist/Helpers/TableFilters.js +24 -23
- package/dist/Helpers/TableHelpers.d.ts +24 -3
- package/dist/Helpers/TableHelpers.js +58 -12
- package/dist/Helpers/TableJoins.d.ts +83 -0
- package/dist/Helpers/TableJoins.js +284 -0
- package/dist/Helpers/TableStore.d.ts +26 -1
- package/dist/Helpers/TableStore.js +73 -7
- package/dist/Helpers/TreeStore.d.ts +306 -11
- package/dist/Helpers/TreeStore.js +1048 -90
- package/dist/Helpers/UserPreferences.d.ts +8 -0
- package/dist/Helpers/UserPreferences.js +17 -0
- package/dist/Interfaces/CrudInterfaces.d.ts +512 -14
- package/dist/Interfaces/FileInterfaces.d.ts +162 -0
- package/dist/Interfaces/FileInterfaces.js +4 -0
- package/dist/Interfaces/FormInterfaces.d.ts +393 -29
- package/dist/Interfaces/FormInterfaces.js +79 -1
- package/dist/Interfaces/InputInterfaces.d.ts +39 -3
- package/dist/Interfaces/MessageInterfaces.d.ts +1 -1
- package/dist/Interfaces/PreferenceInterfaces.d.ts +8 -0
- package/dist/Interfaces/PreferenceInterfaces.js +2 -5
- package/dist/Interfaces/RecordInterfaces.d.ts +367 -0
- package/dist/Interfaces/RecordInterfaces.js +1 -0
- package/dist/Interfaces/TableInterfaces.d.ts +160 -5
- package/dist/Services/ApiProxy.d.ts +36 -1
- package/dist/Services/ApiProxy.js +182 -52
- package/dist/Services/ApiProxyRules.d.ts +203 -0
- package/dist/Services/ApiProxyRules.js +426 -0
- package/dist/Services/ExcelApi.js +5 -0
- package/dist/Services/FileApi.d.ts +13 -0
- package/dist/Services/FileApi.js +29 -0
- package/dist/Services/ImageEditorLoader.d.ts +14 -0
- package/dist/Services/ImageEditorLoader.js +51 -0
- package/dist/Services/JoinSources.d.ts +80 -0
- package/dist/Services/JoinSources.js +150 -0
- package/dist/Services/ModuleImport.d.ts +7 -0
- package/dist/Services/ModuleImport.js +22 -0
- package/dist/Services/ServerApi.d.ts +13 -2
- package/dist/Services/ServerApi.js +8 -3
- package/dist/Shared.Index.d.ts +20 -0
- package/dist/Shared.Index.js +20 -0
- package/package.json +92 -85
- package/src/Styles/Nexus.Avatar.css +80 -79
- package/src/Styles/Nexus.Base.css +117 -117
- package/src/Styles/Nexus.Button.css +186 -180
- package/src/Styles/Nexus.Calendar.css +273 -273
- package/src/Styles/Nexus.Chat.css +1443 -1443
- package/src/Styles/Nexus.Choice.css +359 -343
- package/src/Styles/Nexus.Crud.css +542 -168
- package/src/Styles/Nexus.DateTime.css +81 -81
- package/src/Styles/Nexus.Dropdown.css +733 -725
- package/src/Styles/Nexus.Editor.css +295 -295
- package/src/Styles/Nexus.Excel.css +389 -389
- package/src/Styles/Nexus.Files.css +410 -0
- package/src/Styles/Nexus.Form.css +282 -279
- package/src/Styles/Nexus.Index.css +41 -37
- package/src/Styles/Nexus.Input.css +238 -4
- package/src/Styles/Nexus.Markdown.css +237 -237
- package/src/Styles/Nexus.Menu.css +246 -237
- package/src/Styles/Nexus.Popup.css +800 -724
- package/src/Styles/Nexus.Print.css +288 -0
- package/src/Styles/Nexus.QrCode.css +12 -0
- package/src/Styles/Nexus.Record.css +430 -0
- package/src/Styles/Nexus.Rows.css +637 -637
- package/src/Styles/Nexus.Slider.css +276 -276
- package/src/Styles/Nexus.Tab.Buttons.css +497 -432
- package/src/Styles/Nexus.Table.css +98 -35
- package/src/Styles/Nexus.Theme.Picker.css +59 -3
- package/src/Styles/Nexus.Themes.css +200 -194
- package/src/Styles/Nexus.Time.css +144 -144
- package/src/Styles/Nexus.Toast.css +263 -263
- package/src/Styles/Nexus.Tokens.css +94 -89
- package/src/Styles/Nexus.Tree.css +530 -431
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { PrimaryPictures } from "../Helpers/FilePrimaries.js";
|
|
3
|
+
import { NexusDriveAdapter } from "../Helpers/NexusDriveAdapter.js";
|
|
4
|
+
import { api } from "./BrowserApi.js";
|
|
5
|
+
/*
|
|
6
|
+
* The app's file backend and the page's kept pictures. Without a `defineFileAdapter`, the Nexus Drive through the app's
|
|
7
|
+
* `api` (its token, headers and proxy).
|
|
8
|
+
*/
|
|
9
|
+
/* The app's adapter */
|
|
10
|
+
let current = null;
|
|
11
|
+
/**
|
|
12
|
+
* Registers the app's file backend, once, beside its API modules. Without it, the Nexus Drive.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* defineFileAdapter(new NexusDriveAdapter({ client: api, drive: HrModule.Files }));
|
|
16
|
+
*/
|
|
17
|
+
export function defineFileAdapter(adapter) {
|
|
18
|
+
current = adapter;
|
|
19
|
+
primaryPictures.clear();
|
|
20
|
+
return adapter;
|
|
21
|
+
}
|
|
22
|
+
/** The registered file backend, or the Nexus Drive. */
|
|
23
|
+
export function getFileAdapter() {
|
|
24
|
+
return (current ??= new NexusDriveAdapter({ client: api }));
|
|
25
|
+
}
|
|
26
|
+
/** Each owner's picture for the page's rows, read in one call per page and kept until a change on the page. */
|
|
27
|
+
export const primaryPictures = new PrimaryPictures((module, category, ownerIds) => getFileAdapter().primaries(module, category, ownerIds, { toast: false }), {
|
|
28
|
+
batchSize: () => getFileAdapter().maxOwners,
|
|
29
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ImageEditorModule } from "../Interfaces/FileInterfaces.ts";
|
|
2
|
+
/**
|
|
3
|
+
* The image editor module, downloaded once per page. A failed download is not kept, so the next Edit tries again.
|
|
4
|
+
* Rejects with an `Error` in plain words ("The image editor is not installed on this server yet.", "The image editor
|
|
5
|
+
* could not be downloaded..."), and logs the cause (a network error, a 404, a bundler that rewrote the import) to the
|
|
6
|
+
* console, so a page that shows the message never hides why.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* const { openImageEditor } = await loadImageEditor();
|
|
10
|
+
* const picture = await openImageEditor({ src: file, aspect: 1, thumbnail: 256 });
|
|
11
|
+
*/
|
|
12
|
+
export declare function loadImageEditor(): Promise<ImageEditorModule>;
|
|
13
|
+
/** Starts the download early, on the hover or focus of an Edit button, so the editor opens at once. Never rejects. */
|
|
14
|
+
export declare function preloadImageEditor(): void;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { getFileAdapter } from "./FileApi.js";
|
|
3
|
+
import { importModule } from "./ModuleImport.js";
|
|
4
|
+
/*
|
|
5
|
+
* The image editor (`nexus-image-editor`, about 45 KB gzipped) is never in an app's bundle: the file backend serves it
|
|
6
|
+
* at a versioned address, and this loader downloads it the first time someone edits a picture. The address comes from
|
|
7
|
+
* the adapter (with Nexus, Drive's `Assets/File/nexus-image-editor.txt` names the current file), and the import is left
|
|
8
|
+
* alone by the bundler (`importModule`, ModuleImport.ts), so the module is fetched by the browser itself and cached by
|
|
9
|
+
* its immutable name.
|
|
10
|
+
*/
|
|
11
|
+
let loading = null;
|
|
12
|
+
/** What a person reads when the module itself could not be downloaded or run: the cause goes to the console. */
|
|
13
|
+
const NOT_DOWNLOADED = "The image editor could not be downloaded. Check the connection and try again; if it keeps failing, tell the site's support.";
|
|
14
|
+
/**
|
|
15
|
+
* The image editor module, downloaded once per page. A failed download is not kept, so the next Edit tries again.
|
|
16
|
+
* Rejects with an `Error` in plain words ("The image editor is not installed on this server yet.", "The image editor
|
|
17
|
+
* could not be downloaded..."), and logs the cause (a network error, a 404, a bundler that rewrote the import) to the
|
|
18
|
+
* console, so a page that shows the message never hides why.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* const { openImageEditor } = await loadImageEditor();
|
|
22
|
+
* const picture = await openImageEditor({ src: file, aspect: 1, thumbnail: 256 });
|
|
23
|
+
*/
|
|
24
|
+
export function loadImageEditor() {
|
|
25
|
+
loading ??= getFileAdapter()
|
|
26
|
+
.editorModuleUrl()
|
|
27
|
+
.then(url => importModule(url).catch((cause) => {
|
|
28
|
+
console.error(`loadImageEditor(): ${url} could not be imported.`, cause);
|
|
29
|
+
throw new Error(NOT_DOWNLOADED);
|
|
30
|
+
}), (cause) => {
|
|
31
|
+
// The address could not be read: the adapter says why in plain words ("not installed on this server yet").
|
|
32
|
+
console.error("loadImageEditor(): the image editor's address could not be read.", cause);
|
|
33
|
+
throw cause instanceof Error && cause.message ? cause : new Error(NOT_DOWNLOADED);
|
|
34
|
+
})
|
|
35
|
+
.then(module => {
|
|
36
|
+
if (typeof module?.openImageEditor !== "function") {
|
|
37
|
+
console.error("loadImageEditor(): the module downloaded has no openImageEditor.", module);
|
|
38
|
+
throw new Error("The image editor on the server is not one this page can open.");
|
|
39
|
+
}
|
|
40
|
+
return module;
|
|
41
|
+
})
|
|
42
|
+
.catch((error) => {
|
|
43
|
+
loading = null;
|
|
44
|
+
throw error instanceof Error ? error : new Error(NOT_DOWNLOADED);
|
|
45
|
+
});
|
|
46
|
+
return loading;
|
|
47
|
+
}
|
|
48
|
+
/** Starts the download early, on the hover or focus of an Edit button, so the editor opens at once. Never rejects. */
|
|
49
|
+
export function preloadImageEditor() {
|
|
50
|
+
loadImageEditor().catch(() => undefined);
|
|
51
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { type CrudBackend } from "../Helpers/CrudBackend.ts";
|
|
2
|
+
import type { ApiEndpoint } from "../Interfaces/ApiInterfaces.ts";
|
|
3
|
+
import type { DropdownPage, DropdownPageRequest, OptionValue } from "../Interfaces/InputInterfaces.ts";
|
|
4
|
+
import type { TableJoinSource, TableJoinedRecord } from "../Interfaces/TableInterfaces.ts";
|
|
5
|
+
/**
|
|
6
|
+
* A join's source as the table calls it. An endpoint becomes one that POSTs the keys to it as an array and reads the
|
|
7
|
+
* records it answers - a Nexus controller's `findListing` - made once per endpoint, so every table and picker naming it
|
|
8
|
+
* shares one source and so one cache. A source of the page's own is used as it is.
|
|
9
|
+
*
|
|
10
|
+
* `key` is the field the records answered are filed under, `id` unless told: one whose values are another field (a
|
|
11
|
+
* person's account, which their company row carries beside its own key) is a source of its own, kept apart.
|
|
12
|
+
*/
|
|
13
|
+
export declare function joinSource(source: ApiEndpoint | TableJoinSource, backend?: CrudBackend, key?: string): TableJoinSource;
|
|
14
|
+
/**
|
|
15
|
+
* The record a `findListing` answered for a key, or one the page remembered there (`TableJoins.remember`), at once and
|
|
16
|
+
* with no call, while it is fresh: `undefined` while it is not in, and once it was marked old (a save on that controller,
|
|
17
|
+
* a Reload), so a picker asks again and shows the record as it is now. A picker over that controller's records names a
|
|
18
|
+
* value with it (`peekOption`), and so does a CRUD's save, which takes an old one too (`aged`) over no name at all.
|
|
19
|
+
*/
|
|
20
|
+
export declare function peekFound(findListing: ApiEndpoint, key: string, aged?: boolean): TableJoinedRecord | undefined;
|
|
21
|
+
/** The controller a picker offers records from: any with an `activeListing` and a `findListing` (`MODULES.controller(...)`). */
|
|
22
|
+
export interface PickerController {
|
|
23
|
+
activeListing: ApiEndpoint;
|
|
24
|
+
findListing: ApiEndpoint;
|
|
25
|
+
}
|
|
26
|
+
/** What `crudPicker` needs to know of the records: the field a person reads, and the one under it. */
|
|
27
|
+
export interface CrudPickerOptions {
|
|
28
|
+
/** The field shown as the option: `"regionName"`. */
|
|
29
|
+
labelKey: string;
|
|
30
|
+
/** A field shown under it, such as the parent's name: `"regionName"` under a sub-region. */
|
|
31
|
+
descriptionKey?: string;
|
|
32
|
+
/**
|
|
33
|
+
* The field that holds the value. Default `id`: the records' own key, which is what the controller's `findListing`
|
|
34
|
+
* takes. Another field - a person's account (`userId`), which their company row carries beside its own key - needs
|
|
35
|
+
* `find` for the values the kept list does not offer.
|
|
36
|
+
*/
|
|
37
|
+
valueKey?: string;
|
|
38
|
+
/**
|
|
39
|
+
* Where a value the kept list does not offer is looked up when `valueKey` is not `id`: an endpoint that takes such
|
|
40
|
+
* values, POSTed as an array as `findListing` takes keys, and answers the records, each read by its `valueKey` field;
|
|
41
|
+
* or a source of the page's own. Its answers are kept apart from `findListing`'s and marked old with them, after a save
|
|
42
|
+
* on the controller. Without it such a value is never looked up - `findListing` could not answer it - so a form names it
|
|
43
|
+
* from the record it holds (`selectedOptions`), or it shows as not found.
|
|
44
|
+
*/
|
|
45
|
+
find?: ApiEndpoint | TableJoinSource;
|
|
46
|
+
/**
|
|
47
|
+
* The query parameter the controller's `activeListing` narrows by on the server, for a picker another input narrows
|
|
48
|
+
* (`narrowedBy`): `"subscriptionGroupId"` asks `...?subscriptionGroupId={the group}` and keeps each answer apart. Without
|
|
49
|
+
* it, the whole list is read once and narrowed in the browser by the records' own field (`narrowedBy.key`).
|
|
50
|
+
*/
|
|
51
|
+
narrowQuery?: string;
|
|
52
|
+
backend?: CrudBackend;
|
|
53
|
+
}
|
|
54
|
+
/** The dropdown params `crudPicker` gives: spread them into a dropdown's input. */
|
|
55
|
+
export interface CrudPickerParams {
|
|
56
|
+
loadOptions: (request: DropdownPageRequest) => Promise<DropdownPage<TableJoinedRecord>>;
|
|
57
|
+
resolveOptions: (values: OptionValue[]) => Promise<readonly TableJoinedRecord[]>;
|
|
58
|
+
peekOption: (key: string, aged?: boolean) => TableJoinedRecord | undefined;
|
|
59
|
+
valueKey: string;
|
|
60
|
+
labelKey: string;
|
|
61
|
+
descriptionKey?: string;
|
|
62
|
+
isOptionInactive: (item: TableJoinedRecord) => boolean;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* A dropdown of a controller's usable records, for picking a parent in a form: the `activeListing` read once and kept
|
|
66
|
+
* for every form on the page (the owner's caching rule: a second dropdown, or an Add row, never asks again), searched
|
|
67
|
+
* and paged in the browser. A value the form already holds that the list does not offer - a parent since trashed - is
|
|
68
|
+
* found through `findListing`, sharing the calls and answers of the tables' joins, and shows tagged, never offered again.
|
|
69
|
+
* A value that is not the records' key (`valueKey`) is found through the picker's own `find` instead.
|
|
70
|
+
*
|
|
71
|
+
* @example { type: EInputTypes.Dropdown, name: "regionId", label: "Region", required: true, ...crudPicker(REGIONS, { labelKey: "regionName" }) }
|
|
72
|
+
* @example crudPicker(COMPANY_USERS, { labelKey: "fullname", valueKey: "userId", find: COMPANY_USERS_BY_ACCOUNT })
|
|
73
|
+
*/
|
|
74
|
+
export declare function crudPicker(controller: PickerController, { labelKey, descriptionKey, valueKey, find, narrowQuery, backend }: CrudPickerOptions): CrudPickerParams;
|
|
75
|
+
/**
|
|
76
|
+
* Marks what the page looked up from a controller as old, after a write there may have changed it: the records its
|
|
77
|
+
* `findListing` named and its pickers' own finds answered, and the list its picker offers. Drawn as they are until the
|
|
78
|
+
* next ask brings the new ones.
|
|
79
|
+
*/
|
|
80
|
+
export declare function expireLookups(controller: Partial<PickerController>): void;
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { isApiEndpoint } from "../Helpers/ApiRoutes.js";
|
|
2
|
+
import { getCrudBackend } from "../Helpers/CrudBackend.js";
|
|
3
|
+
import { filterItems } from "../Helpers/DropdownHelpers.js";
|
|
4
|
+
import { JOIN_LIFETIME, joinSourceName, tableJoins } from "../Helpers/TableJoins.js";
|
|
5
|
+
import { api } from "./BrowserApi.js";
|
|
6
|
+
/*
|
|
7
|
+
* The browser's half of a join: the call that looks records up, and a picker that shares what it looked up. The cache
|
|
8
|
+
* itself (`tableJoins`) knows nothing of the API; this is where an endpoint becomes a source it can call.
|
|
9
|
+
*/
|
|
10
|
+
const made = new Map();
|
|
11
|
+
/** The sources of the pickers' own finds (`crudPicker` `find`), by the name of the `findListing` of their controller. */
|
|
12
|
+
const finds = new Map();
|
|
13
|
+
/** The lists a picker asked the server for, one per narrowing value (`narrowQuery`), by the name of their whole list. */
|
|
14
|
+
const narrowedLists = new Map();
|
|
15
|
+
/** A field with no value: what `narrow.orUnset` adds to a narrowed list. */
|
|
16
|
+
const unset = (value) => value === null || value === undefined || value === "";
|
|
17
|
+
/**
|
|
18
|
+
* A join's source as the table calls it. An endpoint becomes one that POSTs the keys to it as an array and reads the
|
|
19
|
+
* records it answers - a Nexus controller's `findListing` - made once per endpoint, so every table and picker naming it
|
|
20
|
+
* shares one source and so one cache. A source of the page's own is used as it is.
|
|
21
|
+
*
|
|
22
|
+
* `key` is the field the records answered are filed under, `id` unless told: one whose values are another field (a
|
|
23
|
+
* person's account, which their company row carries beside its own key) is a source of its own, kept apart.
|
|
24
|
+
*/
|
|
25
|
+
export function joinSource(source, backend = getCrudBackend(), key = "id") {
|
|
26
|
+
if (!isApiEndpoint(source))
|
|
27
|
+
return source;
|
|
28
|
+
const name = key === "id" ? joinSourceName(source) : `${joinSourceName(source)} by ${key}`;
|
|
29
|
+
let found = made.get(name);
|
|
30
|
+
if (!found) {
|
|
31
|
+
found = {
|
|
32
|
+
name,
|
|
33
|
+
...(key !== "id" && { key }),
|
|
34
|
+
async load(keys, signal) {
|
|
35
|
+
const answer = await api.send(source, { body: keys, signal, toast: false });
|
|
36
|
+
if (!answer.ok)
|
|
37
|
+
throw new Error(answer.message ?? "The records could not be looked up.");
|
|
38
|
+
return backend.readList(answer.result);
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
made.set(name, found);
|
|
42
|
+
}
|
|
43
|
+
return found;
|
|
44
|
+
}
|
|
45
|
+
/** What a source answered for a key, fresh, or - `aged` - also once it was marked old. */
|
|
46
|
+
function peekSource(name, key, aged) {
|
|
47
|
+
if (!aged)
|
|
48
|
+
return tableJoins.peekFresh(name, key);
|
|
49
|
+
const state = tableJoins.peek(name, key);
|
|
50
|
+
return state.status === "ready" ? state.record : undefined;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* The record a `findListing` answered for a key, or one the page remembered there (`TableJoins.remember`), at once and
|
|
54
|
+
* with no call, while it is fresh: `undefined` while it is not in, and once it was marked old (a save on that controller,
|
|
55
|
+
* a Reload), so a picker asks again and shows the record as it is now. A picker over that controller's records names a
|
|
56
|
+
* value with it (`peekOption`), and so does a CRUD's save, which takes an old one too (`aged`) over no name at all.
|
|
57
|
+
*/
|
|
58
|
+
export function peekFound(findListing, key, aged = false) {
|
|
59
|
+
return peekSource(joinSourceName(findListing), key, aged);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* A dropdown of a controller's usable records, for picking a parent in a form: the `activeListing` read once and kept
|
|
63
|
+
* for every form on the page (the owner's caching rule: a second dropdown, or an Add row, never asks again), searched
|
|
64
|
+
* and paged in the browser. A value the form already holds that the list does not offer - a parent since trashed - is
|
|
65
|
+
* found through `findListing`, sharing the calls and answers of the tables' joins, and shows tagged, never offered again.
|
|
66
|
+
* A value that is not the records' key (`valueKey`) is found through the picker's own `find` instead.
|
|
67
|
+
*
|
|
68
|
+
* @example { type: EInputTypes.Dropdown, name: "regionId", label: "Region", required: true, ...crudPicker(REGIONS, { labelKey: "regionName" }) }
|
|
69
|
+
* @example crudPicker(COMPANY_USERS, { labelKey: "fullname", valueKey: "userId", find: COMPANY_USERS_BY_ACCOUNT })
|
|
70
|
+
*/
|
|
71
|
+
export function crudPicker(controller, { labelKey, descriptionKey, valueKey = "id", find, narrowQuery, backend = getCrudBackend() }) {
|
|
72
|
+
const listName = joinSourceName(controller.activeListing);
|
|
73
|
+
// Where a value the kept list does not offer is looked up: `findListing` while the values are the records' keys, the
|
|
74
|
+
// picker's own find for another field, and nowhere without one.
|
|
75
|
+
const lookup = find ? joinSource(find, backend, valueKey) : valueKey === "id" ? joinSource(controller.findListing, backend) : null;
|
|
76
|
+
if (find && lookup) {
|
|
77
|
+
// Marked old with the controller's own lookups, after a save there (`expireLookups`).
|
|
78
|
+
const beside = joinSourceName(controller.findListing);
|
|
79
|
+
const kept = finds.get(beside) ?? new Set();
|
|
80
|
+
kept.add(lookup.name);
|
|
81
|
+
finds.set(beside, kept);
|
|
82
|
+
}
|
|
83
|
+
// The words a person reads, not the key: a Nexus key is an encrypted token, and a search would find letters in it.
|
|
84
|
+
const searchKeys = descriptionKey ? [labelKey, descriptionKey] : [labelKey];
|
|
85
|
+
const loadList = (signal, query) => api.send(controller.activeListing, { signal, toast: false, ...(query && { query }) }).then(answer => {
|
|
86
|
+
if (!answer.ok)
|
|
87
|
+
throw new Error(answer.message ?? "The list could not be loaded.");
|
|
88
|
+
return backend.readList(answer.result);
|
|
89
|
+
});
|
|
90
|
+
/** The options narrowed by another input's value (`narrowedBy`): asked of the server by `narrowQuery`, else the kept list's. */
|
|
91
|
+
const narrowedList = async ({ key, value, orUnset }) => {
|
|
92
|
+
// The server narrows by a value; which records it adds for `orUnset` is its endpoint's rule.
|
|
93
|
+
if (narrowQuery && value !== null) {
|
|
94
|
+
const name = `${listName}?${narrowQuery}=${String(value)}`;
|
|
95
|
+
const kept = narrowedLists.get(listName) ?? new Set();
|
|
96
|
+
kept.add(name);
|
|
97
|
+
narrowedLists.set(listName, kept);
|
|
98
|
+
return tableJoins.list(name, signal => loadList(signal, { [narrowQuery]: String(value) }));
|
|
99
|
+
}
|
|
100
|
+
const all = await tableJoins.list(listName, loadList);
|
|
101
|
+
return all.filter(row => (value !== null && String(row[key]) === String(value)) || (orUnset && unset(row[key])));
|
|
102
|
+
};
|
|
103
|
+
return {
|
|
104
|
+
async loadOptions({ search, skip, pageSize, narrow }) {
|
|
105
|
+
const all = narrow ? await narrowedList(narrow) : await tableJoins.list(listName, loadList);
|
|
106
|
+
const matches = search ? filterItems(all, search, searchKeys) : all;
|
|
107
|
+
return { items: matches.slice(skip, skip + pageSize), total: matches.length, hasMore: skip + pageSize < matches.length };
|
|
108
|
+
},
|
|
109
|
+
// A saved value the kept list offers is named from it, with no call (a form opened on a tree's country); only one it
|
|
110
|
+
// does not offer - a parent since trashed - is looked up.
|
|
111
|
+
async resolveOptions(values) {
|
|
112
|
+
const keys = values.map(String);
|
|
113
|
+
const kept = tableJoins.peekList(listName) ?? [];
|
|
114
|
+
const found = kept.filter(row => keys.includes(String(row[valueKey])));
|
|
115
|
+
const missing = keys.filter(key => !found.some(row => String(row[valueKey]) === key));
|
|
116
|
+
if (missing.length === 0 || !lookup)
|
|
117
|
+
return found;
|
|
118
|
+
return [...found, ...(await tableJoins.records(lookup, missing))];
|
|
119
|
+
},
|
|
120
|
+
// The same at once, from what the page holds: a box named on its first draw, a saved record named with no call. Only
|
|
121
|
+
// what is fresh, unless an old record is asked for: a save names a value with one rather than with nothing.
|
|
122
|
+
peekOption(key, aged = false) {
|
|
123
|
+
const kept = tableJoins.peekList(listName, aged ? Infinity : JOIN_LIFETIME)?.find(row => String(row[valueKey]) === key);
|
|
124
|
+
return kept ?? (lookup ? peekSource(lookup.name, key, aged) : undefined);
|
|
125
|
+
},
|
|
126
|
+
valueKey,
|
|
127
|
+
labelKey,
|
|
128
|
+
...(descriptionKey && { descriptionKey }),
|
|
129
|
+
isOptionInactive: item => !backend.isPickable(item),
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Marks what the page looked up from a controller as old, after a write there may have changed it: the records its
|
|
134
|
+
* `findListing` named and its pickers' own finds answered, and the list its picker offers. Drawn as they are until the
|
|
135
|
+
* next ask brings the new ones.
|
|
136
|
+
*/
|
|
137
|
+
export function expireLookups(controller) {
|
|
138
|
+
if (controller.findListing) {
|
|
139
|
+
const name = joinSourceName(controller.findListing);
|
|
140
|
+
tableJoins.expire(name);
|
|
141
|
+
for (const other of finds.get(name) ?? [])
|
|
142
|
+
tableJoins.expire(other);
|
|
143
|
+
}
|
|
144
|
+
if (controller.activeListing) {
|
|
145
|
+
const name = joinSourceName(controller.activeListing);
|
|
146
|
+
tableJoins.expireList(name);
|
|
147
|
+
for (const narrowed of narrowedLists.get(name) ?? [])
|
|
148
|
+
tableJoins.expireList(narrowed);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Imports an ES module by its full address, as the browser does, never through the app's bundler: a module a server
|
|
3
|
+
* serves at a versioned address (the image editor from the Nexus Drive).
|
|
4
|
+
*
|
|
5
|
+
* @example const editor = await importModule<ImageEditorModule>("https://drive.example/Assets/File/nexus-image-editor.3f2a.js");
|
|
6
|
+
*/
|
|
7
|
+
export declare function importModule<TModule>(url: string): Promise<TModule>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* The one dynamic `import()` of an address known only at run time, kept alone in this file on purpose.
|
|
3
|
+
*
|
|
4
|
+
* The package build rewrites "./Button.tsx" to "./Button.js" (`rewriteRelativeImportExtensions`), and for an `import()`
|
|
5
|
+
* of a variable it does so at run time: it wraps the address in a helper call, `import(helper(url))`. The bundler-ignore
|
|
6
|
+
* comments are then inside a call, so Next's Turbopack no longer leaves the import alone: it compiles it to "Cannot find
|
|
7
|
+
* module as expression is too dynamic", and the image editor never loads in an app's production build. This file imports
|
|
8
|
+
* nothing, so it is built a second time without that rewrite (`tsconfig.build.module-import.json`, after the main build,
|
|
9
|
+
* in `npm run build`), and the published file keeps the plain `import(/* webpackIgnore: true *\/ ... url)` that webpack,
|
|
10
|
+
* Turbopack and Vite all leave to the browser. `scripts/test-dist-loader.mts` (in `npm test`) fails if it ever does not.
|
|
11
|
+
*
|
|
12
|
+
* Add no import to this file: the second build would leave a "./x.ts" in it unrewritten.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Imports an ES module by its full address, as the browser does, never through the app's bundler: a module a server
|
|
16
|
+
* serves at a versioned address (the image editor from the Nexus Drive).
|
|
17
|
+
*
|
|
18
|
+
* @example const editor = await importModule<ImageEditorModule>("https://drive.example/Assets/File/nexus-image-editor.3f2a.js");
|
|
19
|
+
*/
|
|
20
|
+
export function importModule(url) {
|
|
21
|
+
return import(/* webpackIgnore: true */ /* turbopackIgnore: true */ /* @vite-ignore */ url);
|
|
22
|
+
}
|
|
@@ -11,7 +11,12 @@ export interface ServerApiOptions {
|
|
|
11
11
|
}
|
|
12
12
|
/** How server calls behave. Where they go (each module's root) is the app's `ApiModules`. */
|
|
13
13
|
export interface ServerApiConfig {
|
|
14
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
* The app's own address, for `serverApi`'s relative roots and URLs such as `/api/…`, and for the X-Forwarded-Host and
|
|
16
|
+
* -Proto the proxy sends. Default: `URL_CURRENT` from the environment. Never a request's Host header as it came: a
|
|
17
|
+
* client can name any address in it, and `serverApi` would call that address. (The proxy calls a relative root at
|
|
18
|
+
* this server's own host and port, whatever this says.)
|
|
19
|
+
*/
|
|
15
20
|
origin?: string | (() => string | undefined | Promise<string | undefined>);
|
|
16
21
|
/** The user's token for every call, such as from the session cookie. */
|
|
17
22
|
token?: () => string | null | undefined | Promise<string | null | undefined>;
|
|
@@ -35,9 +40,15 @@ export interface ServerApiConfig {
|
|
|
35
40
|
* configureServerApi({ token: async () => (await cookies()).get("access_token")?.value });
|
|
36
41
|
*/
|
|
37
42
|
export declare function configureServerApi(config: ServerApiConfig): void;
|
|
43
|
+
/**
|
|
44
|
+
* The app's own address, as `configureServerApi({ origin })` or `URL_CURRENT` gives it; `undefined` when neither does.
|
|
45
|
+
* The proxy tells the backend it in X-Forwarded-Host and X-Forwarded-Proto.
|
|
46
|
+
*/
|
|
47
|
+
export declare function serverAppOrigin(): Promise<string | undefined>;
|
|
38
48
|
/**
|
|
39
49
|
* A module's absolute root URL on the server, from the app's `ApiModules`. Throws "The Reservation API address is not
|
|
40
|
-
* set (API_RESERVATION)." when it is missing. `origin` resolves a relative root
|
|
50
|
+
* set (API_RESERVATION)." when it is missing. `origin` resolves a relative root (the proxy passes this server's own);
|
|
51
|
+
* without it, the app's (`serverAppOrigin`).
|
|
41
52
|
*/
|
|
42
53
|
export declare function serverModuleRoot(module: ApiModuleValue, origin?: string): Promise<string>;
|
|
43
54
|
/**
|
|
@@ -12,21 +12,26 @@ let settings = {};
|
|
|
12
12
|
export function configureServerApi(config) {
|
|
13
13
|
settings = { ...settings, ...config };
|
|
14
14
|
}
|
|
15
|
-
|
|
15
|
+
/**
|
|
16
|
+
* The app's own address, as `configureServerApi({ origin })` or `URL_CURRENT` gives it; `undefined` when neither does.
|
|
17
|
+
* The proxy tells the backend it in X-Forwarded-Host and X-Forwarded-Proto.
|
|
18
|
+
*/
|
|
19
|
+
export async function serverAppOrigin() {
|
|
16
20
|
const value = typeof settings.origin === "function" ? await settings.origin() : settings.origin;
|
|
17
21
|
return value || readEnvironment("URL_CURRENT");
|
|
18
22
|
}
|
|
19
23
|
async function absolute(url, fallbackOrigin) {
|
|
20
24
|
if (/^https?:\/\//i.test(url))
|
|
21
25
|
return url;
|
|
22
|
-
const origin = fallbackOrigin ?? (await
|
|
26
|
+
const origin = fallbackOrigin ?? (await serverAppOrigin());
|
|
23
27
|
if (!origin)
|
|
24
28
|
throw new Error(`"${url}" is relative, and the app's address is not set (URL_CURRENT).`);
|
|
25
29
|
return new URL(url.startsWith("/") ? url : `/${url}`, origin).toString();
|
|
26
30
|
}
|
|
27
31
|
/**
|
|
28
32
|
* A module's absolute root URL on the server, from the app's `ApiModules`. Throws "The Reservation API address is not
|
|
29
|
-
* set (API_RESERVATION)." when it is missing. `origin` resolves a relative root
|
|
33
|
+
* set (API_RESERVATION)." when it is missing. `origin` resolves a relative root (the proxy passes this server's own);
|
|
34
|
+
* without it, the app's (`serverAppOrigin`).
|
|
30
35
|
*/
|
|
31
36
|
export async function serverModuleRoot(module, origin) {
|
|
32
37
|
return absolute(await getApiModules().serverUrl(module), origin);
|
package/dist/Shared.Index.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export * from "./Components/Documents/Button.tsx";
|
|
2
|
+
export * from "./Components/Documents/PrintDocument.tsx";
|
|
2
3
|
export * from "./Components/Inputs/Field.tsx";
|
|
3
4
|
export * from "./Components/Layouts/ThemeScript.tsx";
|
|
4
5
|
export * from "./Components/Viewers/MarkdownView.tsx";
|
|
6
|
+
export * from "./Components/Viewers/QrCodeImage.tsx";
|
|
5
7
|
export * from "./Components/Viewers/RichTextView.tsx";
|
|
6
8
|
export * from "./Helpers/ApiClient.ts";
|
|
7
9
|
export * from "./Helpers/ApiFormHelpers.ts";
|
|
@@ -14,26 +16,42 @@ export * from "./Helpers/ChatHelpers.ts";
|
|
|
14
16
|
export * from "./Helpers/ChatStore.ts";
|
|
15
17
|
export * from "./Helpers/ChatSummaries.ts";
|
|
16
18
|
export * from "./Helpers/ClassHelpers.ts";
|
|
19
|
+
export * from "./Helpers/CodeHelpers.ts";
|
|
17
20
|
export * from "./Helpers/CrudBackend.ts";
|
|
21
|
+
export * from "./Helpers/CrudColumns.ts";
|
|
22
|
+
export * from "./Helpers/CrudDetailsTabs.ts";
|
|
18
23
|
export * from "./Helpers/CrudHelpers.ts";
|
|
19
24
|
export * from "./Helpers/DateHelpers.ts";
|
|
20
25
|
export * from "./Helpers/DateTimeHelpers.ts";
|
|
21
26
|
export * from "./Helpers/DropdownHelpers.ts";
|
|
22
27
|
export * from "./Helpers/ExcelBackend.ts";
|
|
23
28
|
export * from "./Helpers/ExcelHelpers.ts";
|
|
29
|
+
export * from "./Helpers/FileAdapter.ts";
|
|
30
|
+
export * from "./Helpers/FilePrimaries.ts";
|
|
31
|
+
export * from "./Helpers/NexusDriveAdapter.ts";
|
|
32
|
+
export * from "./Helpers/FormConfirm.ts";
|
|
24
33
|
export * from "./Helpers/FormDrafts.ts";
|
|
25
34
|
export * from "./Helpers/FormStore.ts";
|
|
26
35
|
export * from "./Helpers/InputParamsHelpers.ts";
|
|
36
|
+
export * from "./Helpers/InputConditions.ts";
|
|
37
|
+
export * from "./Helpers/InputNarrowing.ts";
|
|
38
|
+
export * from "./Helpers/CrudNarrowPick.ts";
|
|
39
|
+
export * from "./Helpers/CrudScopes.ts";
|
|
40
|
+
export * from "./Helpers/CrudRowForms.ts";
|
|
27
41
|
export * from "./Helpers/MarkdownEditing.ts";
|
|
28
42
|
export * from "./Helpers/MarkdownHelpers.ts";
|
|
29
43
|
export * from "./Helpers/MessageBuilder.ts";
|
|
30
44
|
export * from "./Helpers/NepaliCalendar.ts";
|
|
31
45
|
export * from "./Helpers/NumberHelpers.ts";
|
|
32
46
|
export * from "./Helpers/Permissions.ts";
|
|
47
|
+
export * from "./Helpers/QrCode.ts";
|
|
48
|
+
export * from "./Helpers/RecordCards.ts";
|
|
49
|
+
export * from "./Helpers/RequestCache.ts";
|
|
33
50
|
export * from "./Helpers/RichTextHelpers.ts";
|
|
34
51
|
export * from "./Helpers/RowsStore.ts";
|
|
35
52
|
export * from "./Helpers/TableFilters.ts";
|
|
36
53
|
export * from "./Helpers/TableHelpers.ts";
|
|
54
|
+
export * from "./Helpers/TableJoins.ts";
|
|
37
55
|
export * from "./Helpers/TableStore.ts";
|
|
38
56
|
export * from "./Helpers/ThemeHelpers.ts";
|
|
39
57
|
export * from "./Helpers/TimeHelpers.ts";
|
|
@@ -44,10 +62,12 @@ export * from "./Interfaces/ChatInterfaces.ts";
|
|
|
44
62
|
export * from "./Interfaces/CrudInterfaces.ts";
|
|
45
63
|
export * from "./Interfaces/DateInterfaces.ts";
|
|
46
64
|
export * from "./Interfaces/ExcelInterfaces.ts";
|
|
65
|
+
export * from "./Interfaces/FileInterfaces.ts";
|
|
47
66
|
export * from "./Interfaces/FormInterfaces.ts";
|
|
48
67
|
export * from "./Interfaces/InputInterfaces.ts";
|
|
49
68
|
export * from "./Interfaces/MessageInterfaces.ts";
|
|
50
69
|
export * from "./Interfaces/PreferenceInterfaces.ts";
|
|
70
|
+
export * from "./Interfaces/RecordInterfaces.ts";
|
|
51
71
|
export * from "./Interfaces/TableInterfaces.ts";
|
|
52
72
|
export * from "./Interfaces/ThemeInterfaces.ts";
|
|
53
73
|
export * from "./Interfaces/TypeInterfaces.ts";
|
package/dist/Shared.Index.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
// Works everywhere: server components, client components, and plain TypeScript.
|
|
2
2
|
// Components
|
|
3
3
|
export * from "./Components/Documents/Button.js";
|
|
4
|
+
export * from "./Components/Documents/PrintDocument.js";
|
|
4
5
|
export * from "./Components/Inputs/Field.js";
|
|
5
6
|
export * from "./Components/Layouts/ThemeScript.js";
|
|
6
7
|
export * from "./Components/Viewers/MarkdownView.js";
|
|
8
|
+
export * from "./Components/Viewers/QrCodeImage.js";
|
|
7
9
|
export * from "./Components/Viewers/RichTextView.js";
|
|
8
10
|
// Helpers
|
|
9
11
|
export * from "./Helpers/ApiClient.js";
|
|
@@ -17,26 +19,42 @@ export * from "./Helpers/ChatHelpers.js";
|
|
|
17
19
|
export * from "./Helpers/ChatStore.js";
|
|
18
20
|
export * from "./Helpers/ChatSummaries.js";
|
|
19
21
|
export * from "./Helpers/ClassHelpers.js";
|
|
22
|
+
export * from "./Helpers/CodeHelpers.js";
|
|
20
23
|
export * from "./Helpers/CrudBackend.js";
|
|
24
|
+
export * from "./Helpers/CrudColumns.js";
|
|
25
|
+
export * from "./Helpers/CrudDetailsTabs.js";
|
|
21
26
|
export * from "./Helpers/CrudHelpers.js";
|
|
22
27
|
export * from "./Helpers/DateHelpers.js";
|
|
23
28
|
export * from "./Helpers/DateTimeHelpers.js";
|
|
24
29
|
export * from "./Helpers/DropdownHelpers.js";
|
|
25
30
|
export * from "./Helpers/ExcelBackend.js";
|
|
26
31
|
export * from "./Helpers/ExcelHelpers.js";
|
|
32
|
+
export * from "./Helpers/FileAdapter.js";
|
|
33
|
+
export * from "./Helpers/FilePrimaries.js";
|
|
34
|
+
export * from "./Helpers/NexusDriveAdapter.js";
|
|
35
|
+
export * from "./Helpers/FormConfirm.js";
|
|
27
36
|
export * from "./Helpers/FormDrafts.js";
|
|
28
37
|
export * from "./Helpers/FormStore.js";
|
|
29
38
|
export * from "./Helpers/InputParamsHelpers.js";
|
|
39
|
+
export * from "./Helpers/InputConditions.js";
|
|
40
|
+
export * from "./Helpers/InputNarrowing.js";
|
|
41
|
+
export * from "./Helpers/CrudNarrowPick.js";
|
|
42
|
+
export * from "./Helpers/CrudScopes.js";
|
|
43
|
+
export * from "./Helpers/CrudRowForms.js";
|
|
30
44
|
export * from "./Helpers/MarkdownEditing.js";
|
|
31
45
|
export * from "./Helpers/MarkdownHelpers.js";
|
|
32
46
|
export * from "./Helpers/MessageBuilder.js";
|
|
33
47
|
export * from "./Helpers/NepaliCalendar.js";
|
|
34
48
|
export * from "./Helpers/NumberHelpers.js";
|
|
35
49
|
export * from "./Helpers/Permissions.js";
|
|
50
|
+
export * from "./Helpers/QrCode.js";
|
|
51
|
+
export * from "./Helpers/RecordCards.js";
|
|
52
|
+
export * from "./Helpers/RequestCache.js";
|
|
36
53
|
export * from "./Helpers/RichTextHelpers.js";
|
|
37
54
|
export * from "./Helpers/RowsStore.js";
|
|
38
55
|
export * from "./Helpers/TableFilters.js";
|
|
39
56
|
export * from "./Helpers/TableHelpers.js";
|
|
57
|
+
export * from "./Helpers/TableJoins.js";
|
|
40
58
|
export * from "./Helpers/TableStore.js";
|
|
41
59
|
export * from "./Helpers/ThemeHelpers.js";
|
|
42
60
|
export * from "./Helpers/TimeHelpers.js";
|
|
@@ -48,10 +66,12 @@ export * from "./Interfaces/ChatInterfaces.js";
|
|
|
48
66
|
export * from "./Interfaces/CrudInterfaces.js";
|
|
49
67
|
export * from "./Interfaces/DateInterfaces.js";
|
|
50
68
|
export * from "./Interfaces/ExcelInterfaces.js";
|
|
69
|
+
export * from "./Interfaces/FileInterfaces.js";
|
|
51
70
|
export * from "./Interfaces/FormInterfaces.js";
|
|
52
71
|
export * from "./Interfaces/InputInterfaces.js";
|
|
53
72
|
export * from "./Interfaces/MessageInterfaces.js";
|
|
54
73
|
export * from "./Interfaces/PreferenceInterfaces.js";
|
|
74
|
+
export * from "./Interfaces/RecordInterfaces.js";
|
|
55
75
|
export * from "./Interfaces/TableInterfaces.js";
|
|
56
76
|
export * from "./Interfaces/ThemeInterfaces.js";
|
|
57
77
|
export * from "./Interfaces/TypeInterfaces.js";
|