Last round of prettier: npx prettier --write src/
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "osit-aether-app-svelte",
|
"name": "osit-aether-app-svelte",
|
||||||
"version": "3.00.05",
|
"version": "3.00.06",
|
||||||
"description": "One Sky IT's Aether App created with Svelte, SvelteKit, Tailwind CSS, Lucide, Font Awesome, and Skeleton UI. -Scott Idem",
|
"description": "One Sky IT's Aether App created with Svelte, SvelteKit, Tailwind CSS, Lucide, Font Awesome, and Skeleton UI. -Scott Idem",
|
||||||
"homepage": "https://oneskyit.com/",
|
"homepage": "https://oneskyit.com/",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
|||||||
@@ -63,50 +63,50 @@ html[data-theme='AE_Firefly_Indigo'] {
|
|||||||
|
|
||||||
/* --- Color ramps (light mode) copied from dark block so both modes have full ramps --- */
|
/* --- Color ramps (light mode) copied from dark block so both modes have full ramps --- */
|
||||||
html[data-theme='AE_Firefly_Indigo'] {
|
html[data-theme='AE_Firefly_Indigo'] {
|
||||||
--color-primary-50: oklch(95.5% 0.040 270deg);
|
--color-primary-50: oklch(95.5% 0.04 270deg);
|
||||||
--color-primary-100: oklch(89.5% 0.072 270deg);
|
--color-primary-100: oklch(89.5% 0.072 270deg);
|
||||||
--color-primary-200: oklch(82.5% 0.108 269deg);
|
--color-primary-200: oklch(82.5% 0.108 269deg);
|
||||||
--color-primary-300: oklch(74.5% 0.135 268deg);
|
--color-primary-300: oklch(74.5% 0.135 268deg);
|
||||||
--color-primary-400: oklch(65.0% 0.155 267deg);
|
--color-primary-400: oklch(65% 0.155 267deg);
|
||||||
--color-primary-500: oklch(50.5% 0.160 266deg);
|
--color-primary-500: oklch(50.5% 0.16 266deg);
|
||||||
--color-primary-600: oklch(43.5% 0.152 265deg);
|
--color-primary-600: oklch(43.5% 0.152 265deg);
|
||||||
--color-primary-700: oklch(37.0% 0.138 264deg);
|
--color-primary-700: oklch(37% 0.138 264deg);
|
||||||
--color-primary-800: oklch(30.0% 0.120 263deg);
|
--color-primary-800: oklch(30% 0.12 263deg);
|
||||||
--color-primary-900: oklch(23.0% 0.100 262deg);
|
--color-primary-900: oklch(23% 0.1 262deg);
|
||||||
--color-primary-950: oklch(15.5% 0.080 261deg);
|
--color-primary-950: oklch(15.5% 0.08 261deg);
|
||||||
--color-primary-contrast-dark: var(--color-primary-950);
|
--color-primary-contrast-dark: var(--color-primary-950);
|
||||||
--color-primary-contrast-light: var(--color-primary-50);
|
--color-primary-contrast-light: var(--color-primary-50);
|
||||||
|
|
||||||
--color-secondary-50: oklch(96.5% 0.032 297deg);
|
--color-secondary-50: oklch(96.5% 0.032 297deg);
|
||||||
--color-secondary-100: oklch(91.5% 0.058 295deg);
|
--color-secondary-100: oklch(91.5% 0.058 295deg);
|
||||||
--color-secondary-200: oklch(85.5% 0.090 293deg);
|
--color-secondary-200: oklch(85.5% 0.09 293deg);
|
||||||
--color-secondary-300: oklch(78.5% 0.115 292deg);
|
--color-secondary-300: oklch(78.5% 0.115 292deg);
|
||||||
--color-secondary-400: oklch(70.0% 0.132 291deg);
|
--color-secondary-400: oklch(70% 0.132 291deg);
|
||||||
--color-secondary-500: oklch(60.0% 0.140 290deg);
|
--color-secondary-500: oklch(60% 0.14 290deg);
|
||||||
--color-secondary-600: oklch(52.5% 0.135 289deg);
|
--color-secondary-600: oklch(52.5% 0.135 289deg);
|
||||||
--color-secondary-700: oklch(45.0% 0.126 288deg);
|
--color-secondary-700: oklch(45% 0.126 288deg);
|
||||||
--color-secondary-800: oklch(37.5% 0.112 286deg);
|
--color-secondary-800: oklch(37.5% 0.112 286deg);
|
||||||
--color-secondary-900: oklch(30.0% 0.094 284deg);
|
--color-secondary-900: oklch(30% 0.094 284deg);
|
||||||
--color-secondary-950: oklch(22.0% 0.076 282deg);
|
--color-secondary-950: oklch(22% 0.076 282deg);
|
||||||
--color-secondary-contrast-dark: var(--color-secondary-950);
|
--color-secondary-contrast-dark: var(--color-secondary-950);
|
||||||
--color-secondary-contrast-light: var(--color-secondary-50);
|
--color-secondary-contrast-light: var(--color-secondary-50);
|
||||||
|
|
||||||
--color-tertiary-50: oklch(96.5% 0.022 348deg);
|
--color-tertiary-50: oklch(96.5% 0.022 348deg);
|
||||||
--color-tertiary-100: oklch(91.0% 0.042 346deg);
|
--color-tertiary-100: oklch(91% 0.042 346deg);
|
||||||
--color-tertiary-200: oklch(84.5% 0.068 344deg);
|
--color-tertiary-200: oklch(84.5% 0.068 344deg);
|
||||||
--color-tertiary-300: oklch(76.5% 0.095 343deg);
|
--color-tertiary-300: oklch(76.5% 0.095 343deg);
|
||||||
--color-tertiary-400: oklch(68.0% 0.118 342deg);
|
--color-tertiary-400: oklch(68% 0.118 342deg);
|
||||||
--color-tertiary-500: oklch(57.5% 0.128 341deg);
|
--color-tertiary-500: oklch(57.5% 0.128 341deg);
|
||||||
--color-tertiary-600: oklch(50.0% 0.122 340deg);
|
--color-tertiary-600: oklch(50% 0.122 340deg);
|
||||||
--color-tertiary-700: oklch(43.0% 0.112 339deg);
|
--color-tertiary-700: oklch(43% 0.112 339deg);
|
||||||
--color-tertiary-800: oklch(35.5% 0.098 338deg);
|
--color-tertiary-800: oklch(35.5% 0.098 338deg);
|
||||||
--color-tertiary-900: oklch(28.0% 0.080 337deg);
|
--color-tertiary-900: oklch(28% 0.08 337deg);
|
||||||
--color-tertiary-950: oklch(20.5% 0.062 336deg);
|
--color-tertiary-950: oklch(20.5% 0.062 336deg);
|
||||||
--color-tertiary-contrast-dark: var(--color-tertiary-950);
|
--color-tertiary-contrast-dark: var(--color-tertiary-950);
|
||||||
--color-tertiary-contrast-light: var(--color-tertiary-50);
|
--color-tertiary-contrast-light: var(--color-tertiary-50);
|
||||||
|
|
||||||
--color-success-50: oklch(95.77% 0.05 152.69deg);
|
--color-success-50: oklch(95.77% 0.05 152.69deg);
|
||||||
--color-success-100: oklch(91.59% 0.06 152.00deg);
|
--color-success-100: oklch(91.59% 0.06 152deg);
|
||||||
--color-success-200: oklch(87.45% 0.08 152.08deg);
|
--color-success-200: oklch(87.45% 0.08 152.08deg);
|
||||||
--color-success-300: oklch(83.57% 0.09 150.85deg);
|
--color-success-300: oklch(83.57% 0.09 150.85deg);
|
||||||
--color-success-400: oklch(79.47% 0.11 150.71deg);
|
--color-success-400: oklch(79.47% 0.11 150.71deg);
|
||||||
@@ -114,51 +114,51 @@ html[data-theme='AE_Firefly_Indigo'] {
|
|||||||
--color-success-600: oklch(67.65% 0.11 149.94deg);
|
--color-success-600: oklch(67.65% 0.11 149.94deg);
|
||||||
--color-success-700: oklch(59.71% 0.09 150.42deg);
|
--color-success-700: oklch(59.71% 0.09 150.42deg);
|
||||||
--color-success-800: oklch(51.74% 0.08 150.24deg);
|
--color-success-800: oklch(51.74% 0.08 150.24deg);
|
||||||
--color-success-900: oklch(43.20% 0.06 151.12deg);
|
--color-success-900: oklch(43.2% 0.06 151.12deg);
|
||||||
--color-success-950: oklch(34.20% 0.04 151.44deg);
|
--color-success-950: oklch(34.2% 0.04 151.44deg);
|
||||||
--color-success-contrast-dark: var(--color-success-950);
|
--color-success-contrast-dark: var(--color-success-950);
|
||||||
--color-success-contrast-light: var(--color-success-50);
|
--color-success-contrast-light: var(--color-success-50);
|
||||||
|
|
||||||
--color-warning-50: oklch(97.5% 0.065 78deg);
|
--color-warning-50: oklch(97.5% 0.065 78deg);
|
||||||
--color-warning-100: oklch(93.5% 0.090 75deg);
|
--color-warning-100: oklch(93.5% 0.09 75deg);
|
||||||
--color-warning-200: oklch(89.5% 0.120 73deg);
|
--color-warning-200: oklch(89.5% 0.12 73deg);
|
||||||
--color-warning-300: oklch(85.5% 0.145 70deg);
|
--color-warning-300: oklch(85.5% 0.145 70deg);
|
||||||
--color-warning-400: oklch(81.5% 0.160 67deg);
|
--color-warning-400: oklch(81.5% 0.16 67deg);
|
||||||
--color-warning-500: oklch(77.0% 0.165 65deg);
|
--color-warning-500: oklch(77% 0.165 65deg);
|
||||||
--color-warning-600: oklch(69.5% 0.155 64deg);
|
--color-warning-600: oklch(69.5% 0.155 64deg);
|
||||||
--color-warning-700: oklch(61.5% 0.140 63deg);
|
--color-warning-700: oklch(61.5% 0.14 63deg);
|
||||||
--color-warning-800: oklch(53.5% 0.125 62deg);
|
--color-warning-800: oklch(53.5% 0.125 62deg);
|
||||||
--color-warning-900: oklch(45.0% 0.105 61deg);
|
--color-warning-900: oklch(45% 0.105 61deg);
|
||||||
--color-warning-950: oklch(37.0% 0.088 60deg);
|
--color-warning-950: oklch(37% 0.088 60deg);
|
||||||
--color-warning-contrast-dark: var(--color-warning-950);
|
--color-warning-contrast-dark: var(--color-warning-950);
|
||||||
--color-warning-contrast-light: var(--color-warning-50);
|
--color-warning-contrast-light: var(--color-warning-50);
|
||||||
|
|
||||||
--color-error-50: oklch(95.0% 0.040 18deg);
|
--color-error-50: oklch(95% 0.04 18deg);
|
||||||
--color-error-100: oklch(88.0% 0.070 20deg);
|
--color-error-100: oklch(88% 0.07 20deg);
|
||||||
--color-error-200: oklch(80.0% 0.105 21deg);
|
--color-error-200: oklch(80% 0.105 21deg);
|
||||||
--color-error-300: oklch(72.0% 0.140 22deg);
|
--color-error-300: oklch(72% 0.14 22deg);
|
||||||
--color-error-400: oklch(64.5% 0.170 23deg);
|
--color-error-400: oklch(64.5% 0.17 23deg);
|
||||||
--color-error-500: oklch(57.5% 0.195 24deg);
|
--color-error-500: oklch(57.5% 0.195 24deg);
|
||||||
--color-error-600: oklch(51.5% 0.182 25deg);
|
--color-error-600: oklch(51.5% 0.182 25deg);
|
||||||
--color-error-700: oklch(45.5% 0.165 26deg);
|
--color-error-700: oklch(45.5% 0.165 26deg);
|
||||||
--color-error-800: oklch(39.5% 0.148 27deg);
|
--color-error-800: oklch(39.5% 0.148 27deg);
|
||||||
--color-error-900: oklch(33.0% 0.128 28deg);
|
--color-error-900: oklch(33% 0.128 28deg);
|
||||||
--color-error-950: oklch(26.5% 0.108 29deg);
|
--color-error-950: oklch(26.5% 0.108 29deg);
|
||||||
--color-error-contrast-dark: var(--color-error-950);
|
--color-error-contrast-dark: var(--color-error-950);
|
||||||
--color-error-contrast-light: var(--color-error-50);
|
--color-error-contrast-light: var(--color-error-50);
|
||||||
|
|
||||||
--color-surface-50: oklch(99.0% 0.003 270deg);
|
--color-surface-50: oklch(99% 0.003 270deg);
|
||||||
--color-surface-100: oklch(96.5% 0.006 268deg);
|
--color-surface-100: oklch(96.5% 0.006 268deg);
|
||||||
--color-surface-200: oklch(92.5% 0.010 266deg);
|
--color-surface-200: oklch(92.5% 0.01 266deg);
|
||||||
--color-surface-300: oklch(87.0% 0.014 265deg);
|
--color-surface-300: oklch(87% 0.014 265deg);
|
||||||
--color-surface-400: oklch(78.5% 0.018 265deg);
|
--color-surface-400: oklch(78.5% 0.018 265deg);
|
||||||
--color-surface-500: oklch(66.5% 0.020 267deg);
|
--color-surface-500: oklch(66.5% 0.02 267deg);
|
||||||
--color-surface-600: oklch(54.5% 0.022 269deg);
|
--color-surface-600: oklch(54.5% 0.022 269deg);
|
||||||
--color-surface-700: oklch(42.5% 0.024 270deg);
|
--color-surface-700: oklch(42.5% 0.024 270deg);
|
||||||
--color-surface-800: oklch(31.0% 0.026 272deg);
|
--color-surface-800: oklch(31% 0.026 272deg);
|
||||||
--color-surface-900: oklch(20.5% 0.030 274deg);
|
--color-surface-900: oklch(20.5% 0.03 274deg);
|
||||||
--color-surface-950: oklch(13.0% 0.034 276deg);
|
--color-surface-950: oklch(13% 0.034 276deg);
|
||||||
--color-surface-contrast-dark: var(--color-surface-950);
|
--color-surface-contrast-dark: var(--color-surface-950);
|
||||||
--color-surface-contrast-light: var(--color-surface-50);
|
--color-surface-contrast-light: var(--color-surface-50);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,20 +182,20 @@ html.dark[data-theme='AE_Firefly_Indigo'] {
|
|||||||
* maintaining sufficient contrast at mid-range shades.
|
* maintaining sufficient contrast at mid-range shades.
|
||||||
* At 500 (L≈50%): sufficient contrast with primary-50 text (≥4:1).
|
* At 500 (L≈50%): sufficient contrast with primary-50 text (≥4:1).
|
||||||
* =================================================================== */
|
* =================================================================== */
|
||||||
--color-primary-50: oklch(95.5% 0.040 270deg);
|
--color-primary-50: oklch(95.5% 0.04 270deg);
|
||||||
--color-primary-100: oklch(89.5% 0.072 270deg);
|
--color-primary-100: oklch(89.5% 0.072 270deg);
|
||||||
--color-primary-200: oklch(82.5% 0.108 269deg);
|
--color-primary-200: oklch(82.5% 0.108 269deg);
|
||||||
--color-primary-300: oklch(74.5% 0.135 268deg);
|
--color-primary-300: oklch(74.5% 0.135 268deg);
|
||||||
--color-primary-400: oklch(65.0% 0.155 267deg);
|
--color-primary-400: oklch(65% 0.155 267deg);
|
||||||
--color-primary-500: oklch(50.5% 0.160 266deg);
|
--color-primary-500: oklch(50.5% 0.16 266deg);
|
||||||
--color-primary-600: oklch(43.5% 0.152 265deg);
|
--color-primary-600: oklch(43.5% 0.152 265deg);
|
||||||
--color-primary-700: oklch(37.0% 0.138 264deg);
|
--color-primary-700: oklch(37% 0.138 264deg);
|
||||||
--color-primary-800: oklch(30.0% 0.120 263deg);
|
--color-primary-800: oklch(30% 0.12 263deg);
|
||||||
--color-primary-900: oklch(23.0% 0.100 262deg);
|
--color-primary-900: oklch(23% 0.1 262deg);
|
||||||
--color-primary-950: oklch(15.5% 0.080 261deg);
|
--color-primary-950: oklch(15.5% 0.08 261deg);
|
||||||
--color-primary-contrast-dark: var(--color-primary-950);
|
--color-primary-contrast-dark: var(--color-primary-950);
|
||||||
--color-primary-contrast-light: var(--color-primary-50);
|
--color-primary-contrast-light: var(--color-primary-50);
|
||||||
--color-primary-contrast-50: var(--color-primary-contrast-dark);
|
--color-primary-contrast-50: var(--color-primary-contrast-dark);
|
||||||
--color-primary-contrast-100: var(--color-primary-contrast-dark);
|
--color-primary-contrast-100: var(--color-primary-contrast-dark);
|
||||||
--color-primary-contrast-200: var(--color-primary-contrast-dark);
|
--color-primary-contrast-200: var(--color-primary-contrast-dark);
|
||||||
--color-primary-contrast-300: var(--color-primary-contrast-dark);
|
--color-primary-contrast-300: var(--color-primary-contrast-dark);
|
||||||
@@ -214,20 +214,20 @@ html.dark[data-theme='AE_Firefly_Indigo'] {
|
|||||||
* remaining clearly distinct from the primary.
|
* remaining clearly distinct from the primary.
|
||||||
* Used for secondary actions, badges, and soft highlights.
|
* Used for secondary actions, badges, and soft highlights.
|
||||||
* =================================================================== */
|
* =================================================================== */
|
||||||
--color-secondary-50: oklch(96.5% 0.032 297deg);
|
--color-secondary-50: oklch(96.5% 0.032 297deg);
|
||||||
--color-secondary-100: oklch(91.5% 0.058 295deg);
|
--color-secondary-100: oklch(91.5% 0.058 295deg);
|
||||||
--color-secondary-200: oklch(85.5% 0.090 293deg);
|
--color-secondary-200: oklch(85.5% 0.09 293deg);
|
||||||
--color-secondary-300: oklch(78.5% 0.115 292deg);
|
--color-secondary-300: oklch(78.5% 0.115 292deg);
|
||||||
--color-secondary-400: oklch(70.0% 0.132 291deg);
|
--color-secondary-400: oklch(70% 0.132 291deg);
|
||||||
--color-secondary-500: oklch(60.0% 0.140 290deg);
|
--color-secondary-500: oklch(60% 0.14 290deg);
|
||||||
--color-secondary-600: oklch(52.5% 0.135 289deg);
|
--color-secondary-600: oklch(52.5% 0.135 289deg);
|
||||||
--color-secondary-700: oklch(45.0% 0.126 288deg);
|
--color-secondary-700: oklch(45% 0.126 288deg);
|
||||||
--color-secondary-800: oklch(37.5% 0.112 286deg);
|
--color-secondary-800: oklch(37.5% 0.112 286deg);
|
||||||
--color-secondary-900: oklch(30.0% 0.094 284deg);
|
--color-secondary-900: oklch(30% 0.094 284deg);
|
||||||
--color-secondary-950: oklch(22.0% 0.076 282deg);
|
--color-secondary-950: oklch(22% 0.076 282deg);
|
||||||
--color-secondary-contrast-dark: var(--color-secondary-950);
|
--color-secondary-contrast-dark: var(--color-secondary-950);
|
||||||
--color-secondary-contrast-light: var(--color-secondary-50);
|
--color-secondary-contrast-light: var(--color-secondary-50);
|
||||||
--color-secondary-contrast-50: var(--color-secondary-contrast-dark);
|
--color-secondary-contrast-50: var(--color-secondary-contrast-dark);
|
||||||
--color-secondary-contrast-100: var(--color-secondary-contrast-dark);
|
--color-secondary-contrast-100: var(--color-secondary-contrast-dark);
|
||||||
--color-secondary-contrast-200: var(--color-secondary-contrast-dark);
|
--color-secondary-contrast-200: var(--color-secondary-contrast-dark);
|
||||||
--color-secondary-contrast-300: var(--color-secondary-contrast-dark);
|
--color-secondary-contrast-300: var(--color-secondary-contrast-dark);
|
||||||
@@ -247,20 +247,20 @@ html.dark[data-theme='AE_Firefly_Indigo'] {
|
|||||||
* breaking against a deep indigo sky.
|
* breaking against a deep indigo sky.
|
||||||
* Used for location chips, warm accents, tertiary elements.
|
* Used for location chips, warm accents, tertiary elements.
|
||||||
* =================================================================== */
|
* =================================================================== */
|
||||||
--color-tertiary-50: oklch(96.5% 0.022 348deg);
|
--color-tertiary-50: oklch(96.5% 0.022 348deg);
|
||||||
--color-tertiary-100: oklch(91.0% 0.042 346deg);
|
--color-tertiary-100: oklch(91% 0.042 346deg);
|
||||||
--color-tertiary-200: oklch(84.5% 0.068 344deg);
|
--color-tertiary-200: oklch(84.5% 0.068 344deg);
|
||||||
--color-tertiary-300: oklch(76.5% 0.095 343deg);
|
--color-tertiary-300: oklch(76.5% 0.095 343deg);
|
||||||
--color-tertiary-400: oklch(68.0% 0.118 342deg);
|
--color-tertiary-400: oklch(68% 0.118 342deg);
|
||||||
--color-tertiary-500: oklch(57.5% 0.128 341deg);
|
--color-tertiary-500: oklch(57.5% 0.128 341deg);
|
||||||
--color-tertiary-600: oklch(50.0% 0.122 340deg);
|
--color-tertiary-600: oklch(50% 0.122 340deg);
|
||||||
--color-tertiary-700: oklch(43.0% 0.112 339deg);
|
--color-tertiary-700: oklch(43% 0.112 339deg);
|
||||||
--color-tertiary-800: oklch(35.5% 0.098 338deg);
|
--color-tertiary-800: oklch(35.5% 0.098 338deg);
|
||||||
--color-tertiary-900: oklch(28.0% 0.080 337deg);
|
--color-tertiary-900: oklch(28% 0.08 337deg);
|
||||||
--color-tertiary-950: oklch(20.5% 0.062 336deg);
|
--color-tertiary-950: oklch(20.5% 0.062 336deg);
|
||||||
--color-tertiary-contrast-dark: var(--color-tertiary-950);
|
--color-tertiary-contrast-dark: var(--color-tertiary-950);
|
||||||
--color-tertiary-contrast-light: var(--color-tertiary-50);
|
--color-tertiary-contrast-light: var(--color-tertiary-50);
|
||||||
--color-tertiary-contrast-50: var(--color-tertiary-contrast-dark);
|
--color-tertiary-contrast-50: var(--color-tertiary-contrast-dark);
|
||||||
--color-tertiary-contrast-100: var(--color-tertiary-contrast-dark);
|
--color-tertiary-contrast-100: var(--color-tertiary-contrast-dark);
|
||||||
--color-tertiary-contrast-200: var(--color-tertiary-contrast-dark);
|
--color-tertiary-contrast-200: var(--color-tertiary-contrast-dark);
|
||||||
--color-tertiary-contrast-300: var(--color-tertiary-contrast-dark);
|
--color-tertiary-contrast-300: var(--color-tertiary-contrast-dark);
|
||||||
@@ -277,8 +277,8 @@ html.dark[data-theme='AE_Firefly_Indigo'] {
|
|||||||
* Hue: ~152°. Consistent with AE_Firefly for recognizable semantic
|
* Hue: ~152°. Consistent with AE_Firefly for recognizable semantic
|
||||||
* color meaning across OSIT themes.
|
* color meaning across OSIT themes.
|
||||||
* =================================================================== */
|
* =================================================================== */
|
||||||
--color-success-50: oklch(95.77% 0.05 152.69deg);
|
--color-success-50: oklch(95.77% 0.05 152.69deg);
|
||||||
--color-success-100: oklch(91.59% 0.06 152.00deg);
|
--color-success-100: oklch(91.59% 0.06 152deg);
|
||||||
--color-success-200: oklch(87.45% 0.08 152.08deg);
|
--color-success-200: oklch(87.45% 0.08 152.08deg);
|
||||||
--color-success-300: oklch(83.57% 0.09 150.85deg);
|
--color-success-300: oklch(83.57% 0.09 150.85deg);
|
||||||
--color-success-400: oklch(79.47% 0.11 150.71deg);
|
--color-success-400: oklch(79.47% 0.11 150.71deg);
|
||||||
@@ -286,11 +286,11 @@ html.dark[data-theme='AE_Firefly_Indigo'] {
|
|||||||
--color-success-600: oklch(67.65% 0.11 149.94deg);
|
--color-success-600: oklch(67.65% 0.11 149.94deg);
|
||||||
--color-success-700: oklch(59.71% 0.09 150.42deg);
|
--color-success-700: oklch(59.71% 0.09 150.42deg);
|
||||||
--color-success-800: oklch(51.74% 0.08 150.24deg);
|
--color-success-800: oklch(51.74% 0.08 150.24deg);
|
||||||
--color-success-900: oklch(43.20% 0.06 151.12deg);
|
--color-success-900: oklch(43.2% 0.06 151.12deg);
|
||||||
--color-success-950: oklch(34.20% 0.04 151.44deg);
|
--color-success-950: oklch(34.2% 0.04 151.44deg);
|
||||||
--color-success-contrast-dark: var(--color-success-950);
|
--color-success-contrast-dark: var(--color-success-950);
|
||||||
--color-success-contrast-light: var(--color-success-50);
|
--color-success-contrast-light: var(--color-success-50);
|
||||||
--color-success-contrast-50: var(--color-success-contrast-dark);
|
--color-success-contrast-50: var(--color-success-contrast-dark);
|
||||||
--color-success-contrast-100: var(--color-success-contrast-dark);
|
--color-success-contrast-100: var(--color-success-contrast-dark);
|
||||||
--color-success-contrast-200: var(--color-success-contrast-dark);
|
--color-success-contrast-200: var(--color-success-contrast-dark);
|
||||||
--color-success-contrast-300: var(--color-success-contrast-dark);
|
--color-success-contrast-300: var(--color-success-contrast-dark);
|
||||||
@@ -306,20 +306,20 @@ html.dark[data-theme='AE_Firefly_Indigo'] {
|
|||||||
* WARNING — Amber Orange
|
* WARNING — Amber Orange
|
||||||
* Consistent with AE_Firefly for recognizable semantic meaning.
|
* Consistent with AE_Firefly for recognizable semantic meaning.
|
||||||
* =================================================================== */
|
* =================================================================== */
|
||||||
--color-warning-50: oklch(97.5% 0.065 78deg);
|
--color-warning-50: oklch(97.5% 0.065 78deg);
|
||||||
--color-warning-100: oklch(93.5% 0.090 75deg);
|
--color-warning-100: oklch(93.5% 0.09 75deg);
|
||||||
--color-warning-200: oklch(89.5% 0.120 73deg);
|
--color-warning-200: oklch(89.5% 0.12 73deg);
|
||||||
--color-warning-300: oklch(85.5% 0.145 70deg);
|
--color-warning-300: oklch(85.5% 0.145 70deg);
|
||||||
--color-warning-400: oklch(81.5% 0.160 67deg);
|
--color-warning-400: oklch(81.5% 0.16 67deg);
|
||||||
--color-warning-500: oklch(77.0% 0.165 65deg);
|
--color-warning-500: oklch(77% 0.165 65deg);
|
||||||
--color-warning-600: oklch(69.5% 0.155 64deg);
|
--color-warning-600: oklch(69.5% 0.155 64deg);
|
||||||
--color-warning-700: oklch(61.5% 0.140 63deg);
|
--color-warning-700: oklch(61.5% 0.14 63deg);
|
||||||
--color-warning-800: oklch(53.5% 0.125 62deg);
|
--color-warning-800: oklch(53.5% 0.125 62deg);
|
||||||
--color-warning-900: oklch(45.0% 0.105 61deg);
|
--color-warning-900: oklch(45% 0.105 61deg);
|
||||||
--color-warning-950: oklch(37.0% 0.088 60deg);
|
--color-warning-950: oklch(37% 0.088 60deg);
|
||||||
--color-warning-contrast-dark: var(--color-warning-950);
|
--color-warning-contrast-dark: var(--color-warning-950);
|
||||||
--color-warning-contrast-light: var(--color-warning-50);
|
--color-warning-contrast-light: var(--color-warning-50);
|
||||||
--color-warning-contrast-50: var(--color-warning-contrast-dark);
|
--color-warning-contrast-50: var(--color-warning-contrast-dark);
|
||||||
--color-warning-contrast-100: var(--color-warning-contrast-dark);
|
--color-warning-contrast-100: var(--color-warning-contrast-dark);
|
||||||
--color-warning-contrast-200: var(--color-warning-contrast-dark);
|
--color-warning-contrast-200: var(--color-warning-contrast-dark);
|
||||||
--color-warning-contrast-300: var(--color-warning-contrast-dark);
|
--color-warning-contrast-300: var(--color-warning-contrast-dark);
|
||||||
@@ -335,20 +335,20 @@ html.dark[data-theme='AE_Firefly_Indigo'] {
|
|||||||
* ERROR — Soft Coral/Rose
|
* ERROR — Soft Coral/Rose
|
||||||
* Consistent with AE_Firefly for recognizable semantic meaning.
|
* Consistent with AE_Firefly for recognizable semantic meaning.
|
||||||
* =================================================================== */
|
* =================================================================== */
|
||||||
--color-error-50: oklch(95.0% 0.040 18deg);
|
--color-error-50: oklch(95% 0.04 18deg);
|
||||||
--color-error-100: oklch(88.0% 0.070 20deg);
|
--color-error-100: oklch(88% 0.07 20deg);
|
||||||
--color-error-200: oklch(80.0% 0.105 21deg);
|
--color-error-200: oklch(80% 0.105 21deg);
|
||||||
--color-error-300: oklch(72.0% 0.140 22deg);
|
--color-error-300: oklch(72% 0.14 22deg);
|
||||||
--color-error-400: oklch(64.5% 0.170 23deg);
|
--color-error-400: oklch(64.5% 0.17 23deg);
|
||||||
--color-error-500: oklch(57.5% 0.195 24deg);
|
--color-error-500: oklch(57.5% 0.195 24deg);
|
||||||
--color-error-600: oklch(51.5% 0.182 25deg);
|
--color-error-600: oklch(51.5% 0.182 25deg);
|
||||||
--color-error-700: oklch(45.5% 0.165 26deg);
|
--color-error-700: oklch(45.5% 0.165 26deg);
|
||||||
--color-error-800: oklch(39.5% 0.148 27deg);
|
--color-error-800: oklch(39.5% 0.148 27deg);
|
||||||
--color-error-900: oklch(33.0% 0.128 28deg);
|
--color-error-900: oklch(33% 0.128 28deg);
|
||||||
--color-error-950: oklch(26.5% 0.108 29deg);
|
--color-error-950: oklch(26.5% 0.108 29deg);
|
||||||
--color-error-contrast-dark: var(--color-error-950);
|
--color-error-contrast-dark: var(--color-error-950);
|
||||||
--color-error-contrast-light: var(--color-error-50);
|
--color-error-contrast-light: var(--color-error-50);
|
||||||
--color-error-contrast-50: var(--color-error-contrast-dark);
|
--color-error-contrast-50: var(--color-error-contrast-dark);
|
||||||
--color-error-contrast-100: var(--color-error-contrast-dark);
|
--color-error-contrast-100: var(--color-error-contrast-dark);
|
||||||
--color-error-contrast-200: var(--color-error-contrast-dark);
|
--color-error-contrast-200: var(--color-error-contrast-dark);
|
||||||
--color-error-contrast-300: var(--color-error-contrast-dark);
|
--color-error-contrast-300: var(--color-error-contrast-dark);
|
||||||
@@ -370,20 +370,20 @@ html.dark[data-theme='AE_Firefly_Indigo'] {
|
|||||||
* 50 → body-bg light: near-white with ImperceptibleISTIC purple cast
|
* 50 → body-bg light: near-white with ImperceptibleISTIC purple cast
|
||||||
* 950 → body-bg dark: deep midnight with indigo depth
|
* 950 → body-bg dark: deep midnight with indigo depth
|
||||||
* =================================================================== */
|
* =================================================================== */
|
||||||
--color-surface-50: oklch(99.0% 0.003 270deg);
|
--color-surface-50: oklch(99% 0.003 270deg);
|
||||||
--color-surface-100: oklch(96.5% 0.006 268deg);
|
--color-surface-100: oklch(96.5% 0.006 268deg);
|
||||||
--color-surface-200: oklch(92.5% 0.010 266deg);
|
--color-surface-200: oklch(92.5% 0.01 266deg);
|
||||||
--color-surface-300: oklch(87.0% 0.014 265deg);
|
--color-surface-300: oklch(87% 0.014 265deg);
|
||||||
--color-surface-400: oklch(78.5% 0.018 265deg);
|
--color-surface-400: oklch(78.5% 0.018 265deg);
|
||||||
--color-surface-500: oklch(66.5% 0.020 267deg);
|
--color-surface-500: oklch(66.5% 0.02 267deg);
|
||||||
--color-surface-600: oklch(54.5% 0.022 269deg);
|
--color-surface-600: oklch(54.5% 0.022 269deg);
|
||||||
--color-surface-700: oklch(42.5% 0.024 270deg);
|
--color-surface-700: oklch(42.5% 0.024 270deg);
|
||||||
--color-surface-800: oklch(31.0% 0.026 272deg);
|
--color-surface-800: oklch(31% 0.026 272deg);
|
||||||
--color-surface-900: oklch(20.5% 0.030 274deg);
|
--color-surface-900: oklch(20.5% 0.03 274deg);
|
||||||
--color-surface-950: oklch(13.0% 0.034 276deg);
|
--color-surface-950: oklch(13% 0.034 276deg);
|
||||||
--color-surface-contrast-dark: var(--color-surface-950);
|
--color-surface-contrast-dark: var(--color-surface-950);
|
||||||
--color-surface-contrast-light: var(--color-surface-50);
|
--color-surface-contrast-light: var(--color-surface-50);
|
||||||
--color-surface-contrast-50: var(--color-surface-contrast-dark);
|
--color-surface-contrast-50: var(--color-surface-contrast-dark);
|
||||||
--color-surface-contrast-100: var(--color-surface-contrast-dark);
|
--color-surface-contrast-100: var(--color-surface-contrast-dark);
|
||||||
--color-surface-contrast-200: var(--color-surface-contrast-dark);
|
--color-surface-contrast-200: var(--color-surface-contrast-dark);
|
||||||
--color-surface-contrast-300: var(--color-surface-contrast-dark);
|
--color-surface-contrast-300: var(--color-surface-contrast-dark);
|
||||||
|
|||||||
@@ -63,50 +63,50 @@ html[data-theme='AE_Firefly_Rainbow'] {
|
|||||||
|
|
||||||
/* --- Color ramps (light mode) copied from dark block so both modes have full ramps --- */
|
/* --- Color ramps (light mode) copied from dark block so both modes have full ramps --- */
|
||||||
html[data-theme='AE_Firefly_Rainbow'] {
|
html[data-theme='AE_Firefly_Rainbow'] {
|
||||||
--color-primary-50: oklch(97.0% 0.020 15deg);
|
--color-primary-50: oklch(97% 0.02 15deg);
|
||||||
--color-primary-100: oklch(92.0% 0.048 14deg);
|
--color-primary-100: oklch(92% 0.048 14deg);
|
||||||
--color-primary-200: oklch(86.0% 0.085 13deg);
|
--color-primary-200: oklch(86% 0.085 13deg);
|
||||||
--color-primary-300: oklch(79.0% 0.125 13deg);
|
--color-primary-300: oklch(79% 0.125 13deg);
|
||||||
--color-primary-400: oklch(71.0% 0.160 13deg);
|
--color-primary-400: oklch(71% 0.16 13deg);
|
||||||
--color-primary-500: oklch(60.0% 0.190 14deg);
|
--color-primary-500: oklch(60% 0.19 14deg);
|
||||||
--color-primary-600: oklch(52.5% 0.178 15deg);
|
--color-primary-600: oklch(52.5% 0.178 15deg);
|
||||||
--color-primary-700: oklch(45.0% 0.162 16deg);
|
--color-primary-700: oklch(45% 0.162 16deg);
|
||||||
--color-primary-800: oklch(37.5% 0.142 17deg);
|
--color-primary-800: oklch(37.5% 0.142 17deg);
|
||||||
--color-primary-900: oklch(30.0% 0.118 18deg);
|
--color-primary-900: oklch(30% 0.118 18deg);
|
||||||
--color-primary-950: oklch(22.5% 0.092 19deg);
|
--color-primary-950: oklch(22.5% 0.092 19deg);
|
||||||
--color-primary-contrast-dark: var(--color-primary-950);
|
--color-primary-contrast-dark: var(--color-primary-950);
|
||||||
--color-primary-contrast-light: var(--color-primary-50);
|
--color-primary-contrast-light: var(--color-primary-50);
|
||||||
|
|
||||||
--color-secondary-50: oklch(97.0% 0.040 152deg);
|
--color-secondary-50: oklch(97% 0.04 152deg);
|
||||||
--color-secondary-100: oklch(92.5% 0.072 150deg);
|
--color-secondary-100: oklch(92.5% 0.072 150deg);
|
||||||
--color-secondary-200: oklch(87.0% 0.105 149deg);
|
--color-secondary-200: oklch(87% 0.105 149deg);
|
||||||
--color-secondary-300: oklch(81.0% 0.132 148deg);
|
--color-secondary-300: oklch(81% 0.132 148deg);
|
||||||
--color-secondary-400: oklch(74.5% 0.152 148deg);
|
--color-secondary-400: oklch(74.5% 0.152 148deg);
|
||||||
--color-secondary-500: oklch(62.0% 0.160 148deg);
|
--color-secondary-500: oklch(62% 0.16 148deg);
|
||||||
--color-secondary-600: oklch(53.5% 0.148 148deg);
|
--color-secondary-600: oklch(53.5% 0.148 148deg);
|
||||||
--color-secondary-700: oklch(45.5% 0.132 147deg);
|
--color-secondary-700: oklch(45.5% 0.132 147deg);
|
||||||
--color-secondary-800: oklch(37.5% 0.112 146deg);
|
--color-secondary-800: oklch(37.5% 0.112 146deg);
|
||||||
--color-secondary-900: oklch(29.5% 0.090 145deg);
|
--color-secondary-900: oklch(29.5% 0.09 145deg);
|
||||||
--color-secondary-950: oklch(21.5% 0.068 144deg);
|
--color-secondary-950: oklch(21.5% 0.068 144deg);
|
||||||
--color-secondary-contrast-dark: var(--color-secondary-950);
|
--color-secondary-contrast-dark: var(--color-secondary-950);
|
||||||
--color-secondary-contrast-light: var(--color-secondary-50);
|
--color-secondary-contrast-light: var(--color-secondary-50);
|
||||||
|
|
||||||
--color-tertiary-50: oklch(96.5% 0.030 299deg);
|
--color-tertiary-50: oklch(96.5% 0.03 299deg);
|
||||||
--color-tertiary-100: oklch(91.0% 0.058 297deg);
|
--color-tertiary-100: oklch(91% 0.058 297deg);
|
||||||
--color-tertiary-200: oklch(84.5% 0.092 296deg);
|
--color-tertiary-200: oklch(84.5% 0.092 296deg);
|
||||||
--color-tertiary-300: oklch(77.0% 0.122 295deg);
|
--color-tertiary-300: oklch(77% 0.122 295deg);
|
||||||
--color-tertiary-400: oklch(68.5% 0.148 295deg);
|
--color-tertiary-400: oklch(68.5% 0.148 295deg);
|
||||||
--color-tertiary-500: oklch(57.0% 0.158 295deg);
|
--color-tertiary-500: oklch(57% 0.158 295deg);
|
||||||
--color-tertiary-600: oklch(49.5% 0.150 294deg);
|
--color-tertiary-600: oklch(49.5% 0.15 294deg);
|
||||||
--color-tertiary-700: oklch(42.5% 0.138 293deg);
|
--color-tertiary-700: oklch(42.5% 0.138 293deg);
|
||||||
--color-tertiary-800: oklch(35.5% 0.122 292deg);
|
--color-tertiary-800: oklch(35.5% 0.122 292deg);
|
||||||
--color-tertiary-900: oklch(28.5% 0.102 291deg);
|
--color-tertiary-900: oklch(28.5% 0.102 291deg);
|
||||||
--color-tertiary-950: oklch(21.0% 0.080 290deg);
|
--color-tertiary-950: oklch(21% 0.08 290deg);
|
||||||
--color-tertiary-contrast-dark: var(--color-tertiary-950);
|
--color-tertiary-contrast-dark: var(--color-tertiary-950);
|
||||||
--color-tertiary-contrast-light: var(--color-tertiary-50);
|
--color-tertiary-contrast-light: var(--color-tertiary-50);
|
||||||
|
|
||||||
--color-success-50: oklch(95.77% 0.05 152.69deg);
|
--color-success-50: oklch(95.77% 0.05 152.69deg);
|
||||||
--color-success-100: oklch(91.59% 0.06 152.00deg);
|
--color-success-100: oklch(91.59% 0.06 152deg);
|
||||||
--color-success-200: oklch(87.45% 0.08 152.08deg);
|
--color-success-200: oklch(87.45% 0.08 152.08deg);
|
||||||
--color-success-300: oklch(83.57% 0.09 150.85deg);
|
--color-success-300: oklch(83.57% 0.09 150.85deg);
|
||||||
--color-success-400: oklch(79.47% 0.11 150.71deg);
|
--color-success-400: oklch(79.47% 0.11 150.71deg);
|
||||||
@@ -114,51 +114,51 @@ html[data-theme='AE_Firefly_Rainbow'] {
|
|||||||
--color-success-600: oklch(67.65% 0.11 149.94deg);
|
--color-success-600: oklch(67.65% 0.11 149.94deg);
|
||||||
--color-success-700: oklch(59.71% 0.09 150.42deg);
|
--color-success-700: oklch(59.71% 0.09 150.42deg);
|
||||||
--color-success-800: oklch(51.74% 0.08 150.24deg);
|
--color-success-800: oklch(51.74% 0.08 150.24deg);
|
||||||
--color-success-900: oklch(43.20% 0.06 151.12deg);
|
--color-success-900: oklch(43.2% 0.06 151.12deg);
|
||||||
--color-success-950: oklch(34.20% 0.04 151.44deg);
|
--color-success-950: oklch(34.2% 0.04 151.44deg);
|
||||||
--color-success-contrast-dark: var(--color-success-950);
|
--color-success-contrast-dark: var(--color-success-950);
|
||||||
--color-success-contrast-light: var(--color-success-50);
|
--color-success-contrast-light: var(--color-success-50);
|
||||||
|
|
||||||
--color-warning-50: oklch(97.5% 0.065 78deg);
|
--color-warning-50: oklch(97.5% 0.065 78deg);
|
||||||
--color-warning-100: oklch(93.5% 0.090 75deg);
|
--color-warning-100: oklch(93.5% 0.09 75deg);
|
||||||
--color-warning-200: oklch(89.5% 0.120 73deg);
|
--color-warning-200: oklch(89.5% 0.12 73deg);
|
||||||
--color-warning-300: oklch(85.5% 0.145 70deg);
|
--color-warning-300: oklch(85.5% 0.145 70deg);
|
||||||
--color-warning-400: oklch(81.5% 0.160 67deg);
|
--color-warning-400: oklch(81.5% 0.16 67deg);
|
||||||
--color-warning-500: oklch(77.0% 0.165 65deg);
|
--color-warning-500: oklch(77% 0.165 65deg);
|
||||||
--color-warning-600: oklch(69.5% 0.155 64deg);
|
--color-warning-600: oklch(69.5% 0.155 64deg);
|
||||||
--color-warning-700: oklch(61.5% 0.140 63deg);
|
--color-warning-700: oklch(61.5% 0.14 63deg);
|
||||||
--color-warning-800: oklch(53.5% 0.125 62deg);
|
--color-warning-800: oklch(53.5% 0.125 62deg);
|
||||||
--color-warning-900: oklch(45.0% 0.105 61deg);
|
--color-warning-900: oklch(45% 0.105 61deg);
|
||||||
--color-warning-950: oklch(37.0% 0.088 60deg);
|
--color-warning-950: oklch(37% 0.088 60deg);
|
||||||
--color-warning-contrast-dark: var(--color-warning-950);
|
--color-warning-contrast-dark: var(--color-warning-950);
|
||||||
--color-warning-contrast-light: var(--color-warning-50);
|
--color-warning-contrast-light: var(--color-warning-50);
|
||||||
|
|
||||||
--color-error-50: oklch(95.0% 0.040 18deg);
|
--color-error-50: oklch(95% 0.04 18deg);
|
||||||
--color-error-100: oklch(88.0% 0.070 20deg);
|
--color-error-100: oklch(88% 0.07 20deg);
|
||||||
--color-error-200: oklch(80.0% 0.105 21deg);
|
--color-error-200: oklch(80% 0.105 21deg);
|
||||||
--color-error-300: oklch(72.0% 0.140 22deg);
|
--color-error-300: oklch(72% 0.14 22deg);
|
||||||
--color-error-400: oklch(64.5% 0.170 23deg);
|
--color-error-400: oklch(64.5% 0.17 23deg);
|
||||||
--color-error-500: oklch(57.5% 0.195 24deg);
|
--color-error-500: oklch(57.5% 0.195 24deg);
|
||||||
--color-error-600: oklch(51.5% 0.182 25deg);
|
--color-error-600: oklch(51.5% 0.182 25deg);
|
||||||
--color-error-700: oklch(45.5% 0.165 26deg);
|
--color-error-700: oklch(45.5% 0.165 26deg);
|
||||||
--color-error-800: oklch(39.5% 0.148 27deg);
|
--color-error-800: oklch(39.5% 0.148 27deg);
|
||||||
--color-error-900: oklch(33.0% 0.128 28deg);
|
--color-error-900: oklch(33% 0.128 28deg);
|
||||||
--color-error-950: oklch(26.5% 0.108 29deg);
|
--color-error-950: oklch(26.5% 0.108 29deg);
|
||||||
--color-error-contrast-dark: var(--color-error-950);
|
--color-error-contrast-dark: var(--color-error-950);
|
||||||
--color-error-contrast-light: var(--color-error-50);
|
--color-error-contrast-light: var(--color-error-50);
|
||||||
|
|
||||||
--color-surface-50: oklch(99.2% 0.004 75deg);
|
--color-surface-50: oklch(99.2% 0.004 75deg);
|
||||||
--color-surface-100: oklch(97.0% 0.007 72deg);
|
--color-surface-100: oklch(97% 0.007 72deg);
|
||||||
--color-surface-200: oklch(93.5% 0.010 70deg);
|
--color-surface-200: oklch(93.5% 0.01 70deg);
|
||||||
--color-surface-300: oklch(88.5% 0.013 68deg);
|
--color-surface-300: oklch(88.5% 0.013 68deg);
|
||||||
--color-surface-400: oklch(81.5% 0.016 66deg);
|
--color-surface-400: oklch(81.5% 0.016 66deg);
|
||||||
--color-surface-500: oklch(70.5% 0.018 64deg);
|
--color-surface-500: oklch(70.5% 0.018 64deg);
|
||||||
--color-surface-600: oklch(59.0% 0.018 62deg);
|
--color-surface-600: oklch(59% 0.018 62deg);
|
||||||
--color-surface-700: oklch(47.5% 0.018 58deg);
|
--color-surface-700: oklch(47.5% 0.018 58deg);
|
||||||
--color-surface-800: oklch(35.5% 0.020 55deg);
|
--color-surface-800: oklch(35.5% 0.02 55deg);
|
||||||
--color-surface-900: oklch(24.5% 0.020 52deg);
|
--color-surface-900: oklch(24.5% 0.02 52deg);
|
||||||
--color-surface-950: oklch(15.5% 0.022 48deg);
|
--color-surface-950: oklch(15.5% 0.022 48deg);
|
||||||
--color-surface-contrast-dark: var(--color-surface-950);
|
--color-surface-contrast-dark: var(--color-surface-950);
|
||||||
--color-surface-contrast-light: var(--color-surface-50);
|
--color-surface-contrast-light: var(--color-surface-50);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,20 +180,20 @@ html.dark[data-theme='AE_Firefly_Rainbow'] {
|
|||||||
* Kept within sRGB gamut across the full ramp.
|
* Kept within sRGB gamut across the full ramp.
|
||||||
* At 500 (L≈60%): sufficient contrast with primary-50 text (≥4:1).
|
* At 500 (L≈60%): sufficient contrast with primary-50 text (≥4:1).
|
||||||
* =================================================================== */
|
* =================================================================== */
|
||||||
--color-primary-50: oklch(97.0% 0.020 15deg);
|
--color-primary-50: oklch(97% 0.02 15deg);
|
||||||
--color-primary-100: oklch(92.0% 0.048 14deg);
|
--color-primary-100: oklch(92% 0.048 14deg);
|
||||||
--color-primary-200: oklch(86.0% 0.085 13deg);
|
--color-primary-200: oklch(86% 0.085 13deg);
|
||||||
--color-primary-300: oklch(79.0% 0.125 13deg);
|
--color-primary-300: oklch(79% 0.125 13deg);
|
||||||
--color-primary-400: oklch(71.0% 0.160 13deg);
|
--color-primary-400: oklch(71% 0.16 13deg);
|
||||||
--color-primary-500: oklch(60.0% 0.190 14deg);
|
--color-primary-500: oklch(60% 0.19 14deg);
|
||||||
--color-primary-600: oklch(52.5% 0.178 15deg);
|
--color-primary-600: oklch(52.5% 0.178 15deg);
|
||||||
--color-primary-700: oklch(45.0% 0.162 16deg);
|
--color-primary-700: oklch(45% 0.162 16deg);
|
||||||
--color-primary-800: oklch(37.5% 0.142 17deg);
|
--color-primary-800: oklch(37.5% 0.142 17deg);
|
||||||
--color-primary-900: oklch(30.0% 0.118 18deg);
|
--color-primary-900: oklch(30% 0.118 18deg);
|
||||||
--color-primary-950: oklch(22.5% 0.092 19deg);
|
--color-primary-950: oklch(22.5% 0.092 19deg);
|
||||||
--color-primary-contrast-dark: var(--color-primary-950);
|
--color-primary-contrast-dark: var(--color-primary-950);
|
||||||
--color-primary-contrast-light: var(--color-primary-50);
|
--color-primary-contrast-light: var(--color-primary-50);
|
||||||
--color-primary-contrast-50: var(--color-primary-contrast-dark);
|
--color-primary-contrast-50: var(--color-primary-contrast-dark);
|
||||||
--color-primary-contrast-100: var(--color-primary-contrast-dark);
|
--color-primary-contrast-100: var(--color-primary-contrast-dark);
|
||||||
--color-primary-contrast-200: var(--color-primary-contrast-dark);
|
--color-primary-contrast-200: var(--color-primary-contrast-dark);
|
||||||
--color-primary-contrast-300: var(--color-primary-contrast-dark);
|
--color-primary-contrast-300: var(--color-primary-contrast-dark);
|
||||||
@@ -212,20 +212,20 @@ html.dark[data-theme='AE_Firefly_Rainbow'] {
|
|||||||
* it bridges the warm red primary and the cool violet tertiary.
|
* it bridges the warm red primary and the cool violet tertiary.
|
||||||
* Used for secondary actions, success-adjacent highlights, badges.
|
* Used for secondary actions, success-adjacent highlights, badges.
|
||||||
* =================================================================== */
|
* =================================================================== */
|
||||||
--color-secondary-50: oklch(97.0% 0.040 152deg);
|
--color-secondary-50: oklch(97% 0.04 152deg);
|
||||||
--color-secondary-100: oklch(92.5% 0.072 150deg);
|
--color-secondary-100: oklch(92.5% 0.072 150deg);
|
||||||
--color-secondary-200: oklch(87.0% 0.105 149deg);
|
--color-secondary-200: oklch(87% 0.105 149deg);
|
||||||
--color-secondary-300: oklch(81.0% 0.132 148deg);
|
--color-secondary-300: oklch(81% 0.132 148deg);
|
||||||
--color-secondary-400: oklch(74.5% 0.152 148deg);
|
--color-secondary-400: oklch(74.5% 0.152 148deg);
|
||||||
--color-secondary-500: oklch(62.0% 0.160 148deg);
|
--color-secondary-500: oklch(62% 0.16 148deg);
|
||||||
--color-secondary-600: oklch(53.5% 0.148 148deg);
|
--color-secondary-600: oklch(53.5% 0.148 148deg);
|
||||||
--color-secondary-700: oklch(45.5% 0.132 147deg);
|
--color-secondary-700: oklch(45.5% 0.132 147deg);
|
||||||
--color-secondary-800: oklch(37.5% 0.112 146deg);
|
--color-secondary-800: oklch(37.5% 0.112 146deg);
|
||||||
--color-secondary-900: oklch(29.5% 0.090 145deg);
|
--color-secondary-900: oklch(29.5% 0.09 145deg);
|
||||||
--color-secondary-950: oklch(21.5% 0.068 144deg);
|
--color-secondary-950: oklch(21.5% 0.068 144deg);
|
||||||
--color-secondary-contrast-dark: var(--color-secondary-950);
|
--color-secondary-contrast-dark: var(--color-secondary-950);
|
||||||
--color-secondary-contrast-light: var(--color-secondary-50);
|
--color-secondary-contrast-light: var(--color-secondary-50);
|
||||||
--color-secondary-contrast-50: var(--color-secondary-contrast-dark);
|
--color-secondary-contrast-50: var(--color-secondary-contrast-dark);
|
||||||
--color-secondary-contrast-100: var(--color-secondary-contrast-dark);
|
--color-secondary-contrast-100: var(--color-secondary-contrast-dark);
|
||||||
--color-secondary-contrast-200: var(--color-secondary-contrast-dark);
|
--color-secondary-contrast-200: var(--color-secondary-contrast-dark);
|
||||||
--color-secondary-contrast-300: var(--color-secondary-contrast-dark);
|
--color-secondary-contrast-300: var(--color-secondary-contrast-dark);
|
||||||
@@ -244,20 +244,20 @@ html.dark[data-theme='AE_Firefly_Rainbow'] {
|
|||||||
* brand color slots. Creates striking contrast with the warm primary.
|
* brand color slots. Creates striking contrast with the warm primary.
|
||||||
* Used for location chips, deep accents, tertiary elements.
|
* Used for location chips, deep accents, tertiary elements.
|
||||||
* =================================================================== */
|
* =================================================================== */
|
||||||
--color-tertiary-50: oklch(96.5% 0.030 299deg);
|
--color-tertiary-50: oklch(96.5% 0.03 299deg);
|
||||||
--color-tertiary-100: oklch(91.0% 0.058 297deg);
|
--color-tertiary-100: oklch(91% 0.058 297deg);
|
||||||
--color-tertiary-200: oklch(84.5% 0.092 296deg);
|
--color-tertiary-200: oklch(84.5% 0.092 296deg);
|
||||||
--color-tertiary-300: oklch(77.0% 0.122 295deg);
|
--color-tertiary-300: oklch(77% 0.122 295deg);
|
||||||
--color-tertiary-400: oklch(68.5% 0.148 295deg);
|
--color-tertiary-400: oklch(68.5% 0.148 295deg);
|
||||||
--color-tertiary-500: oklch(57.0% 0.158 295deg);
|
--color-tertiary-500: oklch(57% 0.158 295deg);
|
||||||
--color-tertiary-600: oklch(49.5% 0.150 294deg);
|
--color-tertiary-600: oklch(49.5% 0.15 294deg);
|
||||||
--color-tertiary-700: oklch(42.5% 0.138 293deg);
|
--color-tertiary-700: oklch(42.5% 0.138 293deg);
|
||||||
--color-tertiary-800: oklch(35.5% 0.122 292deg);
|
--color-tertiary-800: oklch(35.5% 0.122 292deg);
|
||||||
--color-tertiary-900: oklch(28.5% 0.102 291deg);
|
--color-tertiary-900: oklch(28.5% 0.102 291deg);
|
||||||
--color-tertiary-950: oklch(21.0% 0.080 290deg);
|
--color-tertiary-950: oklch(21% 0.08 290deg);
|
||||||
--color-tertiary-contrast-dark: var(--color-tertiary-950);
|
--color-tertiary-contrast-dark: var(--color-tertiary-950);
|
||||||
--color-tertiary-contrast-light: var(--color-tertiary-50);
|
--color-tertiary-contrast-light: var(--color-tertiary-50);
|
||||||
--color-tertiary-contrast-50: var(--color-tertiary-contrast-dark);
|
--color-tertiary-contrast-50: var(--color-tertiary-contrast-dark);
|
||||||
--color-tertiary-contrast-100: var(--color-tertiary-contrast-dark);
|
--color-tertiary-contrast-100: var(--color-tertiary-contrast-dark);
|
||||||
--color-tertiary-contrast-200: var(--color-tertiary-contrast-dark);
|
--color-tertiary-contrast-200: var(--color-tertiary-contrast-dark);
|
||||||
--color-tertiary-contrast-300: var(--color-tertiary-contrast-dark);
|
--color-tertiary-contrast-300: var(--color-tertiary-contrast-dark);
|
||||||
@@ -274,8 +274,8 @@ html.dark[data-theme='AE_Firefly_Rainbow'] {
|
|||||||
* Hue: ~152°. Consistent with AE_Firefly for recognizable semantic
|
* Hue: ~152°. Consistent with AE_Firefly for recognizable semantic
|
||||||
* color meaning across OSIT themes.
|
* color meaning across OSIT themes.
|
||||||
* =================================================================== */
|
* =================================================================== */
|
||||||
--color-success-50: oklch(95.77% 0.05 152.69deg);
|
--color-success-50: oklch(95.77% 0.05 152.69deg);
|
||||||
--color-success-100: oklch(91.59% 0.06 152.00deg);
|
--color-success-100: oklch(91.59% 0.06 152deg);
|
||||||
--color-success-200: oklch(87.45% 0.08 152.08deg);
|
--color-success-200: oklch(87.45% 0.08 152.08deg);
|
||||||
--color-success-300: oklch(83.57% 0.09 150.85deg);
|
--color-success-300: oklch(83.57% 0.09 150.85deg);
|
||||||
--color-success-400: oklch(79.47% 0.11 150.71deg);
|
--color-success-400: oklch(79.47% 0.11 150.71deg);
|
||||||
@@ -283,11 +283,11 @@ html.dark[data-theme='AE_Firefly_Rainbow'] {
|
|||||||
--color-success-600: oklch(67.65% 0.11 149.94deg);
|
--color-success-600: oklch(67.65% 0.11 149.94deg);
|
||||||
--color-success-700: oklch(59.71% 0.09 150.42deg);
|
--color-success-700: oklch(59.71% 0.09 150.42deg);
|
||||||
--color-success-800: oklch(51.74% 0.08 150.24deg);
|
--color-success-800: oklch(51.74% 0.08 150.24deg);
|
||||||
--color-success-900: oklch(43.20% 0.06 151.12deg);
|
--color-success-900: oklch(43.2% 0.06 151.12deg);
|
||||||
--color-success-950: oklch(34.20% 0.04 151.44deg);
|
--color-success-950: oklch(34.2% 0.04 151.44deg);
|
||||||
--color-success-contrast-dark: var(--color-success-950);
|
--color-success-contrast-dark: var(--color-success-950);
|
||||||
--color-success-contrast-light: var(--color-success-50);
|
--color-success-contrast-light: var(--color-success-50);
|
||||||
--color-success-contrast-50: var(--color-success-contrast-dark);
|
--color-success-contrast-50: var(--color-success-contrast-dark);
|
||||||
--color-success-contrast-100: var(--color-success-contrast-dark);
|
--color-success-contrast-100: var(--color-success-contrast-dark);
|
||||||
--color-success-contrast-200: var(--color-success-contrast-dark);
|
--color-success-contrast-200: var(--color-success-contrast-dark);
|
||||||
--color-success-contrast-300: var(--color-success-contrast-dark);
|
--color-success-contrast-300: var(--color-success-contrast-dark);
|
||||||
@@ -303,20 +303,20 @@ html.dark[data-theme='AE_Firefly_Rainbow'] {
|
|||||||
* WARNING — Amber Orange
|
* WARNING — Amber Orange
|
||||||
* Consistent with AE_Firefly for recognizable semantic meaning.
|
* Consistent with AE_Firefly for recognizable semantic meaning.
|
||||||
* =================================================================== */
|
* =================================================================== */
|
||||||
--color-warning-50: oklch(97.5% 0.065 78deg);
|
--color-warning-50: oklch(97.5% 0.065 78deg);
|
||||||
--color-warning-100: oklch(93.5% 0.090 75deg);
|
--color-warning-100: oklch(93.5% 0.09 75deg);
|
||||||
--color-warning-200: oklch(89.5% 0.120 73deg);
|
--color-warning-200: oklch(89.5% 0.12 73deg);
|
||||||
--color-warning-300: oklch(85.5% 0.145 70deg);
|
--color-warning-300: oklch(85.5% 0.145 70deg);
|
||||||
--color-warning-400: oklch(81.5% 0.160 67deg);
|
--color-warning-400: oklch(81.5% 0.16 67deg);
|
||||||
--color-warning-500: oklch(77.0% 0.165 65deg);
|
--color-warning-500: oklch(77% 0.165 65deg);
|
||||||
--color-warning-600: oklch(69.5% 0.155 64deg);
|
--color-warning-600: oklch(69.5% 0.155 64deg);
|
||||||
--color-warning-700: oklch(61.5% 0.140 63deg);
|
--color-warning-700: oklch(61.5% 0.14 63deg);
|
||||||
--color-warning-800: oklch(53.5% 0.125 62deg);
|
--color-warning-800: oklch(53.5% 0.125 62deg);
|
||||||
--color-warning-900: oklch(45.0% 0.105 61deg);
|
--color-warning-900: oklch(45% 0.105 61deg);
|
||||||
--color-warning-950: oklch(37.0% 0.088 60deg);
|
--color-warning-950: oklch(37% 0.088 60deg);
|
||||||
--color-warning-contrast-dark: var(--color-warning-950);
|
--color-warning-contrast-dark: var(--color-warning-950);
|
||||||
--color-warning-contrast-light: var(--color-warning-50);
|
--color-warning-contrast-light: var(--color-warning-50);
|
||||||
--color-warning-contrast-50: var(--color-warning-contrast-dark);
|
--color-warning-contrast-50: var(--color-warning-contrast-dark);
|
||||||
--color-warning-contrast-100: var(--color-warning-contrast-dark);
|
--color-warning-contrast-100: var(--color-warning-contrast-dark);
|
||||||
--color-warning-contrast-200: var(--color-warning-contrast-dark);
|
--color-warning-contrast-200: var(--color-warning-contrast-dark);
|
||||||
--color-warning-contrast-300: var(--color-warning-contrast-dark);
|
--color-warning-contrast-300: var(--color-warning-contrast-dark);
|
||||||
@@ -332,20 +332,20 @@ html.dark[data-theme='AE_Firefly_Rainbow'] {
|
|||||||
* ERROR — Soft Coral/Rose
|
* ERROR — Soft Coral/Rose
|
||||||
* Consistent with AE_Firefly for recognizable semantic meaning.
|
* Consistent with AE_Firefly for recognizable semantic meaning.
|
||||||
* =================================================================== */
|
* =================================================================== */
|
||||||
--color-error-50: oklch(95.0% 0.040 18deg);
|
--color-error-50: oklch(95% 0.04 18deg);
|
||||||
--color-error-100: oklch(88.0% 0.070 20deg);
|
--color-error-100: oklch(88% 0.07 20deg);
|
||||||
--color-error-200: oklch(80.0% 0.105 21deg);
|
--color-error-200: oklch(80% 0.105 21deg);
|
||||||
--color-error-300: oklch(72.0% 0.140 22deg);
|
--color-error-300: oklch(72% 0.14 22deg);
|
||||||
--color-error-400: oklch(64.5% 0.170 23deg);
|
--color-error-400: oklch(64.5% 0.17 23deg);
|
||||||
--color-error-500: oklch(57.5% 0.195 24deg);
|
--color-error-500: oklch(57.5% 0.195 24deg);
|
||||||
--color-error-600: oklch(51.5% 0.182 25deg);
|
--color-error-600: oklch(51.5% 0.182 25deg);
|
||||||
--color-error-700: oklch(45.5% 0.165 26deg);
|
--color-error-700: oklch(45.5% 0.165 26deg);
|
||||||
--color-error-800: oklch(39.5% 0.148 27deg);
|
--color-error-800: oklch(39.5% 0.148 27deg);
|
||||||
--color-error-900: oklch(33.0% 0.128 28deg);
|
--color-error-900: oklch(33% 0.128 28deg);
|
||||||
--color-error-950: oklch(26.5% 0.108 29deg);
|
--color-error-950: oklch(26.5% 0.108 29deg);
|
||||||
--color-error-contrast-dark: var(--color-error-950);
|
--color-error-contrast-dark: var(--color-error-950);
|
||||||
--color-error-contrast-light: var(--color-error-50);
|
--color-error-contrast-light: var(--color-error-50);
|
||||||
--color-error-contrast-50: var(--color-error-contrast-dark);
|
--color-error-contrast-50: var(--color-error-contrast-dark);
|
||||||
--color-error-contrast-100: var(--color-error-contrast-dark);
|
--color-error-contrast-100: var(--color-error-contrast-dark);
|
||||||
--color-error-contrast-200: var(--color-error-contrast-dark);
|
--color-error-contrast-200: var(--color-error-contrast-dark);
|
||||||
--color-error-contrast-300: var(--color-error-contrast-dark);
|
--color-error-contrast-300: var(--color-error-contrast-dark);
|
||||||
@@ -366,20 +366,20 @@ html.dark[data-theme='AE_Firefly_Rainbow'] {
|
|||||||
* 50 → body-bg light: warm near-white, like morning paper
|
* 50 → body-bg light: warm near-white, like morning paper
|
||||||
* 950 → body-bg dark: deep warm charcoal, like a dim theatre
|
* 950 → body-bg dark: deep warm charcoal, like a dim theatre
|
||||||
* =================================================================== */
|
* =================================================================== */
|
||||||
--color-surface-50: oklch(99.2% 0.004 75deg);
|
--color-surface-50: oklch(99.2% 0.004 75deg);
|
||||||
--color-surface-100: oklch(97.0% 0.007 72deg);
|
--color-surface-100: oklch(97% 0.007 72deg);
|
||||||
--color-surface-200: oklch(93.5% 0.010 70deg);
|
--color-surface-200: oklch(93.5% 0.01 70deg);
|
||||||
--color-surface-300: oklch(88.5% 0.013 68deg);
|
--color-surface-300: oklch(88.5% 0.013 68deg);
|
||||||
--color-surface-400: oklch(81.5% 0.016 66deg);
|
--color-surface-400: oklch(81.5% 0.016 66deg);
|
||||||
--color-surface-500: oklch(70.5% 0.018 64deg);
|
--color-surface-500: oklch(70.5% 0.018 64deg);
|
||||||
--color-surface-600: oklch(59.0% 0.018 62deg);
|
--color-surface-600: oklch(59% 0.018 62deg);
|
||||||
--color-surface-700: oklch(47.5% 0.018 58deg);
|
--color-surface-700: oklch(47.5% 0.018 58deg);
|
||||||
--color-surface-800: oklch(35.5% 0.020 55deg);
|
--color-surface-800: oklch(35.5% 0.02 55deg);
|
||||||
--color-surface-900: oklch(24.5% 0.020 52deg);
|
--color-surface-900: oklch(24.5% 0.02 52deg);
|
||||||
--color-surface-950: oklch(15.5% 0.022 48deg);
|
--color-surface-950: oklch(15.5% 0.022 48deg);
|
||||||
--color-surface-contrast-dark: var(--color-surface-950);
|
--color-surface-contrast-dark: var(--color-surface-950);
|
||||||
--color-surface-contrast-light: var(--color-surface-50);
|
--color-surface-contrast-light: var(--color-surface-50);
|
||||||
--color-surface-contrast-50: var(--color-surface-contrast-dark);
|
--color-surface-contrast-50: var(--color-surface-contrast-dark);
|
||||||
--color-surface-contrast-100: var(--color-surface-contrast-dark);
|
--color-surface-contrast-100: var(--color-surface-contrast-dark);
|
||||||
--color-surface-contrast-200: var(--color-surface-contrast-dark);
|
--color-surface-contrast-200: var(--color-surface-contrast-dark);
|
||||||
--color-surface-contrast-300: var(--color-surface-contrast-dark);
|
--color-surface-contrast-300: var(--color-surface-contrast-dark);
|
||||||
|
|||||||
@@ -60,50 +60,50 @@ html[data-theme='AE_Firefly_SteelBlue'] {
|
|||||||
--radius-base: 0.375rem;
|
--radius-base: 0.375rem;
|
||||||
--radius-container: 0.875rem;
|
--radius-container: 0.875rem;
|
||||||
/* --- Color ramps (light mode) copied from dark block so both modes have full ramps --- */
|
/* --- Color ramps (light mode) copied from dark block so both modes have full ramps --- */
|
||||||
--color-primary-50: oklch(96.5% 0.022 214deg);
|
--color-primary-50: oklch(96.5% 0.022 214deg);
|
||||||
--color-primary-100: oklch(91.0% 0.045 213deg);
|
--color-primary-100: oklch(91% 0.045 213deg);
|
||||||
--color-primary-200: oklch(84.5% 0.072 212deg);
|
--color-primary-200: oklch(84.5% 0.072 212deg);
|
||||||
--color-primary-300: oklch(76.5% 0.097 212deg);
|
--color-primary-300: oklch(76.5% 0.097 212deg);
|
||||||
--color-primary-400: oklch(67.0% 0.115 213deg);
|
--color-primary-400: oklch(67% 0.115 213deg);
|
||||||
--color-primary-500: oklch(56.0% 0.115 214deg);
|
--color-primary-500: oklch(56% 0.115 214deg);
|
||||||
--color-primary-600: oklch(49.0% 0.112 214deg);
|
--color-primary-600: oklch(49% 0.112 214deg);
|
||||||
--color-primary-700: oklch(41.5% 0.105 213deg);
|
--color-primary-700: oklch(41.5% 0.105 213deg);
|
||||||
--color-primary-800: oklch(34.0% 0.095 212deg);
|
--color-primary-800: oklch(34% 0.095 212deg);
|
||||||
--color-primary-900: oklch(26.5% 0.080 211deg);
|
--color-primary-900: oklch(26.5% 0.08 211deg);
|
||||||
--color-primary-950: oklch(18.5% 0.065 210deg);
|
--color-primary-950: oklch(18.5% 0.065 210deg);
|
||||||
--color-primary-contrast-dark: var(--color-primary-950);
|
--color-primary-contrast-dark: var(--color-primary-950);
|
||||||
--color-primary-contrast-light: var(--color-primary-50);
|
--color-primary-contrast-light: var(--color-primary-50);
|
||||||
|
|
||||||
--color-secondary-50: oklch(97.5% 0.055 56deg);
|
--color-secondary-50: oklch(97.5% 0.055 56deg);
|
||||||
--color-secondary-100: oklch(93.5% 0.090 55deg);
|
--color-secondary-100: oklch(93.5% 0.09 55deg);
|
||||||
--color-secondary-200: oklch(89.5% 0.120 54deg);
|
--color-secondary-200: oklch(89.5% 0.12 54deg);
|
||||||
--color-secondary-300: oklch(85.5% 0.148 53deg);
|
--color-secondary-300: oklch(85.5% 0.148 53deg);
|
||||||
--color-secondary-400: oklch(81.5% 0.162 52deg);
|
--color-secondary-400: oklch(81.5% 0.162 52deg);
|
||||||
--color-secondary-500: oklch(76.5% 0.162 51deg);
|
--color-secondary-500: oklch(76.5% 0.162 51deg);
|
||||||
--color-secondary-600: oklch(68.5% 0.152 50deg);
|
--color-secondary-600: oklch(68.5% 0.152 50deg);
|
||||||
--color-secondary-700: oklch(60.5% 0.138 49deg);
|
--color-secondary-700: oklch(60.5% 0.138 49deg);
|
||||||
--color-secondary-800: oklch(52.0% 0.122 48deg);
|
--color-secondary-800: oklch(52% 0.122 48deg);
|
||||||
--color-secondary-900: oklch(43.5% 0.102 47deg);
|
--color-secondary-900: oklch(43.5% 0.102 47deg);
|
||||||
--color-secondary-950: oklch(35.0% 0.084 46deg);
|
--color-secondary-950: oklch(35% 0.084 46deg);
|
||||||
--color-secondary-contrast-dark: var(--color-secondary-950);
|
--color-secondary-contrast-dark: var(--color-secondary-950);
|
||||||
--color-secondary-contrast-light: var(--color-secondary-50);
|
--color-secondary-contrast-light: var(--color-secondary-50);
|
||||||
|
|
||||||
--color-tertiary-50: oklch(95.5% 0.025 232deg);
|
--color-tertiary-50: oklch(95.5% 0.025 232deg);
|
||||||
--color-tertiary-100: oklch(89.5% 0.048 231deg);
|
--color-tertiary-100: oklch(89.5% 0.048 231deg);
|
||||||
--color-tertiary-200: oklch(82.5% 0.072 230deg);
|
--color-tertiary-200: oklch(82.5% 0.072 230deg);
|
||||||
--color-tertiary-300: oklch(74.5% 0.095 229deg);
|
--color-tertiary-300: oklch(74.5% 0.095 229deg);
|
||||||
--color-tertiary-400: oklch(65.5% 0.120 229deg);
|
--color-tertiary-400: oklch(65.5% 0.12 229deg);
|
||||||
--color-tertiary-500: oklch(54.5% 0.135 230deg);
|
--color-tertiary-500: oklch(54.5% 0.135 230deg);
|
||||||
--color-tertiary-600: oklch(47.0% 0.132 230deg);
|
--color-tertiary-600: oklch(47% 0.132 230deg);
|
||||||
--color-tertiary-700: oklch(39.5% 0.122 229deg);
|
--color-tertiary-700: oklch(39.5% 0.122 229deg);
|
||||||
--color-tertiary-800: oklch(32.0% 0.108 228deg);
|
--color-tertiary-800: oklch(32% 0.108 228deg);
|
||||||
--color-tertiary-900: oklch(25.0% 0.090 227deg);
|
--color-tertiary-900: oklch(25% 0.09 227deg);
|
||||||
--color-tertiary-950: oklch(17.5% 0.072 226deg);
|
--color-tertiary-950: oklch(17.5% 0.072 226deg);
|
||||||
--color-tertiary-contrast-dark: var(--color-tertiary-950);
|
--color-tertiary-contrast-dark: var(--color-tertiary-950);
|
||||||
--color-tertiary-contrast-light: var(--color-tertiary-50);
|
--color-tertiary-contrast-light: var(--color-tertiary-50);
|
||||||
|
|
||||||
--color-success-50: oklch(95.77% 0.05 152.69deg);
|
--color-success-50: oklch(95.77% 0.05 152.69deg);
|
||||||
--color-success-100: oklch(91.59% 0.06 152.00deg);
|
--color-success-100: oklch(91.59% 0.06 152deg);
|
||||||
--color-success-200: oklch(87.45% 0.08 152.08deg);
|
--color-success-200: oklch(87.45% 0.08 152.08deg);
|
||||||
--color-success-300: oklch(83.57% 0.09 150.85deg);
|
--color-success-300: oklch(83.57% 0.09 150.85deg);
|
||||||
--color-success-400: oklch(79.47% 0.11 150.71deg);
|
--color-success-400: oklch(79.47% 0.11 150.71deg);
|
||||||
@@ -111,51 +111,51 @@ html[data-theme='AE_Firefly_SteelBlue'] {
|
|||||||
--color-success-600: oklch(67.65% 0.11 149.94deg);
|
--color-success-600: oklch(67.65% 0.11 149.94deg);
|
||||||
--color-success-700: oklch(59.71% 0.09 150.42deg);
|
--color-success-700: oklch(59.71% 0.09 150.42deg);
|
||||||
--color-success-800: oklch(51.74% 0.08 150.24deg);
|
--color-success-800: oklch(51.74% 0.08 150.24deg);
|
||||||
--color-success-900: oklch(43.20% 0.06 151.12deg);
|
--color-success-900: oklch(43.2% 0.06 151.12deg);
|
||||||
--color-success-950: oklch(34.20% 0.04 151.44deg);
|
--color-success-950: oklch(34.2% 0.04 151.44deg);
|
||||||
--color-success-contrast-dark: var(--color-success-950);
|
--color-success-contrast-dark: var(--color-success-950);
|
||||||
--color-success-contrast-light: var(--color-success-50);
|
--color-success-contrast-light: var(--color-success-50);
|
||||||
|
|
||||||
--color-warning-50: oklch(97.5% 0.065 78deg);
|
--color-warning-50: oklch(97.5% 0.065 78deg);
|
||||||
--color-warning-100: oklch(93.5% 0.090 75deg);
|
--color-warning-100: oklch(93.5% 0.09 75deg);
|
||||||
--color-warning-200: oklch(89.5% 0.120 73deg);
|
--color-warning-200: oklch(89.5% 0.12 73deg);
|
||||||
--color-warning-300: oklch(85.5% 0.145 70deg);
|
--color-warning-300: oklch(85.5% 0.145 70deg);
|
||||||
--color-warning-400: oklch(81.5% 0.160 67deg);
|
--color-warning-400: oklch(81.5% 0.16 67deg);
|
||||||
--color-warning-500: oklch(77.0% 0.165 65deg);
|
--color-warning-500: oklch(77% 0.165 65deg);
|
||||||
--color-warning-600: oklch(69.5% 0.155 64deg);
|
--color-warning-600: oklch(69.5% 0.155 64deg);
|
||||||
--color-warning-700: oklch(61.5% 0.140 63deg);
|
--color-warning-700: oklch(61.5% 0.14 63deg);
|
||||||
--color-warning-800: oklch(53.5% 0.125 62deg);
|
--color-warning-800: oklch(53.5% 0.125 62deg);
|
||||||
--color-warning-900: oklch(45.0% 0.105 61deg);
|
--color-warning-900: oklch(45% 0.105 61deg);
|
||||||
--color-warning-950: oklch(37.0% 0.088 60deg);
|
--color-warning-950: oklch(37% 0.088 60deg);
|
||||||
--color-warning-contrast-dark: var(--color-warning-950);
|
--color-warning-contrast-dark: var(--color-warning-950);
|
||||||
--color-warning-contrast-light: var(--color-warning-50);
|
--color-warning-contrast-light: var(--color-warning-50);
|
||||||
|
|
||||||
--color-error-50: oklch(95.0% 0.040 18deg);
|
--color-error-50: oklch(95% 0.04 18deg);
|
||||||
--color-error-100: oklch(88.0% 0.070 20deg);
|
--color-error-100: oklch(88% 0.07 20deg);
|
||||||
--color-error-200: oklch(80.0% 0.105 21deg);
|
--color-error-200: oklch(80% 0.105 21deg);
|
||||||
--color-error-300: oklch(72.0% 0.140 22deg);
|
--color-error-300: oklch(72% 0.14 22deg);
|
||||||
--color-error-400: oklch(64.5% 0.170 23deg);
|
--color-error-400: oklch(64.5% 0.17 23deg);
|
||||||
--color-error-500: oklch(57.5% 0.195 24deg);
|
--color-error-500: oklch(57.5% 0.195 24deg);
|
||||||
--color-error-600: oklch(51.5% 0.182 25deg);
|
--color-error-600: oklch(51.5% 0.182 25deg);
|
||||||
--color-error-700: oklch(45.5% 0.165 26deg);
|
--color-error-700: oklch(45.5% 0.165 26deg);
|
||||||
--color-error-800: oklch(39.5% 0.148 27deg);
|
--color-error-800: oklch(39.5% 0.148 27deg);
|
||||||
--color-error-900: oklch(33.0% 0.128 28deg);
|
--color-error-900: oklch(33% 0.128 28deg);
|
||||||
--color-error-950: oklch(26.5% 0.108 29deg);
|
--color-error-950: oklch(26.5% 0.108 29deg);
|
||||||
--color-error-contrast-dark: var(--color-error-950);
|
--color-error-contrast-dark: var(--color-error-950);
|
||||||
--color-error-contrast-light: var(--color-error-50);
|
--color-error-contrast-light: var(--color-error-50);
|
||||||
|
|
||||||
--color-surface-50: oklch(99.0% 0.004 220deg);
|
--color-surface-50: oklch(99% 0.004 220deg);
|
||||||
--color-surface-100: oklch(96.5% 0.008 218deg);
|
--color-surface-100: oklch(96.5% 0.008 218deg);
|
||||||
--color-surface-200: oklch(92.5% 0.012 217deg);
|
--color-surface-200: oklch(92.5% 0.012 217deg);
|
||||||
--color-surface-300: oklch(87.0% 0.016 216deg);
|
--color-surface-300: oklch(87% 0.016 216deg);
|
||||||
--color-surface-400: oklch(78.5% 0.020 215deg);
|
--color-surface-400: oklch(78.5% 0.02 215deg);
|
||||||
--color-surface-500: oklch(66.5% 0.022 217deg);
|
--color-surface-500: oklch(66.5% 0.022 217deg);
|
||||||
--color-surface-600: oklch(54.5% 0.025 220deg);
|
--color-surface-600: oklch(54.5% 0.025 220deg);
|
||||||
--color-surface-700: oklch(42.5% 0.028 223deg);
|
--color-surface-700: oklch(42.5% 0.028 223deg);
|
||||||
--color-surface-800: oklch(31.0% 0.032 226deg);
|
--color-surface-800: oklch(31% 0.032 226deg);
|
||||||
--color-surface-900: oklch(20.5% 0.035 228deg);
|
--color-surface-900: oklch(20.5% 0.035 228deg);
|
||||||
--color-surface-950: oklch(13.0% 0.040 232deg);
|
--color-surface-950: oklch(13% 0.04 232deg);
|
||||||
--color-surface-contrast-dark: var(--color-surface-950);
|
--color-surface-contrast-dark: var(--color-surface-950);
|
||||||
--color-surface-contrast-light: var(--color-surface-50);
|
--color-surface-contrast-light: var(--color-surface-50);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,20 +175,20 @@ html.dark[data-theme='AE_Firefly_SteelBlue'] {
|
|||||||
* Approx: #4682B4 (CSS SteelBlue) sits at oklch(56%, 0.113, 214°).
|
* Approx: #4682B4 (CSS SteelBlue) sits at oklch(56%, 0.113, 214°).
|
||||||
* At 500 (L≈56%): sufficient contrast with primary-50 text (≥4:1).
|
* At 500 (L≈56%): sufficient contrast with primary-50 text (≥4:1).
|
||||||
* =================================================================== */
|
* =================================================================== */
|
||||||
--color-primary-50: oklch(96.5% 0.022 214deg);
|
--color-primary-50: oklch(96.5% 0.022 214deg);
|
||||||
--color-primary-100: oklch(91.0% 0.045 213deg);
|
--color-primary-100: oklch(91% 0.045 213deg);
|
||||||
--color-primary-200: oklch(84.5% 0.072 212deg);
|
--color-primary-200: oklch(84.5% 0.072 212deg);
|
||||||
--color-primary-300: oklch(76.5% 0.097 212deg);
|
--color-primary-300: oklch(76.5% 0.097 212deg);
|
||||||
--color-primary-400: oklch(67.0% 0.115 213deg);
|
--color-primary-400: oklch(67% 0.115 213deg);
|
||||||
--color-primary-500: oklch(56.0% 0.115 214deg);
|
--color-primary-500: oklch(56% 0.115 214deg);
|
||||||
--color-primary-600: oklch(49.0% 0.112 214deg);
|
--color-primary-600: oklch(49% 0.112 214deg);
|
||||||
--color-primary-700: oklch(41.5% 0.105 213deg);
|
--color-primary-700: oklch(41.5% 0.105 213deg);
|
||||||
--color-primary-800: oklch(34.0% 0.095 212deg);
|
--color-primary-800: oklch(34% 0.095 212deg);
|
||||||
--color-primary-900: oklch(26.5% 0.080 211deg);
|
--color-primary-900: oklch(26.5% 0.08 211deg);
|
||||||
--color-primary-950: oklch(18.5% 0.065 210deg);
|
--color-primary-950: oklch(18.5% 0.065 210deg);
|
||||||
--color-primary-contrast-dark: var(--color-primary-950);
|
--color-primary-contrast-dark: var(--color-primary-950);
|
||||||
--color-primary-contrast-light: var(--color-primary-50);
|
--color-primary-contrast-light: var(--color-primary-50);
|
||||||
--color-primary-contrast-50: var(--color-primary-contrast-dark);
|
--color-primary-contrast-50: var(--color-primary-contrast-dark);
|
||||||
--color-primary-contrast-100: var(--color-primary-contrast-dark);
|
--color-primary-contrast-100: var(--color-primary-contrast-dark);
|
||||||
--color-primary-contrast-200: var(--color-primary-contrast-dark);
|
--color-primary-contrast-200: var(--color-primary-contrast-dark);
|
||||||
--color-primary-contrast-300: var(--color-primary-contrast-dark);
|
--color-primary-contrast-300: var(--color-primary-contrast-dark);
|
||||||
@@ -206,20 +206,20 @@ html.dark[data-theme='AE_Firefly_SteelBlue'] {
|
|||||||
* of steel blue. The classic "metal on metal" contrast pairing —
|
* of steel blue. The classic "metal on metal" contrast pairing —
|
||||||
* used for secondary actions, badges, and call-to-action highlights.
|
* used for secondary actions, badges, and call-to-action highlights.
|
||||||
* =================================================================== */
|
* =================================================================== */
|
||||||
--color-secondary-50: oklch(97.5% 0.055 56deg);
|
--color-secondary-50: oklch(97.5% 0.055 56deg);
|
||||||
--color-secondary-100: oklch(93.5% 0.090 55deg);
|
--color-secondary-100: oklch(93.5% 0.09 55deg);
|
||||||
--color-secondary-200: oklch(89.5% 0.120 54deg);
|
--color-secondary-200: oklch(89.5% 0.12 54deg);
|
||||||
--color-secondary-300: oklch(85.5% 0.148 53deg);
|
--color-secondary-300: oklch(85.5% 0.148 53deg);
|
||||||
--color-secondary-400: oklch(81.5% 0.162 52deg);
|
--color-secondary-400: oklch(81.5% 0.162 52deg);
|
||||||
--color-secondary-500: oklch(76.5% 0.162 51deg);
|
--color-secondary-500: oklch(76.5% 0.162 51deg);
|
||||||
--color-secondary-600: oklch(68.5% 0.152 50deg);
|
--color-secondary-600: oklch(68.5% 0.152 50deg);
|
||||||
--color-secondary-700: oklch(60.5% 0.138 49deg);
|
--color-secondary-700: oklch(60.5% 0.138 49deg);
|
||||||
--color-secondary-800: oklch(52.0% 0.122 48deg);
|
--color-secondary-800: oklch(52% 0.122 48deg);
|
||||||
--color-secondary-900: oklch(43.5% 0.102 47deg);
|
--color-secondary-900: oklch(43.5% 0.102 47deg);
|
||||||
--color-secondary-950: oklch(35.0% 0.084 46deg);
|
--color-secondary-950: oklch(35% 0.084 46deg);
|
||||||
--color-secondary-contrast-dark: var(--color-secondary-950);
|
--color-secondary-contrast-dark: var(--color-secondary-950);
|
||||||
--color-secondary-contrast-light: var(--color-secondary-50);
|
--color-secondary-contrast-light: var(--color-secondary-50);
|
||||||
--color-secondary-contrast-50: var(--color-secondary-contrast-dark);
|
--color-secondary-contrast-50: var(--color-secondary-contrast-dark);
|
||||||
--color-secondary-contrast-100: var(--color-secondary-contrast-dark);
|
--color-secondary-contrast-100: var(--color-secondary-contrast-dark);
|
||||||
--color-secondary-contrast-200: var(--color-secondary-contrast-dark);
|
--color-secondary-contrast-200: var(--color-secondary-contrast-dark);
|
||||||
--color-secondary-contrast-300: var(--color-secondary-contrast-dark);
|
--color-secondary-contrast-300: var(--color-secondary-contrast-dark);
|
||||||
@@ -237,20 +237,20 @@ html.dark[data-theme='AE_Firefly_SteelBlue'] {
|
|||||||
* like the heavy cobalt-blue depths under polished chrome.
|
* like the heavy cobalt-blue depths under polished chrome.
|
||||||
* Used for accents, location chips, and depth elements.
|
* Used for accents, location chips, and depth elements.
|
||||||
* =================================================================== */
|
* =================================================================== */
|
||||||
--color-tertiary-50: oklch(95.5% 0.025 232deg);
|
--color-tertiary-50: oklch(95.5% 0.025 232deg);
|
||||||
--color-tertiary-100: oklch(89.5% 0.048 231deg);
|
--color-tertiary-100: oklch(89.5% 0.048 231deg);
|
||||||
--color-tertiary-200: oklch(82.5% 0.072 230deg);
|
--color-tertiary-200: oklch(82.5% 0.072 230deg);
|
||||||
--color-tertiary-300: oklch(74.5% 0.095 229deg);
|
--color-tertiary-300: oklch(74.5% 0.095 229deg);
|
||||||
--color-tertiary-400: oklch(65.5% 0.120 229deg);
|
--color-tertiary-400: oklch(65.5% 0.12 229deg);
|
||||||
--color-tertiary-500: oklch(54.5% 0.135 230deg);
|
--color-tertiary-500: oklch(54.5% 0.135 230deg);
|
||||||
--color-tertiary-600: oklch(47.0% 0.132 230deg);
|
--color-tertiary-600: oklch(47% 0.132 230deg);
|
||||||
--color-tertiary-700: oklch(39.5% 0.122 229deg);
|
--color-tertiary-700: oklch(39.5% 0.122 229deg);
|
||||||
--color-tertiary-800: oklch(32.0% 0.108 228deg);
|
--color-tertiary-800: oklch(32% 0.108 228deg);
|
||||||
--color-tertiary-900: oklch(25.0% 0.090 227deg);
|
--color-tertiary-900: oklch(25% 0.09 227deg);
|
||||||
--color-tertiary-950: oklch(17.5% 0.072 226deg);
|
--color-tertiary-950: oklch(17.5% 0.072 226deg);
|
||||||
--color-tertiary-contrast-dark: var(--color-tertiary-950);
|
--color-tertiary-contrast-dark: var(--color-tertiary-950);
|
||||||
--color-tertiary-contrast-light: var(--color-tertiary-50);
|
--color-tertiary-contrast-light: var(--color-tertiary-50);
|
||||||
--color-tertiary-contrast-50: var(--color-tertiary-contrast-dark);
|
--color-tertiary-contrast-50: var(--color-tertiary-contrast-dark);
|
||||||
--color-tertiary-contrast-100: var(--color-tertiary-contrast-dark);
|
--color-tertiary-contrast-100: var(--color-tertiary-contrast-dark);
|
||||||
--color-tertiary-contrast-200: var(--color-tertiary-contrast-dark);
|
--color-tertiary-contrast-200: var(--color-tertiary-contrast-dark);
|
||||||
--color-tertiary-contrast-300: var(--color-tertiary-contrast-dark);
|
--color-tertiary-contrast-300: var(--color-tertiary-contrast-dark);
|
||||||
@@ -267,8 +267,8 @@ html.dark[data-theme='AE_Firefly_SteelBlue'] {
|
|||||||
* Hue: ~152°. Consistent with AE_Firefly for recognizable semantic
|
* Hue: ~152°. Consistent with AE_Firefly for recognizable semantic
|
||||||
* color meaning across OSIT themes.
|
* color meaning across OSIT themes.
|
||||||
* =================================================================== */
|
* =================================================================== */
|
||||||
--color-success-50: oklch(95.77% 0.05 152.69deg);
|
--color-success-50: oklch(95.77% 0.05 152.69deg);
|
||||||
--color-success-100: oklch(91.59% 0.06 152.00deg);
|
--color-success-100: oklch(91.59% 0.06 152deg);
|
||||||
--color-success-200: oklch(87.45% 0.08 152.08deg);
|
--color-success-200: oklch(87.45% 0.08 152.08deg);
|
||||||
--color-success-300: oklch(83.57% 0.09 150.85deg);
|
--color-success-300: oklch(83.57% 0.09 150.85deg);
|
||||||
--color-success-400: oklch(79.47% 0.11 150.71deg);
|
--color-success-400: oklch(79.47% 0.11 150.71deg);
|
||||||
@@ -276,11 +276,11 @@ html.dark[data-theme='AE_Firefly_SteelBlue'] {
|
|||||||
--color-success-600: oklch(67.65% 0.11 149.94deg);
|
--color-success-600: oklch(67.65% 0.11 149.94deg);
|
||||||
--color-success-700: oklch(59.71% 0.09 150.42deg);
|
--color-success-700: oklch(59.71% 0.09 150.42deg);
|
||||||
--color-success-800: oklch(51.74% 0.08 150.24deg);
|
--color-success-800: oklch(51.74% 0.08 150.24deg);
|
||||||
--color-success-900: oklch(43.20% 0.06 151.12deg);
|
--color-success-900: oklch(43.2% 0.06 151.12deg);
|
||||||
--color-success-950: oklch(34.20% 0.04 151.44deg);
|
--color-success-950: oklch(34.2% 0.04 151.44deg);
|
||||||
--color-success-contrast-dark: var(--color-success-950);
|
--color-success-contrast-dark: var(--color-success-950);
|
||||||
--color-success-contrast-light: var(--color-success-50);
|
--color-success-contrast-light: var(--color-success-50);
|
||||||
--color-success-contrast-50: var(--color-success-contrast-dark);
|
--color-success-contrast-50: var(--color-success-contrast-dark);
|
||||||
--color-success-contrast-100: var(--color-success-contrast-dark);
|
--color-success-contrast-100: var(--color-success-contrast-dark);
|
||||||
--color-success-contrast-200: var(--color-success-contrast-dark);
|
--color-success-contrast-200: var(--color-success-contrast-dark);
|
||||||
--color-success-contrast-300: var(--color-success-contrast-dark);
|
--color-success-contrast-300: var(--color-success-contrast-dark);
|
||||||
@@ -296,20 +296,20 @@ html.dark[data-theme='AE_Firefly_SteelBlue'] {
|
|||||||
* WARNING — Amber Orange
|
* WARNING — Amber Orange
|
||||||
* Consistent with AE_Firefly for recognizable semantic meaning.
|
* Consistent with AE_Firefly for recognizable semantic meaning.
|
||||||
* =================================================================== */
|
* =================================================================== */
|
||||||
--color-warning-50: oklch(97.5% 0.065 78deg);
|
--color-warning-50: oklch(97.5% 0.065 78deg);
|
||||||
--color-warning-100: oklch(93.5% 0.090 75deg);
|
--color-warning-100: oklch(93.5% 0.09 75deg);
|
||||||
--color-warning-200: oklch(89.5% 0.120 73deg);
|
--color-warning-200: oklch(89.5% 0.12 73deg);
|
||||||
--color-warning-300: oklch(85.5% 0.145 70deg);
|
--color-warning-300: oklch(85.5% 0.145 70deg);
|
||||||
--color-warning-400: oklch(81.5% 0.160 67deg);
|
--color-warning-400: oklch(81.5% 0.16 67deg);
|
||||||
--color-warning-500: oklch(77.0% 0.165 65deg);
|
--color-warning-500: oklch(77% 0.165 65deg);
|
||||||
--color-warning-600: oklch(69.5% 0.155 64deg);
|
--color-warning-600: oklch(69.5% 0.155 64deg);
|
||||||
--color-warning-700: oklch(61.5% 0.140 63deg);
|
--color-warning-700: oklch(61.5% 0.14 63deg);
|
||||||
--color-warning-800: oklch(53.5% 0.125 62deg);
|
--color-warning-800: oklch(53.5% 0.125 62deg);
|
||||||
--color-warning-900: oklch(45.0% 0.105 61deg);
|
--color-warning-900: oklch(45% 0.105 61deg);
|
||||||
--color-warning-950: oklch(37.0% 0.088 60deg);
|
--color-warning-950: oklch(37% 0.088 60deg);
|
||||||
--color-warning-contrast-dark: var(--color-warning-950);
|
--color-warning-contrast-dark: var(--color-warning-950);
|
||||||
--color-warning-contrast-light: var(--color-warning-50);
|
--color-warning-contrast-light: var(--color-warning-50);
|
||||||
--color-warning-contrast-50: var(--color-warning-contrast-dark);
|
--color-warning-contrast-50: var(--color-warning-contrast-dark);
|
||||||
--color-warning-contrast-100: var(--color-warning-contrast-dark);
|
--color-warning-contrast-100: var(--color-warning-contrast-dark);
|
||||||
--color-warning-contrast-200: var(--color-warning-contrast-dark);
|
--color-warning-contrast-200: var(--color-warning-contrast-dark);
|
||||||
--color-warning-contrast-300: var(--color-warning-contrast-dark);
|
--color-warning-contrast-300: var(--color-warning-contrast-dark);
|
||||||
@@ -325,20 +325,20 @@ html.dark[data-theme='AE_Firefly_SteelBlue'] {
|
|||||||
* ERROR — Soft Coral/Rose
|
* ERROR — Soft Coral/Rose
|
||||||
* Consistent with AE_Firefly for recognizable semantic meaning.
|
* Consistent with AE_Firefly for recognizable semantic meaning.
|
||||||
* =================================================================== */
|
* =================================================================== */
|
||||||
--color-error-50: oklch(95.0% 0.040 18deg);
|
--color-error-50: oklch(95% 0.04 18deg);
|
||||||
--color-error-100: oklch(88.0% 0.070 20deg);
|
--color-error-100: oklch(88% 0.07 20deg);
|
||||||
--color-error-200: oklch(80.0% 0.105 21deg);
|
--color-error-200: oklch(80% 0.105 21deg);
|
||||||
--color-error-300: oklch(72.0% 0.140 22deg);
|
--color-error-300: oklch(72% 0.14 22deg);
|
||||||
--color-error-400: oklch(64.5% 0.170 23deg);
|
--color-error-400: oklch(64.5% 0.17 23deg);
|
||||||
--color-error-500: oklch(57.5% 0.195 24deg);
|
--color-error-500: oklch(57.5% 0.195 24deg);
|
||||||
--color-error-600: oklch(51.5% 0.182 25deg);
|
--color-error-600: oklch(51.5% 0.182 25deg);
|
||||||
--color-error-700: oklch(45.5% 0.165 26deg);
|
--color-error-700: oklch(45.5% 0.165 26deg);
|
||||||
--color-error-800: oklch(39.5% 0.148 27deg);
|
--color-error-800: oklch(39.5% 0.148 27deg);
|
||||||
--color-error-900: oklch(33.0% 0.128 28deg);
|
--color-error-900: oklch(33% 0.128 28deg);
|
||||||
--color-error-950: oklch(26.5% 0.108 29deg);
|
--color-error-950: oklch(26.5% 0.108 29deg);
|
||||||
--color-error-contrast-dark: var(--color-error-950);
|
--color-error-contrast-dark: var(--color-error-950);
|
||||||
--color-error-contrast-light: var(--color-error-50);
|
--color-error-contrast-light: var(--color-error-50);
|
||||||
--color-error-contrast-50: var(--color-error-contrast-dark);
|
--color-error-contrast-50: var(--color-error-contrast-dark);
|
||||||
--color-error-contrast-100: var(--color-error-contrast-dark);
|
--color-error-contrast-100: var(--color-error-contrast-dark);
|
||||||
--color-error-contrast-200: var(--color-error-contrast-dark);
|
--color-error-contrast-200: var(--color-error-contrast-dark);
|
||||||
--color-error-contrast-300: var(--color-error-contrast-dark);
|
--color-error-contrast-300: var(--color-error-contrast-dark);
|
||||||
@@ -359,20 +359,20 @@ html.dark[data-theme='AE_Firefly_SteelBlue'] {
|
|||||||
* 50 → body-bg light: brilliant near-white with a chrome whisper
|
* 50 → body-bg light: brilliant near-white with a chrome whisper
|
||||||
* 950 → body-bg dark: deep gunmetal with subtle cool-blue depth
|
* 950 → body-bg dark: deep gunmetal with subtle cool-blue depth
|
||||||
* =================================================================== */
|
* =================================================================== */
|
||||||
--color-surface-50: oklch(99.0% 0.004 220deg);
|
--color-surface-50: oklch(99% 0.004 220deg);
|
||||||
--color-surface-100: oklch(96.5% 0.008 218deg);
|
--color-surface-100: oklch(96.5% 0.008 218deg);
|
||||||
--color-surface-200: oklch(92.5% 0.012 217deg);
|
--color-surface-200: oklch(92.5% 0.012 217deg);
|
||||||
--color-surface-300: oklch(87.0% 0.016 216deg);
|
--color-surface-300: oklch(87% 0.016 216deg);
|
||||||
--color-surface-400: oklch(78.5% 0.020 215deg);
|
--color-surface-400: oklch(78.5% 0.02 215deg);
|
||||||
--color-surface-500: oklch(66.5% 0.022 217deg);
|
--color-surface-500: oklch(66.5% 0.022 217deg);
|
||||||
--color-surface-600: oklch(54.5% 0.025 220deg);
|
--color-surface-600: oklch(54.5% 0.025 220deg);
|
||||||
--color-surface-700: oklch(42.5% 0.028 223deg);
|
--color-surface-700: oklch(42.5% 0.028 223deg);
|
||||||
--color-surface-800: oklch(31.0% 0.032 226deg);
|
--color-surface-800: oklch(31% 0.032 226deg);
|
||||||
--color-surface-900: oklch(20.5% 0.035 228deg);
|
--color-surface-900: oklch(20.5% 0.035 228deg);
|
||||||
--color-surface-950: oklch(13.0% 0.040 232deg);
|
--color-surface-950: oklch(13% 0.04 232deg);
|
||||||
--color-surface-contrast-dark: var(--color-surface-950);
|
--color-surface-contrast-dark: var(--color-surface-950);
|
||||||
--color-surface-contrast-light: var(--color-surface-50);
|
--color-surface-contrast-light: var(--color-surface-50);
|
||||||
--color-surface-contrast-50: var(--color-surface-contrast-dark);
|
--color-surface-contrast-50: var(--color-surface-contrast-dark);
|
||||||
--color-surface-contrast-100: var(--color-surface-contrast-dark);
|
--color-surface-contrast-100: var(--color-surface-contrast-dark);
|
||||||
--color-surface-contrast-200: var(--color-surface-contrast-dark);
|
--color-surface-contrast-200: var(--color-surface-contrast-dark);
|
||||||
--color-surface-contrast-300: var(--color-surface-contrast-dark);
|
--color-surface-contrast-300: var(--color-surface-contrast-dark);
|
||||||
|
|||||||
@@ -63,50 +63,50 @@ html[data-theme='AE_Firefly'] {
|
|||||||
|
|
||||||
/* --- Color ramps (light mode) copied from dark block so both modes have full ramps --- */
|
/* --- Color ramps (light mode) copied from dark block so both modes have full ramps --- */
|
||||||
html[data-theme='AE_Firefly'] {
|
html[data-theme='AE_Firefly'] {
|
||||||
--color-primary-50: oklch(96.5% 0.025 192deg);
|
--color-primary-50: oklch(96.5% 0.025 192deg);
|
||||||
--color-primary-100: oklch(91.0% 0.050 190deg);
|
--color-primary-100: oklch(91% 0.05 190deg);
|
||||||
--color-primary-200: oklch(84.5% 0.078 188deg);
|
--color-primary-200: oklch(84.5% 0.078 188deg);
|
||||||
--color-primary-300: oklch(76.5% 0.105 186deg);
|
--color-primary-300: oklch(76.5% 0.105 186deg);
|
||||||
--color-primary-400: oklch(67.5% 0.125 185deg);
|
--color-primary-400: oklch(67.5% 0.125 185deg);
|
||||||
--color-primary-500: oklch(50.5% 0.130 184deg);
|
--color-primary-500: oklch(50.5% 0.13 184deg);
|
||||||
--color-primary-600: oklch(44.0% 0.125 183deg);
|
--color-primary-600: oklch(44% 0.125 183deg);
|
||||||
--color-primary-700: oklch(37.5% 0.115 182deg);
|
--color-primary-700: oklch(37.5% 0.115 182deg);
|
||||||
--color-primary-800: oklch(30.5% 0.105 181deg);
|
--color-primary-800: oklch(30.5% 0.105 181deg);
|
||||||
--color-primary-900: oklch(23.5% 0.090 180deg);
|
--color-primary-900: oklch(23.5% 0.09 180deg);
|
||||||
--color-primary-950: oklch(16.0% 0.075 179deg);
|
--color-primary-950: oklch(16% 0.075 179deg);
|
||||||
--color-primary-contrast-dark: var(--color-primary-950);
|
--color-primary-contrast-dark: var(--color-primary-950);
|
||||||
--color-primary-contrast-light: var(--color-primary-50);
|
--color-primary-contrast-light: var(--color-primary-50);
|
||||||
|
|
||||||
--color-secondary-50: oklch(97.5% 0.060 102deg);
|
--color-secondary-50: oklch(97.5% 0.06 102deg);
|
||||||
--color-secondary-100: oklch(93.5% 0.095 100deg);
|
--color-secondary-100: oklch(93.5% 0.095 100deg);
|
||||||
--color-secondary-200: oklch(89.5% 0.128 98deg);
|
--color-secondary-200: oklch(89.5% 0.128 98deg);
|
||||||
--color-secondary-300: oklch(85.5% 0.155 95deg);
|
--color-secondary-300: oklch(85.5% 0.155 95deg);
|
||||||
--color-secondary-400: oklch(81.0% 0.170 93deg);
|
--color-secondary-400: oklch(81% 0.17 93deg);
|
||||||
--color-secondary-500: oklch(76.0% 0.170 90deg);
|
--color-secondary-500: oklch(76% 0.17 90deg);
|
||||||
--color-secondary-600: oklch(68.5% 0.160 87deg);
|
--color-secondary-600: oklch(68.5% 0.16 87deg);
|
||||||
--color-secondary-700: oklch(60.5% 0.145 85deg);
|
--color-secondary-700: oklch(60.5% 0.145 85deg);
|
||||||
--color-secondary-800: oklch(52.0% 0.130 83deg);
|
--color-secondary-800: oklch(52% 0.13 83deg);
|
||||||
--color-secondary-900: oklch(43.5% 0.110 81deg);
|
--color-secondary-900: oklch(43.5% 0.11 81deg);
|
||||||
--color-secondary-950: oklch(35.0% 0.090 79deg);
|
--color-secondary-950: oklch(35% 0.09 79deg);
|
||||||
--color-secondary-contrast-dark: var(--color-secondary-950);
|
--color-secondary-contrast-dark: var(--color-secondary-950);
|
||||||
--color-secondary-contrast-light: var(--color-secondary-50);
|
--color-secondary-contrast-light: var(--color-secondary-50);
|
||||||
|
|
||||||
--color-tertiary-50: oklch(95.5% 0.042 283deg);
|
--color-tertiary-50: oklch(95.5% 0.042 283deg);
|
||||||
--color-tertiary-100: oklch(89.0% 0.068 281deg);
|
--color-tertiary-100: oklch(89% 0.068 281deg);
|
||||||
--color-tertiary-200: oklch(81.5% 0.092 279deg);
|
--color-tertiary-200: oklch(81.5% 0.092 279deg);
|
||||||
--color-tertiary-300: oklch(73.5% 0.112 278deg);
|
--color-tertiary-300: oklch(73.5% 0.112 278deg);
|
||||||
--color-tertiary-400: oklch(65.0% 0.132 277deg);
|
--color-tertiary-400: oklch(65% 0.132 277deg);
|
||||||
--color-tertiary-500: oklch(55.5% 0.142 276deg);
|
--color-tertiary-500: oklch(55.5% 0.142 276deg);
|
||||||
--color-tertiary-600: oklch(48.5% 0.138 275deg);
|
--color-tertiary-600: oklch(48.5% 0.138 275deg);
|
||||||
--color-tertiary-700: oklch(41.5% 0.128 274deg);
|
--color-tertiary-700: oklch(41.5% 0.128 274deg);
|
||||||
--color-tertiary-800: oklch(34.5% 0.112 273deg);
|
--color-tertiary-800: oklch(34.5% 0.112 273deg);
|
||||||
--color-tertiary-900: oklch(27.5% 0.098 272deg);
|
--color-tertiary-900: oklch(27.5% 0.098 272deg);
|
||||||
--color-tertiary-950: oklch(20.0% 0.082 271deg);
|
--color-tertiary-950: oklch(20% 0.082 271deg);
|
||||||
--color-tertiary-contrast-dark: var(--color-tertiary-950);
|
--color-tertiary-contrast-dark: var(--color-tertiary-950);
|
||||||
--color-tertiary-contrast-light: var(--color-tertiary-50);
|
--color-tertiary-contrast-light: var(--color-tertiary-50);
|
||||||
|
|
||||||
--color-success-50: oklch(95.77% 0.05 152.69deg);
|
--color-success-50: oklch(95.77% 0.05 152.69deg);
|
||||||
--color-success-100: oklch(91.59% 0.06 152.00deg);
|
--color-success-100: oklch(91.59% 0.06 152deg);
|
||||||
--color-success-200: oklch(87.45% 0.08 152.08deg);
|
--color-success-200: oklch(87.45% 0.08 152.08deg);
|
||||||
--color-success-300: oklch(83.57% 0.09 150.85deg);
|
--color-success-300: oklch(83.57% 0.09 150.85deg);
|
||||||
--color-success-400: oklch(79.47% 0.11 150.71deg);
|
--color-success-400: oklch(79.47% 0.11 150.71deg);
|
||||||
@@ -114,51 +114,51 @@ html[data-theme='AE_Firefly'] {
|
|||||||
--color-success-600: oklch(67.65% 0.11 149.94deg);
|
--color-success-600: oklch(67.65% 0.11 149.94deg);
|
||||||
--color-success-700: oklch(59.71% 0.09 150.42deg);
|
--color-success-700: oklch(59.71% 0.09 150.42deg);
|
||||||
--color-success-800: oklch(51.74% 0.08 150.24deg);
|
--color-success-800: oklch(51.74% 0.08 150.24deg);
|
||||||
--color-success-900: oklch(43.20% 0.06 151.12deg);
|
--color-success-900: oklch(43.2% 0.06 151.12deg);
|
||||||
--color-success-950: oklch(34.20% 0.04 151.44deg);
|
--color-success-950: oklch(34.2% 0.04 151.44deg);
|
||||||
--color-success-contrast-dark: var(--color-success-950);
|
--color-success-contrast-dark: var(--color-success-950);
|
||||||
--color-success-contrast-light: var(--color-success-50);
|
--color-success-contrast-light: var(--color-success-50);
|
||||||
|
|
||||||
--color-warning-50: oklch(97.5% 0.065 78deg);
|
--color-warning-50: oklch(97.5% 0.065 78deg);
|
||||||
--color-warning-100: oklch(93.5% 0.090 75deg);
|
--color-warning-100: oklch(93.5% 0.09 75deg);
|
||||||
--color-warning-200: oklch(89.5% 0.120 73deg);
|
--color-warning-200: oklch(89.5% 0.12 73deg);
|
||||||
--color-warning-300: oklch(85.5% 0.145 70deg);
|
--color-warning-300: oklch(85.5% 0.145 70deg);
|
||||||
--color-warning-400: oklch(81.5% 0.160 67deg);
|
--color-warning-400: oklch(81.5% 0.16 67deg);
|
||||||
--color-warning-500: oklch(77.0% 0.165 65deg);
|
--color-warning-500: oklch(77% 0.165 65deg);
|
||||||
--color-warning-600: oklch(69.5% 0.155 64deg);
|
--color-warning-600: oklch(69.5% 0.155 64deg);
|
||||||
--color-warning-700: oklch(61.5% 0.140 63deg);
|
--color-warning-700: oklch(61.5% 0.14 63deg);
|
||||||
--color-warning-800: oklch(53.5% 0.125 62deg);
|
--color-warning-800: oklch(53.5% 0.125 62deg);
|
||||||
--color-warning-900: oklch(45.0% 0.105 61deg);
|
--color-warning-900: oklch(45% 0.105 61deg);
|
||||||
--color-warning-950: oklch(37.0% 0.088 60deg);
|
--color-warning-950: oklch(37% 0.088 60deg);
|
||||||
--color-warning-contrast-dark: var(--color-warning-950);
|
--color-warning-contrast-dark: var(--color-warning-950);
|
||||||
--color-warning-contrast-light: var(--color-warning-50);
|
--color-warning-contrast-light: var(--color-warning-50);
|
||||||
|
|
||||||
--color-error-50: oklch(95.0% 0.040 18deg);
|
--color-error-50: oklch(95% 0.04 18deg);
|
||||||
--color-error-100: oklch(88.0% 0.070 20deg);
|
--color-error-100: oklch(88% 0.07 20deg);
|
||||||
--color-error-200: oklch(80.0% 0.105 21deg);
|
--color-error-200: oklch(80% 0.105 21deg);
|
||||||
--color-error-300: oklch(72.0% 0.140 22deg);
|
--color-error-300: oklch(72% 0.14 22deg);
|
||||||
--color-error-400: oklch(64.5% 0.170 23deg);
|
--color-error-400: oklch(64.5% 0.17 23deg);
|
||||||
--color-error-500: oklch(57.5% 0.195 24deg);
|
--color-error-500: oklch(57.5% 0.195 24deg);
|
||||||
--color-error-600: oklch(51.5% 0.182 25deg);
|
--color-error-600: oklch(51.5% 0.182 25deg);
|
||||||
--color-error-700: oklch(45.5% 0.165 26deg);
|
--color-error-700: oklch(45.5% 0.165 26deg);
|
||||||
--color-error-800: oklch(39.5% 0.148 27deg);
|
--color-error-800: oklch(39.5% 0.148 27deg);
|
||||||
--color-error-900: oklch(33.0% 0.128 28deg);
|
--color-error-900: oklch(33% 0.128 28deg);
|
||||||
--color-error-950: oklch(26.5% 0.108 29deg);
|
--color-error-950: oklch(26.5% 0.108 29deg);
|
||||||
--color-error-contrast-dark: var(--color-error-950);
|
--color-error-contrast-dark: var(--color-error-950);
|
||||||
--color-error-contrast-light: var(--color-error-50);
|
--color-error-contrast-light: var(--color-error-50);
|
||||||
|
|
||||||
--color-surface-50: oklch(99.2% 0.003 220deg);
|
--color-surface-50: oklch(99.2% 0.003 220deg);
|
||||||
--color-surface-100: oklch(97.0% 0.006 217deg);
|
--color-surface-100: oklch(97% 0.006 217deg);
|
||||||
--color-surface-200: oklch(93.5% 0.009 215deg);
|
--color-surface-200: oklch(93.5% 0.009 215deg);
|
||||||
--color-surface-300: oklch(88.5% 0.012 213deg);
|
--color-surface-300: oklch(88.5% 0.012 213deg);
|
||||||
--color-surface-400: oklch(81.5% 0.015 212deg);
|
--color-surface-400: oklch(81.5% 0.015 212deg);
|
||||||
--color-surface-500: oklch(70.5% 0.016 215deg);
|
--color-surface-500: oklch(70.5% 0.016 215deg);
|
||||||
--color-surface-600: oklch(59.0% 0.018 218deg);
|
--color-surface-600: oklch(59% 0.018 218deg);
|
||||||
--color-surface-700: oklch(47.5% 0.020 222deg);
|
--color-surface-700: oklch(47.5% 0.02 222deg);
|
||||||
--color-surface-800: oklch(30.5% 0.022 226deg);
|
--color-surface-800: oklch(30.5% 0.022 226deg);
|
||||||
--color-surface-900: oklch(24.5% 0.025 229deg);
|
--color-surface-900: oklch(24.5% 0.025 229deg);
|
||||||
--color-surface-950: oklch(15.5% 0.028 233deg);
|
--color-surface-950: oklch(15.5% 0.028 233deg);
|
||||||
--color-surface-contrast-dark: var(--color-surface-950);
|
--color-surface-contrast-dark: var(--color-surface-950);
|
||||||
--color-surface-contrast-light: var(--color-surface-50);
|
--color-surface-contrast-light: var(--color-surface-50);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,20 +174,20 @@ html.dark[data-theme='AE_Firefly'] {
|
|||||||
* PRIMARY — Luminescent Firefly Teal
|
* PRIMARY — Luminescent Firefly Teal
|
||||||
* ...existing code...
|
* ...existing code...
|
||||||
*/
|
*/
|
||||||
--color-primary-50: oklch(96.5% 0.025 192deg);
|
--color-primary-50: oklch(96.5% 0.025 192deg);
|
||||||
--color-primary-100: oklch(91.0% 0.050 190deg);
|
--color-primary-100: oklch(91% 0.05 190deg);
|
||||||
--color-primary-200: oklch(84.5% 0.078 188deg);
|
--color-primary-200: oklch(84.5% 0.078 188deg);
|
||||||
--color-primary-300: oklch(76.5% 0.105 186deg);
|
--color-primary-300: oklch(76.5% 0.105 186deg);
|
||||||
--color-primary-400: oklch(67.5% 0.125 185deg);
|
--color-primary-400: oklch(67.5% 0.125 185deg);
|
||||||
--color-primary-500: oklch(50.5% 0.130 184deg);
|
--color-primary-500: oklch(50.5% 0.13 184deg);
|
||||||
--color-primary-600: oklch(44.0% 0.125 183deg);
|
--color-primary-600: oklch(44% 0.125 183deg);
|
||||||
--color-primary-700: oklch(37.5% 0.115 182deg);
|
--color-primary-700: oklch(37.5% 0.115 182deg);
|
||||||
--color-primary-800: oklch(30.5% 0.105 181deg);
|
--color-primary-800: oklch(30.5% 0.105 181deg);
|
||||||
--color-primary-900: oklch(23.5% 0.090 180deg);
|
--color-primary-900: oklch(23.5% 0.09 180deg);
|
||||||
--color-primary-950: oklch(16.0% 0.075 179deg);
|
--color-primary-950: oklch(16% 0.075 179deg);
|
||||||
--color-primary-contrast-dark: var(--color-primary-950);
|
--color-primary-contrast-dark: var(--color-primary-950);
|
||||||
--color-primary-contrast-light: var(--color-primary-50);
|
--color-primary-contrast-light: var(--color-primary-50);
|
||||||
--color-primary-contrast-50: var(--color-primary-contrast-dark);
|
--color-primary-contrast-50: var(--color-primary-contrast-dark);
|
||||||
--color-primary-contrast-100: var(--color-primary-contrast-dark);
|
--color-primary-contrast-100: var(--color-primary-contrast-dark);
|
||||||
--color-primary-contrast-200: var(--color-primary-contrast-dark);
|
--color-primary-contrast-200: var(--color-primary-contrast-dark);
|
||||||
--color-primary-contrast-300: var(--color-primary-contrast-dark);
|
--color-primary-contrast-300: var(--color-primary-contrast-dark);
|
||||||
@@ -200,20 +200,20 @@ html.dark[data-theme='AE_Firefly'] {
|
|||||||
--color-primary-contrast-950: var(--color-primary-contrast-light);
|
--color-primary-contrast-950: var(--color-primary-contrast-light);
|
||||||
|
|
||||||
/* ...existing code for secondary, tertiary, success, warning, error, surface... */
|
/* ...existing code for secondary, tertiary, success, warning, error, surface... */
|
||||||
--color-secondary-50: oklch(97.5% 0.060 102deg);
|
--color-secondary-50: oklch(97.5% 0.06 102deg);
|
||||||
--color-secondary-100: oklch(93.5% 0.095 100deg);
|
--color-secondary-100: oklch(93.5% 0.095 100deg);
|
||||||
--color-secondary-200: oklch(89.5% 0.128 98deg);
|
--color-secondary-200: oklch(89.5% 0.128 98deg);
|
||||||
--color-secondary-300: oklch(85.5% 0.155 95deg);
|
--color-secondary-300: oklch(85.5% 0.155 95deg);
|
||||||
--color-secondary-400: oklch(81.0% 0.170 93deg);
|
--color-secondary-400: oklch(81% 0.17 93deg);
|
||||||
--color-secondary-500: oklch(76.0% 0.170 90deg);
|
--color-secondary-500: oklch(76% 0.17 90deg);
|
||||||
--color-secondary-600: oklch(68.5% 0.160 87deg);
|
--color-secondary-600: oklch(68.5% 0.16 87deg);
|
||||||
--color-secondary-700: oklch(60.5% 0.145 85deg);
|
--color-secondary-700: oklch(60.5% 0.145 85deg);
|
||||||
--color-secondary-800: oklch(52.0% 0.130 83deg);
|
--color-secondary-800: oklch(52% 0.13 83deg);
|
||||||
--color-secondary-900: oklch(43.5% 0.110 81deg);
|
--color-secondary-900: oklch(43.5% 0.11 81deg);
|
||||||
--color-secondary-950: oklch(35.0% 0.090 79deg);
|
--color-secondary-950: oklch(35% 0.09 79deg);
|
||||||
--color-secondary-contrast-dark: var(--color-secondary-950);
|
--color-secondary-contrast-dark: var(--color-secondary-950);
|
||||||
--color-secondary-contrast-light: var(--color-secondary-50);
|
--color-secondary-contrast-light: var(--color-secondary-50);
|
||||||
--color-secondary-contrast-50: var(--color-secondary-contrast-dark);
|
--color-secondary-contrast-50: var(--color-secondary-contrast-dark);
|
||||||
--color-secondary-contrast-100: var(--color-secondary-contrast-dark);
|
--color-secondary-contrast-100: var(--color-secondary-contrast-dark);
|
||||||
--color-secondary-contrast-200: var(--color-secondary-contrast-dark);
|
--color-secondary-contrast-200: var(--color-secondary-contrast-dark);
|
||||||
--color-secondary-contrast-300: var(--color-secondary-contrast-dark);
|
--color-secondary-contrast-300: var(--color-secondary-contrast-dark);
|
||||||
@@ -225,20 +225,20 @@ html.dark[data-theme='AE_Firefly'] {
|
|||||||
--color-secondary-contrast-900: var(--color-secondary-contrast-light);
|
--color-secondary-contrast-900: var(--color-secondary-contrast-light);
|
||||||
--color-secondary-contrast-950: var(--color-secondary-contrast-light);
|
--color-secondary-contrast-950: var(--color-secondary-contrast-light);
|
||||||
|
|
||||||
--color-tertiary-50: oklch(95.5% 0.042 283deg);
|
--color-tertiary-50: oklch(95.5% 0.042 283deg);
|
||||||
--color-tertiary-100: oklch(89.0% 0.068 281deg);
|
--color-tertiary-100: oklch(89% 0.068 281deg);
|
||||||
--color-tertiary-200: oklch(81.5% 0.092 279deg);
|
--color-tertiary-200: oklch(81.5% 0.092 279deg);
|
||||||
--color-tertiary-300: oklch(73.5% 0.112 278deg);
|
--color-tertiary-300: oklch(73.5% 0.112 278deg);
|
||||||
--color-tertiary-400: oklch(65.0% 0.132 277deg);
|
--color-tertiary-400: oklch(65% 0.132 277deg);
|
||||||
--color-tertiary-500: oklch(55.5% 0.142 276deg);
|
--color-tertiary-500: oklch(55.5% 0.142 276deg);
|
||||||
--color-tertiary-600: oklch(48.5% 0.138 275deg);
|
--color-tertiary-600: oklch(48.5% 0.138 275deg);
|
||||||
--color-tertiary-700: oklch(41.5% 0.128 274deg);
|
--color-tertiary-700: oklch(41.5% 0.128 274deg);
|
||||||
--color-tertiary-800: oklch(34.5% 0.112 273deg);
|
--color-tertiary-800: oklch(34.5% 0.112 273deg);
|
||||||
--color-tertiary-900: oklch(27.5% 0.098 272deg);
|
--color-tertiary-900: oklch(27.5% 0.098 272deg);
|
||||||
--color-tertiary-950: oklch(20.0% 0.082 271deg);
|
--color-tertiary-950: oklch(20% 0.082 271deg);
|
||||||
--color-tertiary-contrast-dark: var(--color-tertiary-950);
|
--color-tertiary-contrast-dark: var(--color-tertiary-950);
|
||||||
--color-tertiary-contrast-light: var(--color-tertiary-50);
|
--color-tertiary-contrast-light: var(--color-tertiary-50);
|
||||||
--color-tertiary-contrast-50: var(--color-tertiary-contrast-dark);
|
--color-tertiary-contrast-50: var(--color-tertiary-contrast-dark);
|
||||||
--color-tertiary-contrast-100: var(--color-tertiary-contrast-dark);
|
--color-tertiary-contrast-100: var(--color-tertiary-contrast-dark);
|
||||||
--color-tertiary-contrast-200: var(--color-tertiary-contrast-dark);
|
--color-tertiary-contrast-200: var(--color-tertiary-contrast-dark);
|
||||||
--color-tertiary-contrast-300: var(--color-tertiary-contrast-dark);
|
--color-tertiary-contrast-300: var(--color-tertiary-contrast-dark);
|
||||||
@@ -250,8 +250,8 @@ html.dark[data-theme='AE_Firefly'] {
|
|||||||
--color-tertiary-contrast-900: var(--color-tertiary-contrast-light);
|
--color-tertiary-contrast-900: var(--color-tertiary-contrast-light);
|
||||||
--color-tertiary-contrast-950: var(--color-tertiary-contrast-light);
|
--color-tertiary-contrast-950: var(--color-tertiary-contrast-light);
|
||||||
|
|
||||||
--color-success-50: oklch(95.77% 0.05 152.69deg);
|
--color-success-50: oklch(95.77% 0.05 152.69deg);
|
||||||
--color-success-100: oklch(91.59% 0.06 152.00deg);
|
--color-success-100: oklch(91.59% 0.06 152deg);
|
||||||
--color-success-200: oklch(87.45% 0.08 152.08deg);
|
--color-success-200: oklch(87.45% 0.08 152.08deg);
|
||||||
--color-success-300: oklch(83.57% 0.09 150.85deg);
|
--color-success-300: oklch(83.57% 0.09 150.85deg);
|
||||||
--color-success-400: oklch(79.47% 0.11 150.71deg);
|
--color-success-400: oklch(79.47% 0.11 150.71deg);
|
||||||
@@ -259,11 +259,11 @@ html.dark[data-theme='AE_Firefly'] {
|
|||||||
--color-success-600: oklch(67.65% 0.11 149.94deg);
|
--color-success-600: oklch(67.65% 0.11 149.94deg);
|
||||||
--color-success-700: oklch(59.71% 0.09 150.42deg);
|
--color-success-700: oklch(59.71% 0.09 150.42deg);
|
||||||
--color-success-800: oklch(51.74% 0.08 150.24deg);
|
--color-success-800: oklch(51.74% 0.08 150.24deg);
|
||||||
--color-success-900: oklch(43.20% 0.06 151.12deg);
|
--color-success-900: oklch(43.2% 0.06 151.12deg);
|
||||||
--color-success-950: oklch(34.20% 0.04 151.44deg);
|
--color-success-950: oklch(34.2% 0.04 151.44deg);
|
||||||
--color-success-contrast-dark: var(--color-success-950);
|
--color-success-contrast-dark: var(--color-success-950);
|
||||||
--color-success-contrast-light: var(--color-success-50);
|
--color-success-contrast-light: var(--color-success-50);
|
||||||
--color-success-contrast-50: var(--color-success-contrast-dark);
|
--color-success-contrast-50: var(--color-success-contrast-dark);
|
||||||
--color-success-contrast-100: var(--color-success-contrast-dark);
|
--color-success-contrast-100: var(--color-success-contrast-dark);
|
||||||
--color-success-contrast-200: var(--color-success-contrast-dark);
|
--color-success-contrast-200: var(--color-success-contrast-dark);
|
||||||
--color-success-contrast-300: var(--color-success-contrast-dark);
|
--color-success-contrast-300: var(--color-success-contrast-dark);
|
||||||
@@ -275,20 +275,20 @@ html.dark[data-theme='AE_Firefly'] {
|
|||||||
--color-success-contrast-900: var(--color-success-contrast-light);
|
--color-success-contrast-900: var(--color-success-contrast-light);
|
||||||
--color-success-contrast-950: var(--color-success-contrast-light);
|
--color-success-contrast-950: var(--color-success-contrast-light);
|
||||||
|
|
||||||
--color-warning-50: oklch(97.5% 0.065 78deg);
|
--color-warning-50: oklch(97.5% 0.065 78deg);
|
||||||
--color-warning-100: oklch(93.5% 0.090 75deg);
|
--color-warning-100: oklch(93.5% 0.09 75deg);
|
||||||
--color-warning-200: oklch(89.5% 0.120 73deg);
|
--color-warning-200: oklch(89.5% 0.12 73deg);
|
||||||
--color-warning-300: oklch(85.5% 0.145 70deg);
|
--color-warning-300: oklch(85.5% 0.145 70deg);
|
||||||
--color-warning-400: oklch(81.5% 0.160 67deg);
|
--color-warning-400: oklch(81.5% 0.16 67deg);
|
||||||
--color-warning-500: oklch(77.0% 0.165 65deg);
|
--color-warning-500: oklch(77% 0.165 65deg);
|
||||||
--color-warning-600: oklch(69.5% 0.155 64deg);
|
--color-warning-600: oklch(69.5% 0.155 64deg);
|
||||||
--color-warning-700: oklch(61.5% 0.140 63deg);
|
--color-warning-700: oklch(61.5% 0.14 63deg);
|
||||||
--color-warning-800: oklch(53.5% 0.125 62deg);
|
--color-warning-800: oklch(53.5% 0.125 62deg);
|
||||||
--color-warning-900: oklch(45.0% 0.105 61deg);
|
--color-warning-900: oklch(45% 0.105 61deg);
|
||||||
--color-warning-950: oklch(37.0% 0.088 60deg);
|
--color-warning-950: oklch(37% 0.088 60deg);
|
||||||
--color-warning-contrast-dark: var(--color-warning-950);
|
--color-warning-contrast-dark: var(--color-warning-950);
|
||||||
--color-warning-contrast-light: var(--color-warning-50);
|
--color-warning-contrast-light: var(--color-warning-50);
|
||||||
--color-warning-contrast-50: var(--color-warning-contrast-dark);
|
--color-warning-contrast-50: var(--color-warning-contrast-dark);
|
||||||
--color-warning-contrast-100: var(--color-warning-contrast-dark);
|
--color-warning-contrast-100: var(--color-warning-contrast-dark);
|
||||||
--color-warning-contrast-200: var(--color-warning-contrast-dark);
|
--color-warning-contrast-200: var(--color-warning-contrast-dark);
|
||||||
--color-warning-contrast-300: var(--color-warning-contrast-dark);
|
--color-warning-contrast-300: var(--color-warning-contrast-dark);
|
||||||
@@ -300,20 +300,20 @@ html.dark[data-theme='AE_Firefly'] {
|
|||||||
--color-warning-contrast-900: var(--color-warning-contrast-light);
|
--color-warning-contrast-900: var(--color-warning-contrast-light);
|
||||||
--color-warning-contrast-950: var(--color-warning-contrast-light);
|
--color-warning-contrast-950: var(--color-warning-contrast-light);
|
||||||
|
|
||||||
--color-error-50: oklch(95.0% 0.040 18deg);
|
--color-error-50: oklch(95% 0.04 18deg);
|
||||||
--color-error-100: oklch(88.0% 0.070 20deg);
|
--color-error-100: oklch(88% 0.07 20deg);
|
||||||
--color-error-200: oklch(80.0% 0.105 21deg);
|
--color-error-200: oklch(80% 0.105 21deg);
|
||||||
--color-error-300: oklch(72.0% 0.140 22deg);
|
--color-error-300: oklch(72% 0.14 22deg);
|
||||||
--color-error-400: oklch(64.5% 0.170 23deg);
|
--color-error-400: oklch(64.5% 0.17 23deg);
|
||||||
--color-error-500: oklch(57.5% 0.195 24deg);
|
--color-error-500: oklch(57.5% 0.195 24deg);
|
||||||
--color-error-600: oklch(51.5% 0.182 25deg);
|
--color-error-600: oklch(51.5% 0.182 25deg);
|
||||||
--color-error-700: oklch(45.5% 0.165 26deg);
|
--color-error-700: oklch(45.5% 0.165 26deg);
|
||||||
--color-error-800: oklch(39.5% 0.148 27deg);
|
--color-error-800: oklch(39.5% 0.148 27deg);
|
||||||
--color-error-900: oklch(33.0% 0.128 28deg);
|
--color-error-900: oklch(33% 0.128 28deg);
|
||||||
--color-error-950: oklch(26.5% 0.108 29deg);
|
--color-error-950: oklch(26.5% 0.108 29deg);
|
||||||
--color-error-contrast-dark: var(--color-error-950);
|
--color-error-contrast-dark: var(--color-error-950);
|
||||||
--color-error-contrast-light: var(--color-error-50);
|
--color-error-contrast-light: var(--color-error-50);
|
||||||
--color-error-contrast-50: var(--color-error-contrast-dark);
|
--color-error-contrast-50: var(--color-error-contrast-dark);
|
||||||
--color-error-contrast-100: var(--color-error-contrast-dark);
|
--color-error-contrast-100: var(--color-error-contrast-dark);
|
||||||
--color-error-contrast-200: var(--color-error-contrast-dark);
|
--color-error-contrast-200: var(--color-error-contrast-dark);
|
||||||
--color-error-contrast-300: var(--color-error-contrast-dark);
|
--color-error-contrast-300: var(--color-error-contrast-dark);
|
||||||
@@ -325,20 +325,20 @@ html.dark[data-theme='AE_Firefly'] {
|
|||||||
--color-error-contrast-900: var(--color-error-contrast-light);
|
--color-error-contrast-900: var(--color-error-contrast-light);
|
||||||
--color-error-contrast-950: var(--color-error-contrast-light);
|
--color-error-contrast-950: var(--color-error-contrast-light);
|
||||||
|
|
||||||
--color-surface-50: oklch(99.2% 0.003 220deg);
|
--color-surface-50: oklch(99.2% 0.003 220deg);
|
||||||
--color-surface-100: oklch(97.0% 0.006 217deg);
|
--color-surface-100: oklch(97% 0.006 217deg);
|
||||||
--color-surface-200: oklch(93.5% 0.009 215deg);
|
--color-surface-200: oklch(93.5% 0.009 215deg);
|
||||||
--color-surface-300: oklch(88.5% 0.012 213deg);
|
--color-surface-300: oklch(88.5% 0.012 213deg);
|
||||||
--color-surface-400: oklch(81.5% 0.015 212deg);
|
--color-surface-400: oklch(81.5% 0.015 212deg);
|
||||||
--color-surface-500: oklch(70.5% 0.016 215deg);
|
--color-surface-500: oklch(70.5% 0.016 215deg);
|
||||||
--color-surface-600: oklch(59.0% 0.018 218deg);
|
--color-surface-600: oklch(59% 0.018 218deg);
|
||||||
--color-surface-700: oklch(47.5% 0.020 222deg);
|
--color-surface-700: oklch(47.5% 0.02 222deg);
|
||||||
--color-surface-800: oklch(35.5% 0.022 226deg);
|
--color-surface-800: oklch(35.5% 0.022 226deg);
|
||||||
--color-surface-900: oklch(24.5% 0.025 229deg);
|
--color-surface-900: oklch(24.5% 0.025 229deg);
|
||||||
--color-surface-950: oklch(15.5% 0.028 233deg);
|
--color-surface-950: oklch(15.5% 0.028 233deg);
|
||||||
--color-surface-contrast-dark: var(--color-surface-950);
|
--color-surface-contrast-dark: var(--color-surface-950);
|
||||||
--color-surface-contrast-light: var(--color-surface-50);
|
--color-surface-contrast-light: var(--color-surface-50);
|
||||||
--color-surface-contrast-50: var(--color-surface-contrast-dark);
|
--color-surface-contrast-50: var(--color-surface-contrast-dark);
|
||||||
--color-surface-contrast-100: var(--color-surface-contrast-dark);
|
--color-surface-contrast-100: var(--color-surface-contrast-dark);
|
||||||
--color-surface-contrast-200: var(--color-surface-contrast-dark);
|
--color-surface-contrast-200: var(--color-surface-contrast-dark);
|
||||||
--color-surface-contrast-300: var(--color-surface-contrast-dark);
|
--color-surface-contrast-300: var(--color-surface-contrast-dark);
|
||||||
|
|||||||
89
src/app.css
89
src/app.css
@@ -10,12 +10,15 @@
|
|||||||
/* Sync native browser control rendering (select dropdowns, scrollbars, etc.)
|
/* Sync native browser control rendering (select dropdowns, scrollbars, etc.)
|
||||||
with the app's dark/light mode toggle. Without this, native controls follow
|
with the app's dark/light mode toggle. Without this, native controls follow
|
||||||
the OS theme rather than the app's .dark/.light class on <html>. */
|
the OS theme rather than the app's .dark/.light class on <html>. */
|
||||||
html.dark { color-scheme: dark; }
|
html.dark {
|
||||||
html.light { color-scheme: light; }
|
color-scheme: dark;
|
||||||
|
}
|
||||||
|
html.light {
|
||||||
|
color-scheme: light;
|
||||||
|
}
|
||||||
|
|
||||||
@import '@skeletonlabs/skeleton';
|
@import '@skeletonlabs/skeleton';
|
||||||
|
|
||||||
|
|
||||||
/* Register Preset Themes */
|
/* Register Preset Themes */
|
||||||
/* @import '@skeletonlabs/skeleton/themes/{theme-name}'; */
|
/* @import '@skeletonlabs/skeleton/themes/{theme-name}'; */
|
||||||
@import '@skeletonlabs/skeleton/themes/cerberus';
|
@import '@skeletonlabs/skeleton/themes/cerberus';
|
||||||
@@ -154,13 +157,13 @@ html.light { color-scheme: light; }
|
|||||||
.dark .input:not([type='checkbox']):not([type='radio']):not([type='range']),
|
.dark .input:not([type='checkbox']):not([type='radio']):not([type='range']),
|
||||||
.dark .select,
|
.dark .select,
|
||||||
.dark .textarea {
|
.dark .textarea {
|
||||||
color: rgb(243 244 246); /* gray-100 */
|
color: rgb(243 244 246); /* gray-100 */
|
||||||
background-color: rgb(55 65 81); /* gray-700 */
|
background-color: rgb(55 65 81); /* gray-700 */
|
||||||
border-color: rgb(75 85 99); /* gray-600 */
|
border-color: rgb(75 85 99); /* gray-600 */
|
||||||
}
|
}
|
||||||
.dark .input::placeholder,
|
.dark .input::placeholder,
|
||||||
.dark .textarea::placeholder {
|
.dark .textarea::placeholder {
|
||||||
color: rgb(156 163 175); /* gray-400 — legible at reduced opacity */
|
color: rgb(156 163 175); /* gray-400 — legible at reduced opacity */
|
||||||
}
|
}
|
||||||
/* Option elements in dark selects — forces browser native dark chrome */
|
/* Option elements in dark selects — forces browser native dark chrome */
|
||||||
.dark .select option {
|
.dark .select option {
|
||||||
@@ -198,8 +201,12 @@ body {
|
|||||||
/* Font size accessibility modes — cycled via the font size button in the sys menu.
|
/* Font size accessibility modes — cycled via the font size button in the sys menu.
|
||||||
Applied as a class on <html> by the layout DOM effect.
|
Applied as a class on <html> by the layout DOM effect.
|
||||||
The 'default' mode has no class (browser default, typically 16px). */
|
The 'default' mode has no class (browser default, typically 16px). */
|
||||||
html.font-size-larger { font-size: 112.5%; } /* ~18px base */
|
html.font-size-larger {
|
||||||
html.font-size-smaller { font-size: 87.5%; } /* ~14px base */
|
font-size: 112.5%;
|
||||||
|
} /* ~18px base */
|
||||||
|
html.font-size-smaller {
|
||||||
|
font-size: 87.5%;
|
||||||
|
} /* ~14px base */
|
||||||
|
|
||||||
html.super_access #appShell {
|
html.super_access #appShell {
|
||||||
background-color: hsla(0, 100%, 50%, 0.5);
|
background-color: hsla(0, 100%, 50%, 0.5);
|
||||||
@@ -356,51 +363,51 @@ html.trusted_access #appShell {
|
|||||||
/* @apply preset-tonal-primary border border-primary-500 transition-all; */
|
/* @apply preset-tonal-primary border border-primary-500 transition-all; */
|
||||||
}
|
}
|
||||||
.ae_btn_secondary {
|
.ae_btn_secondary {
|
||||||
@apply preset-tonal-secondary border border-secondary-500 transition-all;
|
@apply preset-tonal-secondary border-secondary-500 border transition-all;
|
||||||
/* hover:preset-filled-secondary-500 */
|
/* hover:preset-filled-secondary-500 */
|
||||||
}
|
}
|
||||||
.ae_btn_tertiary {
|
.ae_btn_tertiary {
|
||||||
@apply preset-tonal-tertiary border border-tertiary-500 transition-all;
|
@apply preset-tonal-tertiary border-tertiary-500 border transition-all;
|
||||||
}
|
}
|
||||||
.ae_btn_success {
|
.ae_btn_success {
|
||||||
@apply preset-tonal-success border border-success-500 transition-all;
|
@apply preset-tonal-success border-success-500 border transition-all;
|
||||||
}
|
}
|
||||||
.ae_btn_warning {
|
.ae_btn_warning {
|
||||||
@apply preset-tonal-warning border border-warning-500 text-warning-950-50 transition-all;
|
@apply preset-tonal-warning border-warning-500 text-warning-950-50 border transition-all;
|
||||||
}
|
}
|
||||||
.ae_btn_error {
|
.ae_btn_error {
|
||||||
@apply preset-tonal-error border border-error-500 transition-all;
|
@apply preset-tonal-error border-error-500 border transition-all;
|
||||||
}
|
}
|
||||||
.ae_btn_surface {
|
.ae_btn_surface {
|
||||||
@apply preset-tonal-surface border border-surface-500 transition-all;
|
@apply preset-tonal-surface border-surface-500 border transition-all;
|
||||||
}
|
}
|
||||||
/* Buttons customized for Aether using Skeleton Tailwind preset classes */
|
/* Buttons customized for Aether using Skeleton Tailwind preset classes */
|
||||||
.ae_btn_info {
|
.ae_btn_info {
|
||||||
@apply border text-cyan-950 dark:text-cyan-50 bg-cyan-50 dark:bg-cyan-950 border-cyan-100 dark:border-cyan-900 hover:bg-cyan-200 hover:dark:bg-cyan-800 transition-all;
|
@apply border border-cyan-100 bg-cyan-50 text-cyan-950 transition-all hover:bg-cyan-200 dark:border-cyan-900 dark:bg-cyan-950 dark:text-cyan-50 hover:dark:bg-cyan-800;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Buttons are for filled and outlined presets */
|
/* Buttons are for filled and outlined presets */
|
||||||
.ae_btn_secondary_filled {
|
.ae_btn_secondary_filled {
|
||||||
@apply preset-filled-secondary-200-800 border border-secondary-500 transition-all;
|
@apply preset-filled-secondary-200-800 border-secondary-500 border transition-all;
|
||||||
/* hover:preset-filled-secondary-500 */
|
/* hover:preset-filled-secondary-500 */
|
||||||
}
|
}
|
||||||
.ae_btn_secondary_outlined {
|
.ae_btn_secondary_outlined {
|
||||||
@apply preset-outlined-secondary-200-800 hover:preset-filled-secondary-400-600 text-secondary-950-50 transition-all;
|
@apply preset-outlined-secondary-200-800 hover:preset-filled-secondary-400-600 text-secondary-950-50 transition-all;
|
||||||
}
|
}
|
||||||
.ae_btn_success_filled {
|
.ae_btn_success_filled {
|
||||||
@apply preset-filled-success-200-800 border border-success-500 transition-all;
|
@apply preset-filled-success-200-800 border-success-500 border transition-all;
|
||||||
}
|
}
|
||||||
.ae_btn_success_outlined {
|
.ae_btn_success_outlined {
|
||||||
@apply preset-outlined-success-200-800 hover:preset-filled-success-400-600 text-success-950-50 transition-all;
|
@apply preset-outlined-success-200-800 hover:preset-filled-success-400-600 text-success-950-50 transition-all;
|
||||||
}
|
}
|
||||||
.ae_btn_warning_filled {
|
.ae_btn_warning_filled {
|
||||||
@apply preset-filled-warning-200-800 border border-warning-500 transition-all;
|
@apply preset-filled-warning-200-800 border-warning-500 border transition-all;
|
||||||
}
|
}
|
||||||
.ae_btn_warning_outlined {
|
.ae_btn_warning_outlined {
|
||||||
@apply preset-outlined-warning-200-800 hover:preset-filled-warning-400-600 text-warning-950-50 transition-all;
|
@apply preset-outlined-warning-200-800 hover:preset-filled-warning-400-600 text-warning-950-50 transition-all;
|
||||||
}
|
}
|
||||||
.ae_btn_surface_filled {
|
.ae_btn_surface_filled {
|
||||||
@apply preset-filled-surface-200-800 border border-surface-500 transition-all;
|
@apply preset-filled-surface-200-800 border-surface-500 border transition-all;
|
||||||
}
|
}
|
||||||
.ae_btn_surface_outlined {
|
.ae_btn_surface_outlined {
|
||||||
@apply preset-outlined-surface-200-800 hover:preset-filled-surface-400-600 text-surface-950-50 transition-all;
|
@apply preset-outlined-surface-200-800 hover:preset-filled-surface-400-600 text-surface-950-50 transition-all;
|
||||||
@@ -409,10 +416,10 @@ html.trusted_access #appShell {
|
|||||||
@apply preset-outlined-error-200-800 hover:preset-filled-error-400-600 text-error-950-50 transition-all;
|
@apply preset-outlined-error-200-800 hover:preset-filled-error-400-600 text-error-950-50 transition-all;
|
||||||
}
|
}
|
||||||
.ae_btn_info_filled {
|
.ae_btn_info_filled {
|
||||||
@apply border text-cyan-950 dark:text-cyan-50 bg-cyan-200 dark:bg-cyan-800 border-cyan-200 dark:border-cyan-800 transition-all;
|
@apply border border-cyan-200 bg-cyan-200 text-cyan-950 transition-all dark:border-cyan-800 dark:bg-cyan-800 dark:text-cyan-50;
|
||||||
}
|
}
|
||||||
.ae_btn_info_outlined {
|
.ae_btn_info_outlined {
|
||||||
@apply border text-cyan-950 dark:text-cyan-50 bg-cyan-50 dark:bg-cyan-950 border-cyan-200 dark:border-cyan-800 transition-all;
|
@apply border border-cyan-200 bg-cyan-50 text-cyan-950 transition-all dark:border-cyan-800 dark:bg-cyan-950 dark:text-cyan-50;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Containers customized for Aether using Skeleton Tailwind preset classes */
|
/* Containers customized for Aether using Skeleton Tailwind preset classes */
|
||||||
@@ -436,7 +443,7 @@ html.trusted_access #appShell {
|
|||||||
.ae_module_header {
|
.ae_module_header {
|
||||||
/* LCI request 3a5997 */
|
/* LCI request 3a5997 */
|
||||||
/* bg-gray-300 */
|
/* bg-gray-300 */
|
||||||
@apply preset-tonal-surface rounded-md flex flex-col md:flex-row flex-wrap gap-0.25 items-center justify-between w-full max-w-7xl p-1 px-2;
|
@apply preset-tonal-surface flex w-full max-w-7xl flex-col flex-wrap items-center justify-between gap-0.25 rounded-md p-1 px-2 md:flex-row;
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-theme='AE_c_LCI'] .ae_module_header {
|
[data-theme='AE_c_LCI'] .ae_module_header {
|
||||||
@@ -453,32 +460,18 @@ html.trusted_access #appShell {
|
|||||||
@apply container;
|
@apply container;
|
||||||
}
|
}
|
||||||
.ae_container_module_menu {
|
.ae_container_module_menu {
|
||||||
@apply w-full max-w-7xl flex flex-col items-center justify-center gap-1 p-1
|
@apply flex w-full max-w-7xl flex-col items-center justify-center gap-1 rounded-md border border-gray-200 p-1 transition-all duration-700 hover:bg-gray-100 hover:duration-300 dark:border-gray-800 dark:hover:bg-gray-900;
|
||||||
border rounded-md border-gray-200 dark:border-gray-800 hover:bg-gray-100 dark:hover:bg-gray-900 transition-all duration-700 hover:duration-300;
|
|
||||||
}
|
}
|
||||||
.ae_container_module_options {
|
.ae_container_module_options {
|
||||||
@apply text-cyan-950 dark:text-cyan-50
|
@apply flex w-full max-w-full flex-row flex-wrap items-center justify-around rounded-md border border-cyan-200 bg-cyan-50 p-2 text-cyan-950 transition-all hover:border-cyan-400 hover:bg-cyan-100 dark:border-cyan-800 dark:bg-cyan-950 dark:text-cyan-50 dark:hover:border-cyan-600 dark:hover:bg-cyan-900;
|
||||||
bg-cyan-50 dark:bg-cyan-950 hover:bg-cyan-100 dark:hover:bg-cyan-900
|
|
||||||
border border-cyan-200 dark:border-cyan-800 hover:border-cyan-400 dark:hover:border-cyan-600
|
|
||||||
rounded-md
|
|
||||||
flex flex-row flex-wrap items-center justify-around
|
|
||||||
w-full max-w-full
|
|
||||||
p-2
|
|
||||||
transition-all;
|
|
||||||
}
|
}
|
||||||
.ae_container_module_help {
|
.ae_container_module_help {
|
||||||
@apply text-yellow-950 dark:text-yellow-50
|
@apply w-lg max-w-full rounded-md border border-yellow-200 bg-yellow-50 p-2 text-yellow-950 transition-all hover:border-yellow-400 hover:bg-yellow-100 dark:border-yellow-800 dark:bg-yellow-950 dark:text-yellow-50 dark:hover:border-yellow-600 dark:hover:bg-yellow-900;
|
||||||
bg-yellow-50 dark:bg-yellow-950 hover:bg-yellow-100 dark:hover:bg-yellow-900
|
|
||||||
border border-yellow-200 dark:border-yellow-800 hover:border-yellow-400 dark:hover:border-yellow-600
|
|
||||||
rounded-md
|
|
||||||
w-lg max-w-full
|
|
||||||
p-2
|
|
||||||
transition-all;
|
|
||||||
/* bg-yellow-100 border border-yellow-400 p-2 rounded-md max-w-xl */
|
/* bg-yellow-100 border border-yellow-400 p-2 rounded-md max-w-xl */
|
||||||
}
|
}
|
||||||
|
|
||||||
.ae_container_actions {
|
.ae_container_actions {
|
||||||
@apply container preset-tonal-success border border-success-500 rounded-md flex flex-row items-center my-2 p-2;
|
@apply preset-tonal-success border-success-500 container my-2 flex flex-row items-center rounded-md border p-2;
|
||||||
}
|
}
|
||||||
.ae_container_results {
|
.ae_container_results {
|
||||||
@apply container;
|
@apply container;
|
||||||
@@ -500,23 +493,11 @@ html.trusted_access #appShell {
|
|||||||
@apply container;
|
@apply container;
|
||||||
}
|
}
|
||||||
.ae_container_help {
|
.ae_container_help {
|
||||||
@apply text-yellow-950 dark:text-yellow-50
|
@apply max-w-full rounded-md border border-yellow-200 bg-yellow-50 p-2 text-yellow-950 transition-all hover:border-yellow-400 hover:bg-yellow-100 dark:border-yellow-800 dark:bg-yellow-950 dark:text-yellow-50 dark:hover:border-yellow-600 dark:hover:bg-yellow-900;
|
||||||
bg-yellow-50 dark:bg-yellow-950 hover:bg-yellow-100 dark:hover:bg-yellow-900
|
|
||||||
border border-yellow-200 dark:border-yellow-800 hover:border-yellow-400 dark:hover:border-yellow-600
|
|
||||||
rounded-md
|
|
||||||
max-w-full
|
|
||||||
p-2
|
|
||||||
transition-all;
|
|
||||||
/* bg-yellow-100 border border-yellow-400 p-2 rounded-md max-w-xl */
|
/* bg-yellow-100 border border-yellow-400 p-2 rounded-md max-w-xl */
|
||||||
}
|
}
|
||||||
.ae_container_info {
|
.ae_container_info {
|
||||||
@apply text-cyan-950 dark:text-cyan-50
|
@apply max-w-full rounded-md border border-cyan-200 bg-cyan-50 p-2 text-cyan-950 transition-all hover:border-cyan-400 hover:bg-cyan-100 dark:border-cyan-800 dark:bg-cyan-950 dark:text-cyan-50 dark:hover:border-cyan-600 dark:hover:bg-cyan-900;
|
||||||
bg-cyan-50 dark:bg-cyan-950 hover:bg-cyan-100 dark:hover:bg-cyan-900
|
|
||||||
border border-cyan-200 dark:border-cyan-800 hover:border-cyan-400 dark:hover:border-cyan-600
|
|
||||||
rounded-md
|
|
||||||
max-w-full
|
|
||||||
p-2
|
|
||||||
transition-all;
|
|
||||||
}
|
}
|
||||||
.ae_container_msg {
|
.ae_container_msg {
|
||||||
@apply container;
|
@apply container;
|
||||||
|
|||||||
@@ -12,16 +12,13 @@
|
|||||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||||
<link
|
<link
|
||||||
href="https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,400;0,700;1,400;1,700&display=swap"
|
href="https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,400;0,700;1,400;1,700&display=swap"
|
||||||
rel="stylesheet"
|
rel="stylesheet" />
|
||||||
/>
|
|
||||||
<link
|
<link
|
||||||
href="https://fonts.googleapis.com/css2?family=Noto+Serif:ital,wght@0,400;0,700;1,400;1,700&display=swap"
|
href="https://fonts.googleapis.com/css2?family=Noto+Serif:ital,wght@0,400;0,700;1,400;1,700&display=swap"
|
||||||
rel="stylesheet"
|
rel="stylesheet" />
|
||||||
/>
|
|
||||||
<link
|
<link
|
||||||
href="https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&display=swap"
|
href="https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&display=swap"
|
||||||
rel="stylesheet"
|
rel="stylesheet" />
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- <link href="app.css" rel="stylesheet"> -->
|
<!-- <link href="app.css" rel="stylesheet"> -->
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,9 @@ export const delete_object = async function delete_object({
|
|||||||
// Construct the URL with query parameters
|
// Construct the URL with query parameters
|
||||||
const url = new URL(endpoint, api_cfg['base_url']);
|
const url = new URL(endpoint, api_cfg['base_url']);
|
||||||
if (params) {
|
if (params) {
|
||||||
Object.keys(params).forEach((key) => url.searchParams.append(key, params[key]));
|
Object.keys(params).forEach((key) =>
|
||||||
|
url.searchParams.append(key, params[key])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean and merge headers without mutating the original api_cfg
|
// Clean and merge headers without mutating the original api_cfg
|
||||||
@@ -70,8 +72,13 @@ export const delete_object = async function delete_object({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Auto-inject Authorization header if JWT is present but header is missing
|
// Auto-inject Authorization header if JWT is present but header is missing
|
||||||
const jwt = headers_cleaned['jwt'] || headers_cleaned['JWT'] || api_cfg['jwt'];
|
const jwt =
|
||||||
if (jwt && !headers_cleaned['Authorization'] && !headers_cleaned['authorization']) {
|
headers_cleaned['jwt'] || headers_cleaned['JWT'] || api_cfg['jwt'];
|
||||||
|
if (
|
||||||
|
jwt &&
|
||||||
|
!headers_cleaned['Authorization'] &&
|
||||||
|
!headers_cleaned['authorization']
|
||||||
|
) {
|
||||||
headers_cleaned['Authorization'] = `Bearer ${jwt}`;
|
headers_cleaned['Authorization'] = `Bearer ${jwt}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,20 +100,26 @@ export const delete_object = async function delete_object({
|
|||||||
try {
|
try {
|
||||||
const controller = new AbortController();
|
const controller = new AbortController();
|
||||||
const timeoutId = setTimeout(() => {
|
const timeoutId = setTimeout(() => {
|
||||||
console.error(`API DELETE request timed out after ${timeout}ms.`);
|
console.error(
|
||||||
|
`API DELETE request timed out after ${timeout}ms.`
|
||||||
|
);
|
||||||
controller.abort();
|
controller.abort();
|
||||||
}, timeout);
|
}, timeout);
|
||||||
|
|
||||||
const fetchOptions: RequestInit = {
|
const fetchOptions: RequestInit = {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: headers_cleaned,
|
headers: headers_cleaned,
|
||||||
body: Object.keys(data).length > 0 ? JSON.stringify(data) : undefined,
|
body:
|
||||||
|
Object.keys(data).length > 0
|
||||||
|
? JSON.stringify(data)
|
||||||
|
: undefined,
|
||||||
signal: controller.signal
|
signal: controller.signal
|
||||||
};
|
};
|
||||||
|
|
||||||
const response = await fetch_method(url.toString(), fetchOptions).catch(function (
|
const response = await fetch_method(
|
||||||
error: any
|
url.toString(),
|
||||||
) {
|
fetchOptions
|
||||||
|
).catch(function (error: any) {
|
||||||
console.log(
|
console.log(
|
||||||
'API DELETE Object *fetch* request was aborted or failed in an unexpected way.',
|
'API DELETE Object *fetch* request was aborted or failed in an unexpected way.',
|
||||||
error
|
error
|
||||||
@@ -121,7 +134,9 @@ export const delete_object = async function delete_object({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`Response: status=${response.status} attempt=${attempt}`);
|
console.log(
|
||||||
|
`Response: status=${response.status} attempt=${attempt}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
@@ -131,13 +146,18 @@ export const delete_object = async function delete_object({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const errorBody = await response.text();
|
const errorBody = await response.text();
|
||||||
console.error(`HTTP error! status: ${response.status}`, errorBody);
|
console.error(
|
||||||
|
`HTTP error! status: ${response.status}`,
|
||||||
|
errorBody
|
||||||
|
);
|
||||||
|
|
||||||
if (response.status >= 400 && response.status < 404) {
|
if (response.status >= 400 && response.status < 404) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error(`HTTP error! status: ${response.status} - ${errorBody}`);
|
throw new Error(
|
||||||
|
`HTTP error! status: ${response.status} - ${errorBody}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const json = await response.json();
|
const json = await response.json();
|
||||||
@@ -148,7 +168,11 @@ export const delete_object = async function delete_object({
|
|||||||
|
|
||||||
// Return the response data or metadata
|
// Return the response data or metadata
|
||||||
// Robustly handle V3 response envelopes
|
// Robustly handle V3 response envelopes
|
||||||
return return_meta ? json : (json.data !== undefined ? json.data : json);
|
return return_meta
|
||||||
|
? json
|
||||||
|
: json.data !== undefined
|
||||||
|
? json.data
|
||||||
|
: json;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`API DELETE error on attempt ${attempt}:`, error);
|
console.error(`API DELETE error on attempt ${attempt}:`, error);
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,9 @@ export async function get_ae_obj_id_crud({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}) {
|
}) {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** get_ae_obj_id_crud() *** Type: ${obj_type} ID: ${obj_id}`);
|
console.log(
|
||||||
|
`*** get_ae_obj_id_crud() *** Type: ${obj_type} ID: ${obj_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// V3 Standard: Unified endpoint for all objects
|
// V3 Standard: Unified endpoint for all objects
|
||||||
@@ -77,7 +79,10 @@ export async function get_ae_obj_id_crud({
|
|||||||
log_lvl: log_lvl,
|
log_lvl: log_lvl,
|
||||||
return_meta: return_meta
|
return_meta: return_meta
|
||||||
}).catch(function (error: any) {
|
}).catch(function (error: any) {
|
||||||
console.error(`API GET CRUD object ID request failed for ${obj_type}/${obj_id}`, error);
|
console.error(
|
||||||
|
`API GET CRUD object ID request failed for ${obj_type}/${obj_id}`,
|
||||||
|
error
|
||||||
|
);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -95,7 +95,10 @@ interface GetAeObjLiV3Params {
|
|||||||
view?: string;
|
view?: string;
|
||||||
limit?: number;
|
limit?: number;
|
||||||
offset?: number;
|
offset?: number;
|
||||||
order_by_li?: Record<string, 'ASC' | 'DESC'> | Record<string, 'ASC' | 'DESC'>[] | null;
|
order_by_li?:
|
||||||
|
| Record<string, 'ASC' | 'DESC'>
|
||||||
|
| Record<string, 'ASC' | 'DESC'>[]
|
||||||
|
| null;
|
||||||
delay_ms?: number;
|
delay_ms?: number;
|
||||||
params?: key_val;
|
params?: key_val;
|
||||||
headers?: key_val;
|
headers?: key_val;
|
||||||
@@ -162,7 +165,10 @@ interface GetNestedObjLiV3Params {
|
|||||||
view?: string;
|
view?: string;
|
||||||
limit?: number;
|
limit?: number;
|
||||||
offset?: number;
|
offset?: number;
|
||||||
order_by_li?: Record<string, 'ASC' | 'DESC'> | Record<string, 'ASC' | 'DESC'>[] | null;
|
order_by_li?:
|
||||||
|
| Record<string, 'ASC' | 'DESC'>
|
||||||
|
| Record<string, 'ASC' | 'DESC'>[]
|
||||||
|
| null;
|
||||||
delay_ms?: number;
|
delay_ms?: number;
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ export async function get_data_store({
|
|||||||
log_lvl = 0
|
log_lvl = 0
|
||||||
}: GetDataStoreV3Params): Promise<any> {
|
}: GetDataStoreV3Params): Promise<any> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** get_data_store() *** code=${code} no_account_id=${no_account_id}`);
|
console.log(
|
||||||
|
`*** get_data_store() *** code=${code} no_account_id=${no_account_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const endpoint = `/v3/data_store/code/${code}`;
|
const endpoint = `/v3/data_store/code/${code}`;
|
||||||
|
|||||||
@@ -41,7 +41,9 @@ export const get_object = async function get_object({
|
|||||||
retry_count?: number;
|
retry_count?: number;
|
||||||
}) {
|
}) {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** get_object() *** Endpoint: ${endpoint} AE Task ID: ${task_id}`);
|
console.log(
|
||||||
|
`*** get_object() *** Endpoint: ${endpoint} AE Task ID: ${task_id}`
|
||||||
|
);
|
||||||
console.log('Params:', params);
|
console.log('Params:', params);
|
||||||
if (log_lvl > 1) {
|
if (log_lvl > 1) {
|
||||||
console.log('Data:', data);
|
console.log('Data:', data);
|
||||||
@@ -55,7 +57,10 @@ export const get_object = async function get_object({
|
|||||||
|
|
||||||
// FAIL FAST: Check if we are explicitly offline to avoid long browser timeouts
|
// FAIL FAST: Check if we are explicitly offline to avoid long browser timeouts
|
||||||
if (typeof navigator !== 'undefined' && !navigator.onLine) {
|
if (typeof navigator !== 'undefined' && !navigator.onLine) {
|
||||||
if (log_lvl) console.log('get_object: Browser is offline. Failing fast to allow cache fallback.');
|
if (log_lvl)
|
||||||
|
console.log(
|
||||||
|
'get_object: Browser is offline. Failing fast to allow cache fallback.'
|
||||||
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,7 +69,9 @@ export const get_object = async function get_object({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const url = new URL(endpoint, api_cfg['base_url']);
|
const url = new URL(endpoint, api_cfg['base_url']);
|
||||||
Object.keys(params).forEach((key) => url.searchParams.append(key, params[key]));
|
Object.keys(params).forEach((key) =>
|
||||||
|
url.searchParams.append(key, params[key])
|
||||||
|
);
|
||||||
|
|
||||||
const controller = new AbortController();
|
const controller = new AbortController();
|
||||||
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
||||||
@@ -96,14 +103,19 @@ export const get_object = async function get_object({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle "Bootstrap Paradox" for unauthenticated requests
|
// Handle "Bootstrap Paradox" for unauthenticated requests
|
||||||
const bypass_val = merged_headers['x-no-account-id'] || merged_headers['x_no_account_id'];
|
const bypass_val =
|
||||||
const is_valid_bypass = bypass_val === 'bypass' ||
|
merged_headers['x-no-account-id'] || merged_headers['x_no_account_id'];
|
||||||
bypass_val === 'Nothing to See Here' ||
|
const is_valid_bypass =
|
||||||
params['key'] ||
|
bypass_val === 'bypass' ||
|
||||||
bypass_val === 'direct-download';
|
bypass_val === 'Nothing to See Here' ||
|
||||||
|
params['key'] ||
|
||||||
|
bypass_val === 'direct-download';
|
||||||
|
|
||||||
if (is_valid_bypass) {
|
if (is_valid_bypass) {
|
||||||
if (log_lvl > 1) console.log('api_get_object: Valid bypass detected. Stripping account ID context.');
|
if (log_lvl > 1)
|
||||||
|
console.log(
|
||||||
|
'api_get_object: Valid bypass detected. Stripping account ID context.'
|
||||||
|
);
|
||||||
delete merged_headers['x-account-id'];
|
delete merged_headers['x-account-id'];
|
||||||
delete merged_headers['x_account_id'];
|
delete merged_headers['x_account_id'];
|
||||||
} else {
|
} else {
|
||||||
@@ -126,11 +138,12 @@ export const get_object = async function get_object({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Auto-inject Authorization header if JWT is present but header is missing
|
// Auto-inject Authorization header if JWT is present but header is missing
|
||||||
let jwt = headers_cleaned['jwt'] ||
|
let jwt =
|
||||||
headers_cleaned['JWT'] ||
|
headers_cleaned['jwt'] ||
|
||||||
api_cfg['jwt'] ||
|
headers_cleaned['JWT'] ||
|
||||||
api_cfg['headers']?.['jwt'] ||
|
api_cfg['jwt'] ||
|
||||||
api_cfg['headers']?.['JWT'];
|
api_cfg['headers']?.['jwt'] ||
|
||||||
|
api_cfg['headers']?.['JWT'];
|
||||||
|
|
||||||
// Final Fallback: Direct check of primary ae_loc key
|
// Final Fallback: Direct check of primary ae_loc key
|
||||||
if (!jwt && typeof localStorage !== 'undefined') {
|
if (!jwt && typeof localStorage !== 'undefined') {
|
||||||
@@ -145,7 +158,11 @@ export const get_object = async function get_object({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (jwt && !headers_cleaned['Authorization'] && !headers_cleaned['authorization']) {
|
if (
|
||||||
|
jwt &&
|
||||||
|
!headers_cleaned['Authorization'] &&
|
||||||
|
!headers_cleaned['authorization']
|
||||||
|
) {
|
||||||
headers_cleaned['Authorization'] = `Bearer ${jwt}`;
|
headers_cleaned['Authorization'] = `Bearer ${jwt}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,18 +191,29 @@ export const get_object = async function get_object({
|
|||||||
for (let attempt = 1; attempt <= retry_count; attempt++) {
|
for (let attempt = 1; attempt <= retry_count; attempt++) {
|
||||||
// FAIL FAST: Check if we are explicitly offline to avoid long browser timeouts
|
// FAIL FAST: Check if we are explicitly offline to avoid long browser timeouts
|
||||||
if (typeof navigator !== 'undefined' && !navigator.onLine) {
|
if (typeof navigator !== 'undefined' && !navigator.onLine) {
|
||||||
if (log_lvl) console.log(`get_object: Browser is offline (attempt ${attempt}). Failing fast to allow cache fallback.`);
|
if (log_lvl)
|
||||||
|
console.log(
|
||||||
|
`get_object: Browser is offline (attempt ${attempt}). Failing fast to allow cache fallback.`
|
||||||
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch_method(url.toString(), fetchOptions).catch(function (
|
const response = await fetch_method(
|
||||||
error: any
|
url.toString(),
|
||||||
) {
|
fetchOptions
|
||||||
|
).catch(function (error: any) {
|
||||||
// SILENCE NOISE: Aborted requests (common in SWR/Background loads) shouldn't spam logs
|
// SILENCE NOISE: Aborted requests (common in SWR/Background loads) shouldn't spam logs
|
||||||
if (error.name === 'AbortError' || error.message?.includes('aborted') || error.name === 'TypeError') {
|
if (
|
||||||
|
error.name === 'AbortError' ||
|
||||||
|
error.message?.includes('aborted') ||
|
||||||
|
error.name === 'TypeError'
|
||||||
|
) {
|
||||||
if (log_lvl > 1) {
|
if (log_lvl > 1) {
|
||||||
console.log('API GET: Request was aborted or terminated by browser. This is expected during navigation.', error);
|
console.log(
|
||||||
|
'API GET: Request was aborted or terminated by browser. This is expected during navigation.',
|
||||||
|
error
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return error; // Return error to be handled below
|
return error; // Return error to be handled below
|
||||||
}
|
}
|
||||||
@@ -199,11 +227,19 @@ export const get_object = async function get_object({
|
|||||||
clearTimeout(timeoutId);
|
clearTimeout(timeoutId);
|
||||||
|
|
||||||
// Check if we should stop due to abort or network failure
|
// Check if we should stop due to abort or network failure
|
||||||
if (response instanceof Error || (response && (response.name === 'TypeError' || response.name === 'AbortError'))) {
|
if (
|
||||||
|
response instanceof Error ||
|
||||||
|
(response &&
|
||||||
|
(response.name === 'TypeError' ||
|
||||||
|
response.name === 'AbortError'))
|
||||||
|
) {
|
||||||
// If it was an explicit abort, definitely stop
|
// If it was an explicit abort, definitely stop
|
||||||
if (response.name === 'AbortError') return false;
|
if (response.name === 'AbortError') return false;
|
||||||
|
|
||||||
if (log_lvl > 1) console.log('API GET Object: Detected NetworkError or TypeError. Failing fast.');
|
if (log_lvl > 1)
|
||||||
|
console.log(
|
||||||
|
'API GET Object: Detected NetworkError or TypeError. Failing fast.'
|
||||||
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,24 +267,45 @@ export const get_object = async function get_object({
|
|||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
if (response.status === 404) {
|
if (response.status === 404) {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log('The response was a 404 not found "error". Returning null.');
|
console.log(
|
||||||
|
'The response was a 404 not found "error". Returning null.'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FAIL FAST (Section 2D): Do not retry on Auth or Client errors (400, 401, 403, 422)
|
// FAIL FAST (Section 2D): Do not retry on Auth or Client errors (400, 401, 403, 422)
|
||||||
if (response.status === 400 || response.status === 401 || response.status === 403 || response.status === 422) {
|
if (
|
||||||
if (log_lvl) console.error(`API Client Failure (${response.status}). Failing fast.`);
|
response.status === 400 ||
|
||||||
|
response.status === 401 ||
|
||||||
|
response.status === 403 ||
|
||||||
|
response.status === 422
|
||||||
|
) {
|
||||||
|
if (log_lvl)
|
||||||
|
console.error(
|
||||||
|
`API Client Failure (${response.status}). Failing fast.`
|
||||||
|
);
|
||||||
|
|
||||||
if (response.status === 401 || response.status === 403) {
|
if (response.status === 401 || response.status === 403) {
|
||||||
console.warn(`AUTH DIAGNOSTICS: Headers sent for ${endpoint}:`, {
|
console.warn(
|
||||||
has_auth: !!headers_cleaned['Authorization'],
|
`AUTH DIAGNOSTICS: Headers sent for ${endpoint}:`,
|
||||||
has_api_key: !!headers_cleaned['x-aether-api-key'],
|
{
|
||||||
has_account_id: !!headers_cleaned['x-account-id'],
|
has_auth: !!headers_cleaned['Authorization'],
|
||||||
jwt_preview: jwt ? `${jwt.slice(0, 8)}...` : 'MISSING'
|
has_api_key:
|
||||||
});
|
!!headers_cleaned['x-aether-api-key'],
|
||||||
|
has_account_id:
|
||||||
|
!!headers_cleaned['x-account-id'],
|
||||||
|
jwt_preview: jwt
|
||||||
|
? `${jwt.slice(0, 8)}...`
|
||||||
|
: 'MISSING'
|
||||||
|
}
|
||||||
|
);
|
||||||
// Signal the root layout to show the session-expired banner.
|
// Signal the root layout to show the session-expired banner.
|
||||||
if (browser) ae_auth_error.set({ type: 'expired', ts: Date.now() });
|
if (browser)
|
||||||
|
ae_auth_error.set({
|
||||||
|
type: 'expired',
|
||||||
|
ts: Date.now()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Structured Error Handling (V3): Attempt to get rich error metadata
|
// Structured Error Handling (V3): Attempt to get rich error metadata
|
||||||
@@ -259,7 +316,11 @@ export const get_object = async function get_object({
|
|||||||
// Not JSON
|
// Not JSON
|
||||||
}
|
}
|
||||||
|
|
||||||
if (log_lvl) console.log('The response was not ok. Structured Error Check:', error_json);
|
if (log_lvl)
|
||||||
|
console.log(
|
||||||
|
'The response was not ok. Structured Error Check:',
|
||||||
|
error_json
|
||||||
|
);
|
||||||
|
|
||||||
if (error_json?.meta?.details) {
|
if (error_json?.meta?.details) {
|
||||||
return error_json;
|
return error_json;
|
||||||
@@ -273,7 +334,10 @@ export const get_object = async function get_object({
|
|||||||
status_code: response.status,
|
status_code: response.status,
|
||||||
details: {
|
details: {
|
||||||
category: 'validation',
|
category: 'validation',
|
||||||
message: typeof error_json.detail === 'string' ? error_json.detail : JSON.stringify(error_json.detail),
|
message:
|
||||||
|
typeof error_json.detail === 'string'
|
||||||
|
? error_json.detail
|
||||||
|
: JSON.stringify(error_json.detail),
|
||||||
raw: error_json.detail
|
raw: error_json.detail
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -307,7 +371,9 @@ export const get_object = async function get_object({
|
|||||||
chunks.push(value);
|
chunks.push(value);
|
||||||
receivedLength += value.length;
|
receivedLength += value.length;
|
||||||
|
|
||||||
const percent_completed = Math.round((receivedLength * 100) / contentLength);
|
const percent_completed = Math.round(
|
||||||
|
(receivedLength * 100) / contentLength
|
||||||
|
);
|
||||||
if (log_lvl > 1) {
|
if (log_lvl > 1) {
|
||||||
console.log(
|
console.log(
|
||||||
'GET Blob Progress:',
|
'GET Blob Progress:',
|
||||||
@@ -359,7 +425,10 @@ export const get_object = async function get_object({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(`API GET object request *fetch* error on attempt ${attempt}:`, error);
|
console.log(
|
||||||
|
`API GET object request *fetch* error on attempt ${attempt}:`,
|
||||||
|
error
|
||||||
|
);
|
||||||
|
|
||||||
if (attempt === retry_count) {
|
if (attempt === retry_count) {
|
||||||
console.log('Max retry attempts reached. Returning false.');
|
console.log('Max retry attempts reached. Returning false.');
|
||||||
|
|||||||
@@ -45,7 +45,9 @@ export const patch_object = async function patch_object({
|
|||||||
// Construct the URL with query parameters
|
// Construct the URL with query parameters
|
||||||
const url = new URL(endpoint, api_cfg['base_url']);
|
const url = new URL(endpoint, api_cfg['base_url']);
|
||||||
if (params) {
|
if (params) {
|
||||||
Object.keys(params).forEach((key) => url.searchParams.append(key, params[key]));
|
Object.keys(params).forEach((key) =>
|
||||||
|
url.searchParams.append(key, params[key])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean and merge headers without mutating the original api_cfg
|
// Clean and merge headers without mutating the original api_cfg
|
||||||
@@ -75,14 +77,19 @@ export const patch_object = async function patch_object({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle "Bootstrap Paradox" for unauthenticated requests
|
// Handle "Bootstrap Paradox" for unauthenticated requests
|
||||||
const bypass_val = merged_headers['x-no-account-id'] || merged_headers['x_no_account_id'];
|
const bypass_val =
|
||||||
const is_valid_bypass = bypass_val === 'bypass' ||
|
merged_headers['x-no-account-id'] || merged_headers['x_no_account_id'];
|
||||||
bypass_val === 'Nothing to See Here' ||
|
const is_valid_bypass =
|
||||||
params['key'] ||
|
bypass_val === 'bypass' ||
|
||||||
bypass_val === 'direct-download';
|
bypass_val === 'Nothing to See Here' ||
|
||||||
|
params['key'] ||
|
||||||
|
bypass_val === 'direct-download';
|
||||||
|
|
||||||
if (is_valid_bypass) {
|
if (is_valid_bypass) {
|
||||||
if (log_lvl > 1) console.log('api_patch_object: Valid bypass detected. Stripping account ID context.');
|
if (log_lvl > 1)
|
||||||
|
console.log(
|
||||||
|
'api_patch_object: Valid bypass detected. Stripping account ID context.'
|
||||||
|
);
|
||||||
delete merged_headers['x-account-id'];
|
delete merged_headers['x-account-id'];
|
||||||
delete merged_headers['x_account_id'];
|
delete merged_headers['x_account_id'];
|
||||||
} else {
|
} else {
|
||||||
@@ -104,11 +111,12 @@ export const patch_object = async function patch_object({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Auto-inject Authorization header if JWT is present but header is missing
|
// Auto-inject Authorization header if JWT is present but header is missing
|
||||||
let jwt = headers_cleaned['jwt'] ||
|
let jwt =
|
||||||
headers_cleaned['JWT'] ||
|
headers_cleaned['jwt'] ||
|
||||||
api_cfg['jwt'] ||
|
headers_cleaned['JWT'] ||
|
||||||
api_cfg['headers']?.['jwt'] ||
|
api_cfg['jwt'] ||
|
||||||
api_cfg['headers']?.['JWT'];
|
api_cfg['headers']?.['jwt'] ||
|
||||||
|
api_cfg['headers']?.['JWT'];
|
||||||
|
|
||||||
// Final Fallback: Direct check of primary ae_loc key
|
// Final Fallback: Direct check of primary ae_loc key
|
||||||
if (!jwt && typeof localStorage !== 'undefined') {
|
if (!jwt && typeof localStorage !== 'undefined') {
|
||||||
@@ -123,7 +131,11 @@ export const patch_object = async function patch_object({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (jwt && !headers_cleaned['Authorization'] && !headers_cleaned['authorization']) {
|
if (
|
||||||
|
jwt &&
|
||||||
|
!headers_cleaned['Authorization'] &&
|
||||||
|
!headers_cleaned['authorization']
|
||||||
|
) {
|
||||||
headers_cleaned['Authorization'] = `Bearer ${jwt}`;
|
headers_cleaned['Authorization'] = `Bearer ${jwt}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,7 +157,9 @@ export const patch_object = async function patch_object({
|
|||||||
try {
|
try {
|
||||||
const controller = new AbortController();
|
const controller = new AbortController();
|
||||||
const timeoutId = setTimeout(() => {
|
const timeoutId = setTimeout(() => {
|
||||||
console.error(`API PATCH request timed out after ${timeout}ms.`);
|
console.error(
|
||||||
|
`API PATCH request timed out after ${timeout}ms.`
|
||||||
|
);
|
||||||
controller.abort();
|
controller.abort();
|
||||||
}, timeout);
|
}, timeout);
|
||||||
|
|
||||||
@@ -156,9 +170,10 @@ export const patch_object = async function patch_object({
|
|||||||
signal: controller.signal
|
signal: controller.signal
|
||||||
};
|
};
|
||||||
|
|
||||||
const response = await fetch_method(url.toString(), fetchOptions).catch(function (
|
const response = await fetch_method(
|
||||||
error: any
|
url.toString(),
|
||||||
) {
|
fetchOptions
|
||||||
|
).catch(function (error: any) {
|
||||||
console.log(
|
console.log(
|
||||||
'API PATCH Object *fetch* request was aborted or failed in an unexpected way.',
|
'API PATCH Object *fetch* request was aborted or failed in an unexpected way.',
|
||||||
error
|
error
|
||||||
@@ -173,30 +188,53 @@ export const patch_object = async function patch_object({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`Response: status=${response.status} attempt=${attempt}`);
|
console.log(
|
||||||
|
`Response: status=${response.status} attempt=${attempt}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
if (response.status === 404) {
|
if (response.status === 404) {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log('The response was a 404 not found "error". Returning null.');
|
console.log(
|
||||||
|
'The response was a 404 not found "error". Returning null.'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FAIL FAST (Section 2D): Do not retry on Auth or Client errors (400, 401, 403, 422)
|
// FAIL FAST (Section 2D): Do not retry on Auth or Client errors (400, 401, 403, 422)
|
||||||
if (response.status === 400 || response.status === 401 || response.status === 403 || response.status === 422) {
|
if (
|
||||||
if (log_lvl) console.error(`API Client Failure (${response.status}). Failing fast.`);
|
response.status === 400 ||
|
||||||
|
response.status === 401 ||
|
||||||
|
response.status === 403 ||
|
||||||
|
response.status === 422
|
||||||
|
) {
|
||||||
|
if (log_lvl)
|
||||||
|
console.error(
|
||||||
|
`API Client Failure (${response.status}). Failing fast.`
|
||||||
|
);
|
||||||
|
|
||||||
if (response.status === 401 || response.status === 403) {
|
if (response.status === 401 || response.status === 403) {
|
||||||
console.warn(`AUTH DIAGNOSTICS (PATCH): Headers sent for ${endpoint}:`, {
|
console.warn(
|
||||||
has_auth: !!headers_cleaned['Authorization'],
|
`AUTH DIAGNOSTICS (PATCH): Headers sent for ${endpoint}:`,
|
||||||
has_api_key: !!headers_cleaned['x-aether-api-key'],
|
{
|
||||||
has_account_id: !!headers_cleaned['x-account-id'],
|
has_auth: !!headers_cleaned['Authorization'],
|
||||||
jwt_preview: jwt ? `${jwt.slice(0, 8)}...` : 'MISSING'
|
has_api_key:
|
||||||
});
|
!!headers_cleaned['x-aether-api-key'],
|
||||||
|
has_account_id:
|
||||||
|
!!headers_cleaned['x-account-id'],
|
||||||
|
jwt_preview: jwt
|
||||||
|
? `${jwt.slice(0, 8)}...`
|
||||||
|
: 'MISSING'
|
||||||
|
}
|
||||||
|
);
|
||||||
// Signal the root layout to show the session-expired banner.
|
// Signal the root layout to show the session-expired banner.
|
||||||
if (browser) ae_auth_error.set({ type: 'expired', ts: Date.now() });
|
if (browser)
|
||||||
|
ae_auth_error.set({
|
||||||
|
type: 'expired',
|
||||||
|
ts: Date.now()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Structured Error Handling (V3): Attempt to get rich error metadata
|
// Structured Error Handling (V3): Attempt to get rich error metadata
|
||||||
@@ -207,7 +245,11 @@ export const patch_object = async function patch_object({
|
|||||||
// Not JSON
|
// Not JSON
|
||||||
}
|
}
|
||||||
|
|
||||||
if (log_lvl) console.log('The response was not ok. Structured Error Check:', error_json);
|
if (log_lvl)
|
||||||
|
console.log(
|
||||||
|
'The response was not ok. Structured Error Check:',
|
||||||
|
error_json
|
||||||
|
);
|
||||||
|
|
||||||
if (error_json?.meta?.details) {
|
if (error_json?.meta?.details) {
|
||||||
return error_json;
|
return error_json;
|
||||||
@@ -221,7 +263,10 @@ export const patch_object = async function patch_object({
|
|||||||
status_code: response.status,
|
status_code: response.status,
|
||||||
details: {
|
details: {
|
||||||
category: 'validation',
|
category: 'validation',
|
||||||
message: typeof error_json.detail === 'string' ? error_json.detail : JSON.stringify(error_json.detail),
|
message:
|
||||||
|
typeof error_json.detail === 'string'
|
||||||
|
? error_json.detail
|
||||||
|
: JSON.stringify(error_json.detail),
|
||||||
raw: error_json.detail
|
raw: error_json.detail
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -242,7 +287,11 @@ export const patch_object = async function patch_object({
|
|||||||
|
|
||||||
// Return the response data or metadata
|
// Return the response data or metadata
|
||||||
// Robustly handle V3 response envelopes
|
// Robustly handle V3 response envelopes
|
||||||
return return_meta ? json : (json.data !== undefined ? json.data : json);
|
return return_meta
|
||||||
|
? json
|
||||||
|
: json.data !== undefined
|
||||||
|
? json.data
|
||||||
|
: json;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`API PATCH error on attempt ${attempt}:`, error);
|
console.error(`API PATCH error on attempt ${attempt}:`, error);
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,11 @@ export async function create_ae_obj({
|
|||||||
// Standard Aether Pattern: Auto-serialize any key ending in _json
|
// Standard Aether Pattern: Auto-serialize any key ending in _json
|
||||||
const cleaned_fields = { ...fields };
|
const cleaned_fields = { ...fields };
|
||||||
for (const key in cleaned_fields) {
|
for (const key in cleaned_fields) {
|
||||||
if (key.endsWith('_json') && cleaned_fields[key] !== null && typeof cleaned_fields[key] === 'object') {
|
if (
|
||||||
|
key.endsWith('_json') &&
|
||||||
|
cleaned_fields[key] !== null &&
|
||||||
|
typeof cleaned_fields[key] === 'object'
|
||||||
|
) {
|
||||||
if (log_lvl) console.log(`Auto-serializing field: ${key}`);
|
if (log_lvl) console.log(`Auto-serializing field: ${key}`);
|
||||||
cleaned_fields[key] = JSON.stringify(cleaned_fields[key]);
|
cleaned_fields[key] = JSON.stringify(cleaned_fields[key]);
|
||||||
}
|
}
|
||||||
@@ -94,7 +98,11 @@ export async function create_nested_obj({
|
|||||||
// Standard Aether Pattern: Auto-serialize any key ending in _json
|
// Standard Aether Pattern: Auto-serialize any key ending in _json
|
||||||
const cleaned_fields = { ...fields };
|
const cleaned_fields = { ...fields };
|
||||||
for (const key in cleaned_fields) {
|
for (const key in cleaned_fields) {
|
||||||
if (key.endsWith('_json') && cleaned_fields[key] !== null && typeof cleaned_fields[key] === 'object') {
|
if (
|
||||||
|
key.endsWith('_json') &&
|
||||||
|
cleaned_fields[key] !== null &&
|
||||||
|
typeof cleaned_fields[key] === 'object'
|
||||||
|
) {
|
||||||
cleaned_fields[key] = JSON.stringify(cleaned_fields[key]);
|
cleaned_fields[key] = JSON.stringify(cleaned_fields[key]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -140,7 +148,11 @@ export async function update_ae_obj({
|
|||||||
// Standard Aether Pattern: Auto-serialize any key ending in _json
|
// Standard Aether Pattern: Auto-serialize any key ending in _json
|
||||||
const cleaned_fields = { ...fields };
|
const cleaned_fields = { ...fields };
|
||||||
for (const key in cleaned_fields) {
|
for (const key in cleaned_fields) {
|
||||||
if (key.endsWith('_json') && cleaned_fields[key] !== null && typeof cleaned_fields[key] === 'object') {
|
if (
|
||||||
|
key.endsWith('_json') &&
|
||||||
|
cleaned_fields[key] !== null &&
|
||||||
|
typeof cleaned_fields[key] === 'object'
|
||||||
|
) {
|
||||||
if (log_lvl > 1) console.log(`Auto-serializing field: ${key}`);
|
if (log_lvl > 1) console.log(`Auto-serializing field: ${key}`);
|
||||||
cleaned_fields[key] = JSON.stringify(cleaned_fields[key]);
|
cleaned_fields[key] = JSON.stringify(cleaned_fields[key]);
|
||||||
}
|
}
|
||||||
@@ -202,7 +214,11 @@ export async function update_nested_obj({
|
|||||||
// Standard Aether Pattern: Auto-serialize any key ending in _json
|
// Standard Aether Pattern: Auto-serialize any key ending in _json
|
||||||
const cleaned_fields = { ...fields };
|
const cleaned_fields = { ...fields };
|
||||||
for (const key in cleaned_fields) {
|
for (const key in cleaned_fields) {
|
||||||
if (key.endsWith('_json') && cleaned_fields[key] !== null && typeof cleaned_fields[key] === 'object') {
|
if (
|
||||||
|
key.endsWith('_json') &&
|
||||||
|
cleaned_fields[key] !== null &&
|
||||||
|
typeof cleaned_fields[key] === 'object'
|
||||||
|
) {
|
||||||
cleaned_fields[key] = JSON.stringify(cleaned_fields[key]);
|
cleaned_fields[key] = JSON.stringify(cleaned_fields[key]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,10 @@ interface SearchAeObjV3Params {
|
|||||||
view?: string;
|
view?: string;
|
||||||
for_obj_type?: string;
|
for_obj_type?: string;
|
||||||
for_obj_id?: string;
|
for_obj_id?: string;
|
||||||
order_by_li?: Record<string, 'ASC' | 'DESC'> | Record<string, 'ASC' | 'DESC'>[] | null;
|
order_by_li?:
|
||||||
|
| Record<string, 'ASC' | 'DESC'>
|
||||||
|
| Record<string, 'ASC' | 'DESC'>[]
|
||||||
|
| null;
|
||||||
limit?: number;
|
limit?: number;
|
||||||
offset?: number;
|
offset?: number;
|
||||||
delay_ms?: number;
|
delay_ms?: number;
|
||||||
@@ -55,7 +58,10 @@ export async function search_ae_obj({
|
|||||||
|
|
||||||
// Serialize any complex objects in the query params (e.g. ft_qry, lk_qry)
|
// Serialize any complex objects in the query params (e.g. ft_qry, lk_qry)
|
||||||
for (const key in query_params) {
|
for (const key in query_params) {
|
||||||
if (typeof query_params[key] === 'object' && query_params[key] !== null) {
|
if (
|
||||||
|
typeof query_params[key] === 'object' &&
|
||||||
|
query_params[key] !== null
|
||||||
|
) {
|
||||||
query_params[key] = JSON.stringify(query_params[key]);
|
query_params[key] = JSON.stringify(query_params[key]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,9 @@ export const post_object = async function post_object({
|
|||||||
retry_count?: number;
|
retry_count?: number;
|
||||||
}) {
|
}) {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** post_object() *** Endpoint: ${endpoint} Task ID: ${task_id}`);
|
console.log(
|
||||||
|
`*** post_object() *** Endpoint: ${endpoint} Task ID: ${task_id}`
|
||||||
|
);
|
||||||
console.log('Params:', params);
|
console.log('Params:', params);
|
||||||
if (log_lvl > 1) {
|
if (log_lvl > 1) {
|
||||||
console.log('Data:', data);
|
console.log('Data:', data);
|
||||||
@@ -65,7 +67,9 @@ export const post_object = async function post_object({
|
|||||||
// Construct the URL with query parameters
|
// Construct the URL with query parameters
|
||||||
const url = new URL(endpoint, api_cfg['base_url']);
|
const url = new URL(endpoint, api_cfg['base_url']);
|
||||||
if (params) {
|
if (params) {
|
||||||
Object.keys(params).forEach((key) => url.searchParams.append(key, params[key]));
|
Object.keys(params).forEach((key) =>
|
||||||
|
url.searchParams.append(key, params[key])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean and merge headers
|
// Clean and merge headers
|
||||||
@@ -95,14 +99,19 @@ export const post_object = async function post_object({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle "Bootstrap Paradox" for unauthenticated requests
|
// Handle "Bootstrap Paradox" for unauthenticated requests
|
||||||
const bypass_val = merged_headers['x-no-account-id'] || merged_headers['x_no_account_id'];
|
const bypass_val =
|
||||||
const is_valid_bypass = bypass_val === 'bypass' ||
|
merged_headers['x-no-account-id'] || merged_headers['x_no_account_id'];
|
||||||
bypass_val === 'Nothing to See Here' ||
|
const is_valid_bypass =
|
||||||
params['key'] ||
|
bypass_val === 'bypass' ||
|
||||||
bypass_val === 'direct-download';
|
bypass_val === 'Nothing to See Here' ||
|
||||||
|
params['key'] ||
|
||||||
|
bypass_val === 'direct-download';
|
||||||
|
|
||||||
if (is_valid_bypass) {
|
if (is_valid_bypass) {
|
||||||
if (log_lvl > 1) console.log('api_post_object: Valid bypass detected. Stripping account ID context.');
|
if (log_lvl > 1)
|
||||||
|
console.log(
|
||||||
|
'api_post_object: Valid bypass detected. Stripping account ID context.'
|
||||||
|
);
|
||||||
delete merged_headers['x-account-id'];
|
delete merged_headers['x-account-id'];
|
||||||
delete merged_headers['x_account_id'];
|
delete merged_headers['x_account_id'];
|
||||||
} else {
|
} else {
|
||||||
@@ -124,11 +133,12 @@ export const post_object = async function post_object({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Auto-inject Authorization header if JWT is present but header is missing
|
// Auto-inject Authorization header if JWT is present but header is missing
|
||||||
let jwt = headers_cleaned['jwt'] ||
|
let jwt =
|
||||||
headers_cleaned['JWT'] ||
|
headers_cleaned['jwt'] ||
|
||||||
api_cfg['jwt'] ||
|
headers_cleaned['JWT'] ||
|
||||||
api_cfg['headers']?.['jwt'] ||
|
api_cfg['jwt'] ||
|
||||||
api_cfg['headers']?.['JWT'];
|
api_cfg['headers']?.['jwt'] ||
|
||||||
|
api_cfg['headers']?.['JWT'];
|
||||||
|
|
||||||
// Final Fallback: Direct check of primary ae_loc key
|
// Final Fallback: Direct check of primary ae_loc key
|
||||||
if (!jwt && typeof localStorage !== 'undefined') {
|
if (!jwt && typeof localStorage !== 'undefined') {
|
||||||
@@ -143,7 +153,11 @@ export const post_object = async function post_object({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (jwt && !headers_cleaned['Authorization'] && !headers_cleaned['authorization']) {
|
if (
|
||||||
|
jwt &&
|
||||||
|
!headers_cleaned['Authorization'] &&
|
||||||
|
!headers_cleaned['authorization']
|
||||||
|
) {
|
||||||
headers_cleaned['Authorization'] = `Bearer ${jwt}`;
|
headers_cleaned['Authorization'] = `Bearer ${jwt}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,13 +200,21 @@ export const post_object = async function post_object({
|
|||||||
console.log('Fetch Options:', fetchOptions);
|
console.log('Fetch Options:', fetchOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await fetch_method(url.toString(), fetchOptions).catch(function (
|
const response = await fetch_method(
|
||||||
error: any
|
url.toString(),
|
||||||
) {
|
fetchOptions
|
||||||
|
).catch(function (error: any) {
|
||||||
// SILENCE NOISE: Aborted requests shouldn't spam logs at log_lvl 0
|
// SILENCE NOISE: Aborted requests shouldn't spam logs at log_lvl 0
|
||||||
if (error.name === 'AbortError' || error.message?.includes('aborted') || error.name === 'TypeError') {
|
if (
|
||||||
|
error.name === 'AbortError' ||
|
||||||
|
error.message?.includes('aborted') ||
|
||||||
|
error.name === 'TypeError'
|
||||||
|
) {
|
||||||
if (log_lvl > 1) {
|
if (log_lvl > 1) {
|
||||||
console.log('API POST: Request was aborted or terminated by browser. Expected during navigation.', error);
|
console.log(
|
||||||
|
'API POST: Request was aborted or terminated by browser. Expected during navigation.',
|
||||||
|
error
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
@@ -206,9 +228,17 @@ export const post_object = async function post_object({
|
|||||||
clearTimeout(timeoutId);
|
clearTimeout(timeoutId);
|
||||||
|
|
||||||
// Check if we should stop due to abort or network failure
|
// Check if we should stop due to abort or network failure
|
||||||
if (response instanceof Error || (response && (response.name === 'TypeError' || response.name === 'AbortError'))) {
|
if (
|
||||||
|
response instanceof Error ||
|
||||||
|
(response &&
|
||||||
|
(response.name === 'TypeError' ||
|
||||||
|
response.name === 'AbortError'))
|
||||||
|
) {
|
||||||
if (response.name === 'AbortError') return false;
|
if (response.name === 'AbortError') return false;
|
||||||
if (log_lvl > 1) console.log('API POST Object: Detected NetworkError or TypeError. Failing fast.');
|
if (log_lvl > 1)
|
||||||
|
console.log(
|
||||||
|
'API POST Object: Detected NetworkError or TypeError. Failing fast.'
|
||||||
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,30 +249,53 @@ export const post_object = async function post_object({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`Response: status=${response.status} attempt=${attempt}`);
|
console.log(
|
||||||
|
`Response: status=${response.status} attempt=${attempt}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
if (response.status === 404) {
|
if (response.status === 404) {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log('The response was a 404 not found "error". Returning null.');
|
console.log(
|
||||||
|
'The response was a 404 not found "error". Returning null.'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FAIL FAST (Section 2D): Do not retry on Auth or Client errors (400, 401, 403, 422)
|
// FAIL FAST (Section 2D): Do not retry on Auth or Client errors (400, 401, 403, 422)
|
||||||
if (response.status === 400 || response.status === 401 || response.status === 403 || response.status === 422) {
|
if (
|
||||||
if (log_lvl) console.error(`API Client Failure (${response.status}). Failing fast.`);
|
response.status === 400 ||
|
||||||
|
response.status === 401 ||
|
||||||
|
response.status === 403 ||
|
||||||
|
response.status === 422
|
||||||
|
) {
|
||||||
|
if (log_lvl)
|
||||||
|
console.error(
|
||||||
|
`API Client Failure (${response.status}). Failing fast.`
|
||||||
|
);
|
||||||
|
|
||||||
if (response.status === 401 || response.status === 403) {
|
if (response.status === 401 || response.status === 403) {
|
||||||
console.warn(`AUTH DIAGNOSTICS (POST): Headers sent for ${endpoint}:`, {
|
console.warn(
|
||||||
has_auth: !!headers_cleaned['Authorization'],
|
`AUTH DIAGNOSTICS (POST): Headers sent for ${endpoint}:`,
|
||||||
has_api_key: !!headers_cleaned['x-aether-api-key'],
|
{
|
||||||
has_account_id: !!headers_cleaned['x-account-id'],
|
has_auth: !!headers_cleaned['Authorization'],
|
||||||
jwt_preview: jwt ? `${jwt.slice(0, 8)}...` : 'MISSING'
|
has_api_key:
|
||||||
});
|
!!headers_cleaned['x-aether-api-key'],
|
||||||
|
has_account_id:
|
||||||
|
!!headers_cleaned['x-account-id'],
|
||||||
|
jwt_preview: jwt
|
||||||
|
? `${jwt.slice(0, 8)}...`
|
||||||
|
: 'MISSING'
|
||||||
|
}
|
||||||
|
);
|
||||||
// Signal the root layout to show the session-expired banner.
|
// Signal the root layout to show the session-expired banner.
|
||||||
if (browser) ae_auth_error.set({ type: 'expired', ts: Date.now() });
|
if (browser)
|
||||||
|
ae_auth_error.set({
|
||||||
|
type: 'expired',
|
||||||
|
ts: Date.now()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Structured Error Handling (V3): Attempt to get rich error metadata
|
// Structured Error Handling (V3): Attempt to get rich error metadata
|
||||||
@@ -253,7 +306,11 @@ export const post_object = async function post_object({
|
|||||||
// Not JSON
|
// Not JSON
|
||||||
}
|
}
|
||||||
|
|
||||||
if (log_lvl) console.log('The response was not ok. Structured Error Check:', error_json);
|
if (log_lvl)
|
||||||
|
console.log(
|
||||||
|
'The response was not ok. Structured Error Check:',
|
||||||
|
error_json
|
||||||
|
);
|
||||||
|
|
||||||
if (error_json?.meta?.details) {
|
if (error_json?.meta?.details) {
|
||||||
return error_json;
|
return error_json;
|
||||||
@@ -267,7 +324,10 @@ export const post_object = async function post_object({
|
|||||||
status_code: response.status,
|
status_code: response.status,
|
||||||
details: {
|
details: {
|
||||||
category: 'validation',
|
category: 'validation',
|
||||||
message: typeof error_json.detail === 'string' ? error_json.detail : JSON.stringify(error_json.detail),
|
message:
|
||||||
|
typeof error_json.detail === 'string'
|
||||||
|
? error_json.detail
|
||||||
|
: JSON.stringify(error_json.detail),
|
||||||
raw: error_json.detail
|
raw: error_json.detail
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -311,7 +371,11 @@ export const post_object = async function post_object({
|
|||||||
|
|
||||||
// Return the response data or metadata
|
// Return the response data or metadata
|
||||||
// Robustly handle V3 response envelopes
|
// Robustly handle V3 response envelopes
|
||||||
return return_meta ? json : (json.data !== undefined ? json.data : json);
|
return return_meta
|
||||||
|
? json
|
||||||
|
: json.data !== undefined
|
||||||
|
? json.data
|
||||||
|
: json;
|
||||||
} else {
|
} else {
|
||||||
const blob = await response.blob();
|
const blob = await response.blob();
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,9 @@ export async function load_ae_obj_id__archive({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_Archive | null> {
|
}): Promise<ae_Archive | null> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** load_ae_obj_id__archive() *** archive_id=${archive_id}`);
|
console.log(
|
||||||
|
`*** load_ae_obj_id__archive() *** archive_id=${archive_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ae_promises.load__archive_obj = await api
|
ae_promises.load__archive_obj = await api
|
||||||
@@ -52,10 +54,11 @@ export async function load_ae_obj_id__archive({
|
|||||||
.then(async function (archive_obj_get_result) {
|
.then(async function (archive_obj_get_result) {
|
||||||
if (archive_obj_get_result) {
|
if (archive_obj_get_result) {
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
const processed_obj_li = await process_ae_obj__archive_props({
|
const processed_obj_li =
|
||||||
obj_li: [archive_obj_get_result],
|
await process_ae_obj__archive_props({
|
||||||
log_lvl: log_lvl
|
obj_li: [archive_obj_get_result],
|
||||||
});
|
log_lvl: log_lvl
|
||||||
|
});
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
db_instance: db_archives,
|
db_instance: db_archives,
|
||||||
table_name: 'archive',
|
table_name: 'archive',
|
||||||
@@ -76,19 +79,21 @@ export async function load_ae_obj_id__archive({
|
|||||||
|
|
||||||
if (inc_content_li && ae_promises.load__archive_obj) {
|
if (inc_content_li && ae_promises.load__archive_obj) {
|
||||||
// Load the contents for the archive
|
// Load the contents for the archive
|
||||||
const load_archive_content_obj_li = await load_ae_obj_li__archive_content({
|
const load_archive_content_obj_li =
|
||||||
api_cfg: api_cfg,
|
await load_ae_obj_li__archive_content({
|
||||||
for_obj_type: 'archive',
|
api_cfg: api_cfg,
|
||||||
for_obj_id: archive_id,
|
for_obj_type: 'archive',
|
||||||
enabled: enabled,
|
for_obj_id: archive_id,
|
||||||
hidden: hidden,
|
enabled: enabled,
|
||||||
limit: limit,
|
hidden: hidden,
|
||||||
offset: offset,
|
limit: limit,
|
||||||
params: params,
|
offset: offset,
|
||||||
try_cache: try_cache,
|
params: params,
|
||||||
log_lvl: log_lvl
|
try_cache: try_cache,
|
||||||
});
|
log_lvl: log_lvl
|
||||||
ae_promises.load__archive_obj.archive_content_li = load_archive_content_obj_li;
|
});
|
||||||
|
ae_promises.load__archive_obj.archive_content_li =
|
||||||
|
load_archive_content_obj_li;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ae_promises.load__archive_obj;
|
return ae_promises.load__archive_obj;
|
||||||
@@ -125,7 +130,9 @@ export async function load_ae_obj_li__archive({
|
|||||||
view?: string;
|
view?: string;
|
||||||
limit?: number;
|
limit?: number;
|
||||||
offset?: number;
|
offset?: number;
|
||||||
order_by_li?: Record<string, 'ASC' | 'DESC'> | Record<string, 'ASC' | 'DESC'>[];
|
order_by_li?:
|
||||||
|
| Record<string, 'ASC' | 'DESC'>
|
||||||
|
| Record<string, 'ASC' | 'DESC'>[];
|
||||||
params?: key_val;
|
params?: key_val;
|
||||||
try_cache?: boolean;
|
try_cache?: boolean;
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
@@ -138,7 +145,9 @@ export async function load_ae_obj_li__archive({
|
|||||||
|
|
||||||
// DEBUG: Trace massive content loads
|
// DEBUG: Trace massive content loads
|
||||||
if (inc_content_li) {
|
if (inc_content_li) {
|
||||||
console.warn(`load_ae_obj_li__archive: Loading content for ALL archives in list! Limit: ${limit}`);
|
console.warn(
|
||||||
|
`load_ae_obj_li__archive: Loading content for ALL archives in list! Limit: ${limit}`
|
||||||
|
);
|
||||||
// console.trace();
|
// console.trace();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,10 +168,11 @@ export async function load_ae_obj_li__archive({
|
|||||||
.then(async function (archive_obj_li_get_result) {
|
.then(async function (archive_obj_li_get_result) {
|
||||||
if (archive_obj_li_get_result) {
|
if (archive_obj_li_get_result) {
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
const processed_obj_li = await process_ae_obj__archive_props({
|
const processed_obj_li =
|
||||||
obj_li: archive_obj_li_get_result,
|
await process_ae_obj__archive_props({
|
||||||
log_lvl: log_lvl
|
obj_li: archive_obj_li_get_result,
|
||||||
});
|
log_lvl: log_lvl
|
||||||
|
});
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
db_instance: db_archives,
|
db_instance: db_archives,
|
||||||
table_name: 'archive',
|
table_name: 'archive',
|
||||||
@@ -220,7 +230,9 @@ export async function create_ae_obj__archive({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_Archive | null> {
|
}): Promise<ae_Archive | null> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** create_ae_obj__archive() *** account_id=${account_id}`);
|
console.log(
|
||||||
|
`*** create_ae_obj__archive() *** account_id=${account_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await api.create_ae_obj({
|
const result = await api.create_ae_obj({
|
||||||
@@ -268,7 +280,9 @@ export async function delete_ae_obj_id__archive({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}) {
|
}) {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** delete_ae_obj_id__archive() *** archive_id=${archive_id}`);
|
console.log(
|
||||||
|
`*** delete_ae_obj_id__archive() *** archive_id=${archive_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await api.delete_ae_obj({
|
const result = await api.delete_ae_obj({
|
||||||
@@ -304,7 +318,10 @@ export async function update_ae_obj__archive({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_Archive | null> {
|
}): Promise<ae_Archive | null> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** update_ae_obj__archive() *** archive_id=${archive_id}`, data_kv);
|
console.log(
|
||||||
|
`*** update_ae_obj__archive() *** archive_id=${archive_id}`,
|
||||||
|
data_kv
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await api.update_ae_obj({
|
const result = await api.update_ae_obj({
|
||||||
@@ -366,7 +383,11 @@ export async function qry__archive({
|
|||||||
const search_query: any = { and: [] };
|
const search_query: any = { and: [] };
|
||||||
|
|
||||||
if (account_id) {
|
if (account_id) {
|
||||||
search_query.and.push({ field: 'account_id_random', op: 'eq', value: account_id });
|
search_query.and.push({
|
||||||
|
field: 'account_id_random',
|
||||||
|
op: 'eq',
|
||||||
|
value: account_id
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qry_str) {
|
if (qry_str) {
|
||||||
@@ -452,11 +473,15 @@ async function _process_generic_props<T extends Record<string, any>>({
|
|||||||
const updated = processed_obj.updated_on ?? processed_obj.created_on;
|
const updated = processed_obj.updated_on ?? processed_obj.created_on;
|
||||||
const name = processed_obj.name ?? '';
|
const name = processed_obj.name ?? '';
|
||||||
|
|
||||||
(processed_obj as any).tmp_sort_1 = `${group}_${priority}_${sort}_${updated}`;
|
(processed_obj as any).tmp_sort_1 =
|
||||||
(processed_obj as any).tmp_sort_2 = `${group}_${priority}_${sort}_${name}_${updated}`;
|
`${group}_${priority}_${sort}_${updated}`;
|
||||||
|
(processed_obj as any).tmp_sort_2 =
|
||||||
|
`${group}_${priority}_${sort}_${name}_${updated}`;
|
||||||
|
|
||||||
if (specific_processor) {
|
if (specific_processor) {
|
||||||
processed_obj = await Promise.resolve(specific_processor(processed_obj));
|
processed_obj = await Promise.resolve(
|
||||||
|
specific_processor(processed_obj)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
processed_obj_li.push(processed_obj as T);
|
processed_obj_li.push(processed_obj as T);
|
||||||
|
|||||||
@@ -41,10 +41,11 @@ export async function load_ae_obj_id__archive_content({
|
|||||||
.then(async function (archive_content_obj_get_result) {
|
.then(async function (archive_content_obj_get_result) {
|
||||||
if (archive_content_obj_get_result) {
|
if (archive_content_obj_get_result) {
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
const processed_obj_li = await process_ae_obj__archive_content_props({
|
const processed_obj_li =
|
||||||
obj_li: [archive_content_obj_get_result],
|
await process_ae_obj__archive_content_props({
|
||||||
log_lvl: log_lvl
|
obj_li: [archive_content_obj_get_result],
|
||||||
});
|
log_lvl: log_lvl
|
||||||
|
});
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
db_instance: db_archives,
|
db_instance: db_archives,
|
||||||
table_name: 'content',
|
table_name: 'content',
|
||||||
@@ -96,7 +97,9 @@ export async function load_ae_obj_li__archive_content({
|
|||||||
view?: string;
|
view?: string;
|
||||||
limit?: number;
|
limit?: number;
|
||||||
offset?: number;
|
offset?: number;
|
||||||
order_by_li?: Record<string, 'ASC' | 'DESC'> | Record<string, 'ASC' | 'DESC'>[];
|
order_by_li?:
|
||||||
|
| Record<string, 'ASC' | 'DESC'>
|
||||||
|
| Record<string, 'ASC' | 'DESC'>[];
|
||||||
params?: key_val;
|
params?: key_val;
|
||||||
try_cache?: boolean;
|
try_cache?: boolean;
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
@@ -124,10 +127,11 @@ export async function load_ae_obj_li__archive_content({
|
|||||||
.then(async function (archive_content_obj_li_get_result) {
|
.then(async function (archive_content_obj_li_get_result) {
|
||||||
if (archive_content_obj_li_get_result) {
|
if (archive_content_obj_li_get_result) {
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
const processed_obj_li = await process_ae_obj__archive_content_props({
|
const processed_obj_li =
|
||||||
obj_li: archive_content_obj_li_get_result,
|
await process_ae_obj__archive_content_props({
|
||||||
log_lvl: log_lvl
|
obj_li: archive_content_obj_li_get_result,
|
||||||
});
|
log_lvl: log_lvl
|
||||||
|
});
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
db_instance: db_archives,
|
db_instance: db_archives,
|
||||||
table_name: 'content',
|
table_name: 'content',
|
||||||
@@ -162,11 +166,15 @@ export async function create_ae_obj__archive_content({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_ArchiveContent | null> {
|
}): Promise<ae_ArchiveContent | null> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** create_ae_obj__archive_content() *** archive_id=${archive_id}`);
|
console.log(
|
||||||
|
`*** create_ae_obj__archive_content() *** archive_id=${archive_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!archive_id) {
|
if (!archive_id) {
|
||||||
console.log(`ERROR: Archives - Content - archive_id required to create`);
|
console.log(
|
||||||
|
`ERROR: Archives - Content - archive_id required to create`
|
||||||
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,11 +365,15 @@ async function _process_generic_props<T extends Record<string, any>>({
|
|||||||
const updated = processed_obj.updated_on ?? processed_obj.created_on;
|
const updated = processed_obj.updated_on ?? processed_obj.created_on;
|
||||||
const name = processed_obj.name ?? '';
|
const name = processed_obj.name ?? '';
|
||||||
|
|
||||||
(processed_obj as any).tmp_sort_1 = `${group}_${priority}_${sort}_${updated}`;
|
(processed_obj as any).tmp_sort_1 =
|
||||||
(processed_obj as any).tmp_sort_2 = `${group}_${priority}_${sort}_${name}_${updated}`;
|
`${group}_${priority}_${sort}_${updated}`;
|
||||||
|
(processed_obj as any).tmp_sort_2 =
|
||||||
|
`${group}_${priority}_${sort}_${name}_${updated}`;
|
||||||
|
|
||||||
if (specific_processor) {
|
if (specific_processor) {
|
||||||
processed_obj = await Promise.resolve(specific_processor(processed_obj));
|
processed_obj = await Promise.resolve(
|
||||||
|
specific_processor(processed_obj)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
processed_obj_li.push(processed_obj as T);
|
processed_obj_li.push(processed_obj as T);
|
||||||
|
|||||||
@@ -1,188 +1,191 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
// Imports
|
// Imports
|
||||||
// Import components and elements
|
// Import components and elements
|
||||||
// import Element_input_files_tbl from '$lib/element_input_files_tbl.svelte';
|
// import Element_input_files_tbl from '$lib/element_input_files_tbl.svelte';
|
||||||
|
|
||||||
// Import storage, functions, and libraries
|
// Import storage, functions, and libraries
|
||||||
import type { key_val } from '$lib/stores/ae_stores';
|
import type { key_val } from '$lib/stores/ae_stores';
|
||||||
|
|
||||||
import { api } from '$lib/api/api';
|
import { api } from '$lib/api/api';
|
||||||
import { ae_util } from '$lib/ae_utils/ae_utils';
|
import { ae_util } from '$lib/ae_utils/ae_utils';
|
||||||
import {
|
import {
|
||||||
ae_snip,
|
ae_snip,
|
||||||
ae_loc,
|
ae_loc,
|
||||||
ae_sess,
|
ae_sess,
|
||||||
ae_api,
|
ae_api,
|
||||||
ae_trig,
|
ae_trig,
|
||||||
slct,
|
slct,
|
||||||
slct_trigger
|
slct_trigger
|
||||||
} from '$lib/stores/ae_stores';
|
} from '$lib/stores/ae_stores';
|
||||||
|
|
||||||
import AE_Comp_Hosted_Files_Download_Button from '$lib/ae_core/ae_comp__hosted_files_download_button.svelte';
|
import AE_Comp_Hosted_Files_Download_Button from '$lib/ae_core/ae_comp__hosted_files_download_button.svelte';
|
||||||
import { Check, Download, LoaderCircle, MinusCircle, Scissors } from '@lucide/svelte';
|
import {
|
||||||
// Exports
|
Check,
|
||||||
|
Download,
|
||||||
|
LoaderCircle,
|
||||||
|
MinusCircle,
|
||||||
|
Scissors
|
||||||
|
} from '@lucide/svelte';
|
||||||
|
// Exports
|
||||||
|
|
||||||
// export let input_name = 'file_list';
|
// export let input_name = 'file_list';
|
||||||
// export let multiple: boolean = true;
|
// export let multiple: boolean = true;
|
||||||
// export let required: boolean = true;
|
// export let required: boolean = true;
|
||||||
|
|
||||||
// export let input_class_li: string[] = ['file_drop_area'];
|
// export let input_class_li: string[] = ['file_drop_area'];
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
// Expecting these for link_to_type: 'event', 'event_location', 'archive_content', etc
|
// Expecting these for link_to_type: 'event', 'event_location', 'archive_content', etc
|
||||||
link_to_type: string;
|
link_to_type: string;
|
||||||
link_to_id: string;
|
link_to_id: string;
|
||||||
// export let accept: string = 'audio/*, image/*, video/*, .bak, .cfg, .css, .csv, .doc, .docx, .gz, .htm, .html, .ini, .iso, .j2, .json, .key, .keynote, .md, .pdf, .ppt, .pptx, .rar, .rtf, .sql, .svelte, ttf, .txt, .xls, .xlsx, .xz, .zip, .bin, .dmg, .exe, .js, .msi, .php, .py, .sh';
|
// export let accept: string = 'audio/*, image/*, video/*, .bak, .cfg, .css, .csv, .doc, .docx, .gz, .htm, .html, .ini, .iso, .j2, .json, .key, .keynote, .md, .pdf, .ppt, .pptx, .rar, .rtf, .sql, .svelte, ttf, .txt, .xls, .xlsx, .xz, .zip, .bin, .dmg, .exe, .js, .msi, .php, .py, .sh';
|
||||||
class_li_default?: string;
|
class_li_default?: string;
|
||||||
class_li?: string;
|
class_li?: string;
|
||||||
// export let table_class_li: string[] = ['table', 'table-sm', 'table-striped', 'table-hover' , 'text-sm'];
|
// export let table_class_li: string[] = ['table', 'table-sm', 'table-striped', 'table-hover' , 'text-sm'];
|
||||||
clip_complete?: boolean;
|
clip_complete?: boolean;
|
||||||
// export let upload_complete: boolean = false;
|
// export let upload_complete: boolean = false;
|
||||||
submit_status?: null | string;
|
submit_status?: null | string;
|
||||||
// hosted_file_id_li?: string[];
|
// hosted_file_id_li?: string[];
|
||||||
// hosted_file_obj_li?: any[];
|
// hosted_file_obj_li?: any[];
|
||||||
hosted_file_obj_kv?: key_val;
|
hosted_file_obj_kv?: key_val;
|
||||||
video_clip_file_kv?: key_val;
|
video_clip_file_kv?: key_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
let {
|
let {
|
||||||
log_lvl = $bindable(0),
|
log_lvl = $bindable(0),
|
||||||
link_to_type = $bindable(),
|
link_to_type = $bindable(),
|
||||||
link_to_id = $bindable(),
|
link_to_id = $bindable(),
|
||||||
class_li_default = 'flex flex-col gap-1 items-center justify-center w-full max-w-2xl mx-auto my-1',
|
class_li_default = 'flex flex-col gap-1 items-center justify-center w-full max-w-2xl mx-auto my-1',
|
||||||
class_li = $bindable(''),
|
class_li = $bindable(''),
|
||||||
clip_complete = $bindable(false),
|
clip_complete = $bindable(false),
|
||||||
submit_status = $bindable(null),
|
submit_status = $bindable(null),
|
||||||
// hosted_file_id_li = [],
|
// hosted_file_id_li = [],
|
||||||
// hosted_file_obj_li = [],
|
// hosted_file_obj_li = [],
|
||||||
hosted_file_obj_kv = $bindable({}),
|
hosted_file_obj_kv = $bindable({}),
|
||||||
video_clip_file_kv = $bindable({})
|
video_clip_file_kv = $bindable({})
|
||||||
}: Props = $props();
|
}: Props = $props();
|
||||||
|
|
||||||
// Local Variables
|
// Local Variables
|
||||||
let task_id = link_to_id;
|
let task_id = link_to_id;
|
||||||
// let input_file_list: any = null;
|
// let input_file_list: any = null;
|
||||||
let ae_promises: key_val = $state({});
|
let ae_promises: key_val = $state({});
|
||||||
// let ae_promises_clipping: key_val = {};
|
// let ae_promises_clipping: key_val = {};
|
||||||
// let ae_triggers: key_val = {};
|
// let ae_triggers: key_val = {};
|
||||||
|
|
||||||
// let input_element_id = 'ae_comp__hosted_files_upload__input';
|
// let input_element_id = 'ae_comp__hosted_files_upload__input';
|
||||||
|
|
||||||
// let form_kv: key_val = {
|
// let form_kv: key_val = {
|
||||||
// start_time: null,
|
// start_time: null,
|
||||||
// end_time: null,
|
// end_time: null,
|
||||||
// reencode: null,
|
// reencode: null,
|
||||||
// video_file: null,
|
// video_file: null,
|
||||||
// };
|
// };
|
||||||
// let download_clip_src: string;
|
// let download_clip_src: string;
|
||||||
// let download_clip_filename: string;
|
// let download_clip_filename: string;
|
||||||
|
|
||||||
$ae_sess.files.obj = {
|
$ae_sess.files.obj = {
|
||||||
obj: null
|
obj: null
|
||||||
|
};
|
||||||
|
|
||||||
|
// *** Functions and Logic
|
||||||
|
function prevent_default<T extends Event>(fn: (event: T) => void) {
|
||||||
|
return function (event: T) {
|
||||||
|
event.preventDefault();
|
||||||
|
fn(event);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function handle_clip_video(event: Event) {
|
||||||
|
console.log('*** handle_clip_video() ***');
|
||||||
|
|
||||||
|
submit_status = 'clipping';
|
||||||
|
clip_complete = false;
|
||||||
|
|
||||||
|
const form = event.target as HTMLFormElement;
|
||||||
|
const formData = new FormData(form);
|
||||||
|
|
||||||
|
let hosted_file_id = formData.get('hosted_file_id') as string;
|
||||||
|
let start_time = formData.get('start_time') as string;
|
||||||
|
let end_time = formData.get('end_time') as string;
|
||||||
|
let reencode = formData.get('reencode') as string;
|
||||||
|
let scale_down = formData.get('scale_down') as string;
|
||||||
|
let new_filename = formData.get('new_filename') as string;
|
||||||
|
|
||||||
|
$ae_sess.files.processed_file_kv[hosted_file_id] = {};
|
||||||
|
$ae_sess.files.processed_file_kv[hosted_file_id].submit_status = 'clipping';
|
||||||
|
$ae_sess.files.processed_file_kv[hosted_file_id].clip_complete = false;
|
||||||
|
|
||||||
|
// $ae_sess.files.disable_submit__hosted_file_obj = true;
|
||||||
|
$ae_loc.files.processed_file_kv[hosted_file_id] = {};
|
||||||
|
$ae_loc.files.processed_file_kv[hosted_file_id].submit_status = 'clipping';
|
||||||
|
$ae_loc.files.processed_file_kv[hosted_file_id].start_time = start_time;
|
||||||
|
$ae_loc.files.processed_file_kv[hosted_file_id].end_time = end_time;
|
||||||
|
$ae_loc.files.processed_file_kv[hosted_file_id].reencode = reencode;
|
||||||
|
$ae_loc.files.processed_file_kv[hosted_file_id].scale_down = scale_down;
|
||||||
|
$ae_loc.files.processed_file_kv[hosted_file_id].new_filename = new_filename;
|
||||||
|
$ae_loc.files.processed_file_kv[hosted_file_id].clip_complete = false;
|
||||||
|
|
||||||
|
let endpoint = `/hosted_file/${hosted_file_id}/clip_video`;
|
||||||
|
|
||||||
|
let params = {
|
||||||
|
link_to_type: link_to_type,
|
||||||
|
link_to_id: link_to_id,
|
||||||
|
filename_no_ext: new_filename.replace('.mp4', ''),
|
||||||
|
from_type: 'mp4', // Video file type being converted
|
||||||
|
to_type: 'mp4', // Video file type to convert to
|
||||||
|
start_time: start_time,
|
||||||
|
end_time: end_time,
|
||||||
|
reencode: reencode,
|
||||||
|
scale_down: scale_down
|
||||||
};
|
};
|
||||||
|
|
||||||
// *** Functions and Logic
|
ae_promises[hosted_file_id] = {};
|
||||||
function prevent_default<T extends Event>(fn: (event: T) => void) {
|
// .convert__hosted_file_obj
|
||||||
return function (event: T) {
|
ae_promises[hosted_file_id] = api
|
||||||
event.preventDefault();
|
.get_object({
|
||||||
fn(event);
|
api_cfg: $ae_api,
|
||||||
};
|
endpoint: endpoint,
|
||||||
}
|
params: params,
|
||||||
|
timeout: 300000, // 5 minutes
|
||||||
|
// return_blob: true,
|
||||||
|
// filename: event.target.new_filename.value,
|
||||||
|
// auto_download: false,
|
||||||
|
task_id: task_id,
|
||||||
|
log_lvl: log_lvl
|
||||||
|
})
|
||||||
|
.then(function (result) {
|
||||||
|
console.log(result);
|
||||||
|
|
||||||
function handle_clip_video(event: Event) {
|
video_clip_file_kv[result.hosted_file_id] = {};
|
||||||
console.log('*** handle_clip_video() ***');
|
video_clip_file_kv[result.hosted_file_id] = result;
|
||||||
|
|
||||||
submit_status = 'clipping';
|
// $ae_loc.files.video_clip_file_kv[result.hosted_file_id] = {};
|
||||||
clip_complete = false;
|
// $ae_loc.files.video_clip_file_kv[result.hosted_file_id] = result;
|
||||||
|
|
||||||
const form = event.target as HTMLFormElement;
|
$ae_sess.files.processed_file_kv[hosted_file_id].submit_status =
|
||||||
const formData = new FormData(form);
|
'clipped';
|
||||||
|
$ae_sess.files.processed_file_kv[hosted_file_id].clip_complete =
|
||||||
|
true;
|
||||||
|
|
||||||
let hosted_file_id = formData.get('hosted_file_id') as string;
|
$ae_loc.files.processed_file_kv[hosted_file_id].submit_status =
|
||||||
let start_time = formData.get('start_time') as string;
|
'clipped';
|
||||||
let end_time = formData.get('end_time') as string;
|
$ae_loc.files.processed_file_kv[hosted_file_id].clip_complete =
|
||||||
let reencode = formData.get('reencode') as string;
|
true;
|
||||||
let scale_down = formData.get('scale_down') as string;
|
|
||||||
let new_filename = formData.get('new_filename') as string;
|
|
||||||
|
|
||||||
$ae_sess.files.processed_file_kv[hosted_file_id] = {};
|
submit_status = 'clipped';
|
||||||
$ae_sess.files.processed_file_kv[hosted_file_id].submit_status =
|
clip_complete = true;
|
||||||
'clipping';
|
|
||||||
$ae_sess.files.processed_file_kv[hosted_file_id].clip_complete = false;
|
|
||||||
|
|
||||||
// $ae_sess.files.disable_submit__hosted_file_obj = true;
|
// let file_blob = new Blob([result.data]);
|
||||||
$ae_loc.files.processed_file_kv[hosted_file_id] = {};
|
// // console.log(file_blob);
|
||||||
$ae_loc.files.processed_file_kv[hosted_file_id].submit_status =
|
// let file_obj_url = window.URL.createObjectURL(file_blob); // The img src
|
||||||
'clipping';
|
// // const url = window.URL.createObjectURL(new Blob([result.data]));
|
||||||
$ae_loc.files.processed_file_kv[hosted_file_id].start_time = start_time;
|
// download_clip_src = file_obj_url;
|
||||||
$ae_loc.files.processed_file_kv[hosted_file_id].end_time = end_time;
|
// // download_filename = file_obj_url;
|
||||||
$ae_loc.files.processed_file_kv[hosted_file_id].reencode = reencode;
|
|
||||||
$ae_loc.files.processed_file_kv[hosted_file_id].scale_down = scale_down;
|
|
||||||
$ae_loc.files.processed_file_kv[hosted_file_id].new_filename =
|
|
||||||
new_filename;
|
|
||||||
$ae_loc.files.processed_file_kv[hosted_file_id].clip_complete = false;
|
|
||||||
|
|
||||||
let endpoint = `/hosted_file/${hosted_file_id}/clip_video`;
|
return true;
|
||||||
|
});
|
||||||
let params = {
|
}
|
||||||
link_to_type: link_to_type,
|
|
||||||
link_to_id: link_to_id,
|
|
||||||
filename_no_ext: new_filename.replace('.mp4', ''),
|
|
||||||
from_type: 'mp4', // Video file type being converted
|
|
||||||
to_type: 'mp4', // Video file type to convert to
|
|
||||||
start_time: start_time,
|
|
||||||
end_time: end_time,
|
|
||||||
reencode: reencode,
|
|
||||||
scale_down: scale_down
|
|
||||||
};
|
|
||||||
|
|
||||||
ae_promises[hosted_file_id] = {};
|
|
||||||
// .convert__hosted_file_obj
|
|
||||||
ae_promises[hosted_file_id] = api
|
|
||||||
.get_object({
|
|
||||||
api_cfg: $ae_api,
|
|
||||||
endpoint: endpoint,
|
|
||||||
params: params,
|
|
||||||
timeout: 300000, // 5 minutes
|
|
||||||
// return_blob: true,
|
|
||||||
// filename: event.target.new_filename.value,
|
|
||||||
// auto_download: false,
|
|
||||||
task_id: task_id,
|
|
||||||
log_lvl: log_lvl
|
|
||||||
})
|
|
||||||
.then(function (result) {
|
|
||||||
console.log(result);
|
|
||||||
|
|
||||||
video_clip_file_kv[result.hosted_file_id] = {};
|
|
||||||
video_clip_file_kv[result.hosted_file_id] = result;
|
|
||||||
|
|
||||||
// $ae_loc.files.video_clip_file_kv[result.hosted_file_id] = {};
|
|
||||||
// $ae_loc.files.video_clip_file_kv[result.hosted_file_id] = result;
|
|
||||||
|
|
||||||
$ae_sess.files.processed_file_kv[hosted_file_id].submit_status =
|
|
||||||
'clipped';
|
|
||||||
$ae_sess.files.processed_file_kv[hosted_file_id].clip_complete =
|
|
||||||
true;
|
|
||||||
|
|
||||||
$ae_loc.files.processed_file_kv[hosted_file_id].submit_status =
|
|
||||||
'clipped';
|
|
||||||
$ae_loc.files.processed_file_kv[hosted_file_id].clip_complete =
|
|
||||||
true;
|
|
||||||
|
|
||||||
submit_status = 'clipped';
|
|
||||||
clip_complete = true;
|
|
||||||
|
|
||||||
// let file_blob = new Blob([result.data]);
|
|
||||||
// // console.log(file_blob);
|
|
||||||
// let file_obj_url = window.URL.createObjectURL(file_blob); // The img src
|
|
||||||
// // const url = window.URL.createObjectURL(new Blob([result.data]));
|
|
||||||
// download_clip_src = file_obj_url;
|
|
||||||
// // download_filename = file_obj_url;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<section class="{class_li_default} {class_li}">
|
<section class="{class_li_default} {class_li}">
|
||||||
@@ -191,11 +194,11 @@
|
|||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
{#each Object.entries(hosted_file_obj_kv) as [hosted_file_id, hosted_file_obj] (hosted_file_id)}
|
{#each Object.entries(hosted_file_obj_kv) as [hosted_file_id, hosted_file_obj] (hosted_file_id)}
|
||||||
<div class="border border-surface-500/20 rounded-lg p-2 m-2 preset-tonal-surface">
|
<div
|
||||||
|
class="border-surface-500/20 preset-tonal-surface m-2 rounded-lg border p-2">
|
||||||
<!-- Download Button (Standardized) -->
|
<!-- Download Button (Standardized) -->
|
||||||
<div
|
<div
|
||||||
class="flex flex-row flex-wrap gap-1 justify-center items-center w-full"
|
class="flex w-full flex-row flex-wrap items-center justify-center gap-1">
|
||||||
>
|
|
||||||
<!-- Remove from uploaded file kv list -->
|
<!-- Remove from uploaded file kv list -->
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -219,8 +222,7 @@
|
|||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
class="btn btn-sm preset-tonal-warning hover:preset-filled-warning-500"
|
class="btn btn-sm preset-tonal-warning hover:preset-filled-warning-500"
|
||||||
title={`Remove this file from list of videos:\n${hosted_file_obj.filename}\n[API] SHA256: ${hosted_file_obj?.hash_sha256?.slice(0, 10)}... Hosted ID: ${hosted_file_obj.hosted_file_id}`}
|
title={`Remove this file from list of videos:\n${hosted_file_obj.filename}\n[API] SHA256: ${hosted_file_obj?.hash_sha256?.slice(0, 10)}... Hosted ID: ${hosted_file_obj.hosted_file_id}`}>
|
||||||
>
|
|
||||||
<MinusCircle size="1em" class="m-1" />
|
<MinusCircle size="1em" class="m-1" />
|
||||||
<span class="">Remove</span>
|
<span class="">Remove</span>
|
||||||
</button>
|
</button>
|
||||||
@@ -234,60 +236,49 @@
|
|||||||
variant="tonal"
|
variant="tonal"
|
||||||
classes="novi_btn btn-sm lg:btn-md min-w-72 lg:min-w-96 !justify-start"
|
classes="novi_btn btn-sm lg:btn-md min-w-72 lg:min-w-96 !justify-start"
|
||||||
show_divider={true}
|
show_divider={true}
|
||||||
max_filename={30}
|
max_filename={30} />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<span
|
<span
|
||||||
>{ae_util.shorten_filename({
|
>{ae_util.shorten_filename({
|
||||||
filename: hosted_file_obj?.filename,
|
filename: hosted_file_obj?.filename,
|
||||||
max_length: 30
|
max_length: 30
|
||||||
})}</span
|
})}</span>
|
||||||
>
|
|
||||||
<span>
|
<span>
|
||||||
<span class="text-sm font-bold"> File ID: </span>
|
<span class="text-sm font-bold"> File ID: </span>
|
||||||
{hosted_file_obj.hosted_file_id}</span
|
{hosted_file_obj.hosted_file_id}</span>
|
||||||
>
|
|
||||||
<span>
|
<span>
|
||||||
<span class="text-sm font-bold"> Type: </span>
|
<span class="text-sm font-bold"> Type: </span>
|
||||||
{hosted_file_obj.extension}</span
|
{hosted_file_obj.extension}</span>
|
||||||
>
|
|
||||||
<!-- <span>{hosted_file_obj.filename}</span> -->
|
<!-- <span>{hosted_file_obj.filename}</span> -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form
|
<form
|
||||||
onsubmit={prevent_default(handle_clip_video)}
|
onsubmit={prevent_default(handle_clip_video)}
|
||||||
class="{class_li_default} {class_li}"
|
class="{class_li_default} {class_li}">
|
||||||
>
|
|
||||||
<!-- {$ae_sess?.files[hosted_file_obj?.hosted_file_id ?? 'obj'].submit_status ?? 'not set'} -->
|
<!-- {$ae_sess?.files[hosted_file_obj?.hosted_file_id ?? 'obj'].submit_status ?? 'not set'} -->
|
||||||
|
|
||||||
<input
|
<input
|
||||||
type="hidden"
|
type="hidden"
|
||||||
name="hosted_file_id"
|
name="hosted_file_id"
|
||||||
value={hosted_file_obj.hosted_file_id}
|
value={hosted_file_obj.hosted_file_id} />
|
||||||
/>
|
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="flex flex-row gap-1 justify-center items-center w-full"
|
class="flex w-full flex-row items-center justify-center gap-1">
|
||||||
>
|
<span class="w-32 text-xs font-bold">New Filename:</span>
|
||||||
<span class="text-xs font-bold w-32">New Filename:</span>
|
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
class="input w-full text-sm variant-filled-surface"
|
class="input variant-filled-surface w-full text-sm"
|
||||||
name="new_filename"
|
name="new_filename"
|
||||||
value={hosted_file_obj.filename}
|
value={hosted_file_obj.filename} />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="max-w-(--breakpoint-sm) flex flex-row gap-1 justify-center items-center w-full"
|
class="flex w-full max-w-(--breakpoint-sm) flex-row items-center justify-center gap-1">
|
||||||
>
|
|
||||||
<label
|
<label
|
||||||
class="label w-48"
|
class="label w-48"
|
||||||
title="The start time of the clip. This is the time in the video where the clip will start. You may need to subtract a few seconds to get the exact start time."
|
title="The start time of the clip. This is the time in the video where the clip will start. You may need to subtract a few seconds to get the exact start time.">
|
||||||
>
|
|
||||||
<span class="text-xs font-bold"
|
<span class="text-xs font-bold"
|
||||||
>Start time (HH:MM:SS)</span
|
>Start time (HH:MM:SS)</span>
|
||||||
>
|
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
name="start_time"
|
name="start_time"
|
||||||
@@ -300,17 +291,14 @@
|
|||||||
].start_time
|
].start_time
|
||||||
: '00:00:00'}
|
: '00:00:00'}
|
||||||
placeholder="HH:MM:SS (00:01:30)"
|
placeholder="HH:MM:SS (00:01:30)"
|
||||||
class="input w-32 variant-filled-surface"
|
class="input variant-filled-surface w-32" />
|
||||||
/>
|
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label
|
<label
|
||||||
class="label w-48"
|
class="label w-48"
|
||||||
title="The end time of the clip. This is the time in the video where the clip will end. You may need to add a few seconds to get the exact end time."
|
title="The end time of the clip. This is the time in the video where the clip will end. You may need to add a few seconds to get the exact end time.">
|
||||||
>
|
|
||||||
<span class="text-xs font-bold"
|
<span class="text-xs font-bold"
|
||||||
>End time (HH:MM:SS)</span
|
>End time (HH:MM:SS)</span>
|
||||||
>
|
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
name="end_time"
|
name="end_time"
|
||||||
@@ -323,14 +311,12 @@
|
|||||||
].end_time
|
].end_time
|
||||||
: '00:45:59'}
|
: '00:45:59'}
|
||||||
placeholder="HH:MM:SS (01:05:25)"
|
placeholder="HH:MM:SS (01:05:25)"
|
||||||
class="input w-32 variant-filled-surface"
|
class="input variant-filled-surface w-32" />
|
||||||
/>
|
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<span
|
<span
|
||||||
class="flex flex-col gap-1 items-center justify-center"
|
class="flex flex-col items-center justify-center gap-1"
|
||||||
title="Re-encode the video file? This does cause some minor quality loss. Re-encoding is useful if the audio or video seems to be chopped off at the beginning or end of the clip. It can also help with partially corrupted files."
|
title="Re-encode the video file? This does cause some minor quality loss. Re-encoding is useful if the audio or video seems to be chopped off at the beginning or end of the clip. It can also help with partially corrupted files.">
|
||||||
>
|
|
||||||
<span class="text-xs font-bold"> Re-encode? </span>
|
<span class="text-xs font-bold"> Re-encode? </span>
|
||||||
<label class="inline-block">
|
<label class="inline-block">
|
||||||
<input
|
<input
|
||||||
@@ -338,8 +324,7 @@
|
|||||||
name="reencode"
|
name="reencode"
|
||||||
value="true"
|
value="true"
|
||||||
class="radio"
|
class="radio"
|
||||||
checked
|
checked />
|
||||||
/>
|
|
||||||
True
|
True
|
||||||
</label>
|
</label>
|
||||||
<label class="inline-block">
|
<label class="inline-block">
|
||||||
@@ -347,16 +332,14 @@
|
|||||||
type="radio"
|
type="radio"
|
||||||
name="reencode"
|
name="reencode"
|
||||||
value="false"
|
value="false"
|
||||||
class="radio"
|
class="radio" />
|
||||||
/>
|
|
||||||
False
|
False
|
||||||
</label>
|
</label>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span
|
<span
|
||||||
class="flex flex-col gap-1 items-center justify-center"
|
class="flex flex-col items-center justify-center gap-1"
|
||||||
title="Scale the video file down to 1920x1080? This does cause some minor quality loss. Re-encoding is useful if the audio or video seems to be chopped off at the beginning or end of the clip. It can also help with partially corrupted files."
|
title="Scale the video file down to 1920x1080? This does cause some minor quality loss. Re-encoding is useful if the audio or video seems to be chopped off at the beginning or end of the clip. It can also help with partially corrupted files.">
|
||||||
>
|
|
||||||
<span class="text-xs font-bold"> Scale down? </span>
|
<span class="text-xs font-bold"> Scale down? </span>
|
||||||
<label class="inline-block">
|
<label class="inline-block">
|
||||||
<input
|
<input
|
||||||
@@ -364,8 +347,7 @@
|
|||||||
name="scale_down"
|
name="scale_down"
|
||||||
value="true"
|
value="true"
|
||||||
class="radio"
|
class="radio"
|
||||||
checked
|
checked />
|
||||||
/>
|
|
||||||
True
|
True
|
||||||
</label>
|
</label>
|
||||||
<label class="inline-block">
|
<label class="inline-block">
|
||||||
@@ -373,8 +355,7 @@
|
|||||||
type="radio"
|
type="radio"
|
||||||
name="scale_down"
|
name="scale_down"
|
||||||
value="false"
|
value="false"
|
||||||
class="radio"
|
class="radio" />
|
||||||
/>
|
|
||||||
False
|
False
|
||||||
</label>
|
</label>
|
||||||
</span>
|
</span>
|
||||||
@@ -382,9 +363,8 @@
|
|||||||
|
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
class="btn btn-lg btn-primary preset-tonal-primary border border-primary-500 hover:preset-filled-primary-500 transition-colors"
|
class="btn btn-lg btn-primary preset-tonal-primary border-primary-500 hover:preset-filled-primary-500 border transition-colors"
|
||||||
disabled={submit_status == 'clipping'}
|
disabled={submit_status == 'clipping'}>
|
||||||
>
|
|
||||||
<!-- {#await ae_promises[hosted_file_id]} -->
|
<!-- {#await ae_promises[hosted_file_id]} -->
|
||||||
{#if $ae_loc.files.processed_file_kv[hosted_file_id] && $ae_loc.files.processed_file_kv[hosted_file_id].submit_status == 'clipping'}
|
{#if $ae_loc.files.processed_file_kv[hosted_file_id] && $ae_loc.files.processed_file_kv[hosted_file_id].submit_status == 'clipping'}
|
||||||
<LoaderCircle size="1em" class="m-1 animate-spin" />
|
<LoaderCircle size="1em" class="m-1 animate-spin" />
|
||||||
@@ -407,8 +387,7 @@
|
|||||||
{#await ae_promises[hosted_file_id]}
|
{#await ae_promises[hosted_file_id]}
|
||||||
<LoaderCircle size="1em" class="m-1 animate-spin" />
|
<LoaderCircle size="1em" class="m-1 animate-spin" />
|
||||||
<span class="highlight"
|
<span class="highlight"
|
||||||
>Processing... This may take a few minutes.</span
|
>Processing... This may take a few minutes.</span>
|
||||||
>
|
|
||||||
{:then}
|
{:then}
|
||||||
{#if ae_promises[hosted_file_id]}
|
{#if ae_promises[hosted_file_id]}
|
||||||
<Download size="1em" /> Ready to download below!
|
<Download size="1em" /> Ready to download below!
|
||||||
|
|||||||
@@ -1,48 +1,48 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
// Imports
|
// Imports
|
||||||
// Import components and elements
|
// Import components and elements
|
||||||
import AE_Comp_Hosted_Files_Download_Button from '$lib/ae_core/ae_comp__hosted_files_download_button.svelte';
|
import AE_Comp_Hosted_Files_Download_Button from '$lib/ae_core/ae_comp__hosted_files_download_button.svelte';
|
||||||
|
|
||||||
// Import storage, functions, and libraries
|
// Import storage, functions, and libraries
|
||||||
import type { key_val } from '$lib/stores/ae_stores';
|
import type { key_val } from '$lib/stores/ae_stores';
|
||||||
|
|
||||||
import { api } from '$lib/api/api';
|
import { api } from '$lib/api/api';
|
||||||
import { ae_util } from '$lib/ae_utils/ae_utils';
|
import { ae_util } from '$lib/ae_utils/ae_utils';
|
||||||
import {
|
import {
|
||||||
ae_snip,
|
ae_snip,
|
||||||
ae_loc,
|
ae_loc,
|
||||||
ae_sess,
|
ae_sess,
|
||||||
ae_api,
|
ae_api,
|
||||||
ae_trig,
|
ae_trig,
|
||||||
slct,
|
slct,
|
||||||
slct_trigger
|
slct_trigger
|
||||||
} from '$lib/stores/ae_stores';
|
} from '$lib/stores/ae_stores';
|
||||||
|
|
||||||
// Exports
|
// Exports
|
||||||
|
|
||||||
// export let hosted_file_id_li: string[] = [];
|
// export let hosted_file_id_li: string[] = [];
|
||||||
// export let hosted_file_obj_li: any[] = [];
|
// export let hosted_file_obj_li: any[] = [];
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
// export let hosted_file_obj_kv: key_val = {};
|
// export let hosted_file_obj_kv: key_val = {};
|
||||||
video_clip_file_kv?: key_val;
|
video_clip_file_kv?: key_val;
|
||||||
class_li_default?: string;
|
class_li_default?: string;
|
||||||
class_li?: string;
|
class_li?: string;
|
||||||
link_to_type: string;
|
link_to_type: string;
|
||||||
link_to_id: string;
|
link_to_id: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
let {
|
let {
|
||||||
log_lvl = 0,
|
log_lvl = 0,
|
||||||
video_clip_file_kv = $bindable({}),
|
video_clip_file_kv = $bindable({}),
|
||||||
class_li_default = 'flex flex-row flex-wrap gap-2 items-center justify-center w-full max-w-2xl p-2 mx-auto my-1 border border-surface-500/20 rounded-lg preset-tonal-surface',
|
class_li_default = 'flex flex-row flex-wrap gap-2 items-center justify-center w-full max-w-2xl p-2 mx-auto my-1 border border-surface-500/20 rounded-lg preset-tonal-surface',
|
||||||
class_li = '',
|
class_li = '',
|
||||||
link_to_type,
|
link_to_type,
|
||||||
link_to_id
|
link_to_id
|
||||||
}: Props = $props();
|
}: Props = $props();
|
||||||
|
|
||||||
let ae_promises: key_val = $state({});
|
let ae_promises: key_val = $state({});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<h3 class="h3">{Object.entries(video_clip_file_kv).length}× files clipped</h3>
|
<h3 class="h3">{Object.entries(video_clip_file_kv).length}× files clipped</h3>
|
||||||
@@ -54,7 +54,6 @@
|
|||||||
max_filename={30}
|
max_filename={30}
|
||||||
classes="btn btn-sm lg:btn-md preset-tonal-primary hover:preset-filled-primary-500 min-w-72 lg:min-w-96"
|
classes="btn btn-sm lg:btn-md preset-tonal-primary hover:preset-filled-primary-500 min-w-72 lg:min-w-96"
|
||||||
linked_to_type={link_to_type}
|
linked_to_type={link_to_type}
|
||||||
linked_to_id={link_to_id}
|
linked_to_id={link_to_id} />
|
||||||
/>
|
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,243 +1,275 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
// *** Import Svelte specific
|
// *** Import Svelte specific
|
||||||
import * as Lucide from 'lucide-svelte';
|
import * as Lucide from 'lucide-svelte';
|
||||||
import { fade } from 'svelte/transition';
|
import { fade } from 'svelte/transition';
|
||||||
|
|
||||||
// *** Import Aether specific variables and functions
|
// *** Import Aether specific variables and functions
|
||||||
import type { key_val } from '$lib/stores/ae_stores';
|
import type { key_val } from '$lib/stores/ae_stores';
|
||||||
import { ae_util } from '$lib/ae_utils/ae_utils';
|
import { ae_util } from '$lib/ae_utils/ae_utils';
|
||||||
import { download_ae_obj_id__hosted_file } from '$lib/ae_core/core__hosted_files';
|
import { download_ae_obj_id__hosted_file } from '$lib/ae_core/core__hosted_files';
|
||||||
import {
|
import { ae_loc, ae_sess, ae_api } from '$lib/stores/ae_stores';
|
||||||
ae_loc,
|
|
||||||
ae_sess,
|
|
||||||
ae_api
|
|
||||||
} from '$lib/stores/ae_stores';
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
hosted_file_id: null | string;
|
hosted_file_id: null | string;
|
||||||
hosted_file_obj: null | key_val;
|
hosted_file_obj: null | key_val;
|
||||||
filename?: null | string;
|
filename?: null | string;
|
||||||
max_filename?: number;
|
max_filename?: number;
|
||||||
auto_download?: boolean;
|
auto_download?: boolean;
|
||||||
linked_to_type?: null | string;
|
linked_to_type?: null | string;
|
||||||
linked_to_id?: null | string;
|
linked_to_id?: null | string;
|
||||||
download_complete?: null | boolean;
|
download_complete?: null | boolean;
|
||||||
download_percent?: number;
|
download_percent?: number;
|
||||||
download_status_msg?: string;
|
download_status_msg?: string;
|
||||||
variant?: 'tonal' | 'filled' | 'outline' | 'ghost';
|
variant?: 'tonal' | 'filled' | 'outline' | 'ghost';
|
||||||
color?: 'primary' | 'secondary' | 'tertiary' | 'success' | 'warning' | 'error' | 'surface';
|
color?:
|
||||||
show_divider?: boolean;
|
| 'primary'
|
||||||
show_direct_download?: boolean;
|
| 'secondary'
|
||||||
require_auth?: boolean;
|
| 'tertiary'
|
||||||
classes?: string;
|
| 'success'
|
||||||
click?: () => void | Promise<any>;
|
| 'warning'
|
||||||
label?: import('svelte').Snippet;
|
| 'error'
|
||||||
|
| 'surface';
|
||||||
|
show_divider?: boolean;
|
||||||
|
show_direct_download?: boolean;
|
||||||
|
require_auth?: boolean;
|
||||||
|
classes?: string;
|
||||||
|
click?: () => void | Promise<any>;
|
||||||
|
label?: import('svelte').Snippet;
|
||||||
|
}
|
||||||
|
|
||||||
|
let {
|
||||||
|
log_lvl = 0,
|
||||||
|
hosted_file_id,
|
||||||
|
hosted_file_obj,
|
||||||
|
filename = $bindable(null),
|
||||||
|
max_filename = $bindable(30),
|
||||||
|
auto_download = true,
|
||||||
|
linked_to_type = $bindable(null),
|
||||||
|
linked_to_id = $bindable(null),
|
||||||
|
download_complete = $bindable(),
|
||||||
|
download_percent = $bindable(),
|
||||||
|
download_status_msg = $bindable('Not started'),
|
||||||
|
variant = 'tonal',
|
||||||
|
color = 'primary',
|
||||||
|
show_divider = true,
|
||||||
|
show_direct_download = false,
|
||||||
|
require_auth = true,
|
||||||
|
classes = '',
|
||||||
|
click,
|
||||||
|
label
|
||||||
|
}: Props = $props();
|
||||||
|
|
||||||
|
// Map variant/color to classes using literal strings so Tailwind can find them
|
||||||
|
const color_map: Record<string, Record<string, string>> = {
|
||||||
|
primary: {
|
||||||
|
tonal: 'preset-tonal-primary border border-primary-500/30 hover:preset-filled-primary-500',
|
||||||
|
filled: 'preset-filled-primary-500 hover:preset-filled-primary-600',
|
||||||
|
outline: 'border border-primary-500 hover:preset-tonal-primary',
|
||||||
|
ghost: 'hover:preset-tonal-primary'
|
||||||
|
},
|
||||||
|
secondary: {
|
||||||
|
tonal: 'preset-tonal-secondary border border-secondary-500/30 hover:preset-filled-secondary-500',
|
||||||
|
filled: 'preset-filled-secondary-500 hover:preset-filled-secondary-600',
|
||||||
|
outline: 'border border-secondary-500 hover:preset-tonal-secondary',
|
||||||
|
ghost: 'hover:preset-tonal-secondary'
|
||||||
|
},
|
||||||
|
tertiary: {
|
||||||
|
tonal: 'preset-tonal-tertiary border border-tertiary-500/30 hover:preset-filled-tertiary-500',
|
||||||
|
filled: 'preset-filled-tertiary-500 hover:preset-filled-tertiary-600',
|
||||||
|
outline: 'border border-tertiary-500 hover:preset-tonal-tertiary',
|
||||||
|
ghost: 'hover:preset-tonal-tertiary'
|
||||||
|
},
|
||||||
|
success: {
|
||||||
|
tonal: 'preset-tonal-success border border-success-500/30 hover:preset-filled-success-500',
|
||||||
|
filled: 'preset-filled-success-500 hover:preset-filled-success-600',
|
||||||
|
outline: 'border border-success-500 hover:preset-tonal-success',
|
||||||
|
ghost: 'hover:preset-tonal-success'
|
||||||
|
},
|
||||||
|
warning: {
|
||||||
|
tonal: 'preset-tonal-warning border border-warning-500/30 hover:preset-filled-warning-500',
|
||||||
|
filled: 'preset-filled-warning-500 hover:preset-filled-warning-600',
|
||||||
|
outline: 'border border-warning-500 hover:preset-tonal-warning',
|
||||||
|
ghost: 'hover:preset-tonal-warning'
|
||||||
|
},
|
||||||
|
error: {
|
||||||
|
tonal: 'preset-tonal-error border border-error-500/30 hover:preset-filled-error-500',
|
||||||
|
filled: 'preset-filled-error-500 hover:preset-filled-error-600',
|
||||||
|
outline: 'border border-error-500 hover:preset-tonal-error',
|
||||||
|
ghost: 'hover:preset-tonal-error'
|
||||||
|
},
|
||||||
|
surface: {
|
||||||
|
tonal: 'preset-tonal-surface border border-surface-500/30 hover:preset-filled-surface-500',
|
||||||
|
filled: 'preset-filled-surface-500 hover:preset-filled-surface-600',
|
||||||
|
outline: 'border border-surface-500 hover:preset-tonal-surface',
|
||||||
|
ghost: 'hover:preset-tonal-surface'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let variant_classes = $derived.by(() => {
|
||||||
|
const base =
|
||||||
|
'btn btn-sm lg:btn-md min-w-48 transition-all overflow-hidden px-3';
|
||||||
|
const style = color_map[color]?.[variant] || color_map.primary.tonal;
|
||||||
|
return `${base} ${style} ${classes}`.trim();
|
||||||
|
});
|
||||||
|
|
||||||
|
let show_filename_view = $state(true);
|
||||||
|
let status_interval: any;
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
if (log_lvl) {
|
||||||
|
console.log(
|
||||||
|
`ae_comp__hosted_files_download_button.svelte hosted_file_id=${hosted_file_id}`,
|
||||||
|
hosted_file_obj
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let ae_promises: key_val = $state({});
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
const file_id =
|
||||||
|
hosted_file_obj?.id ||
|
||||||
|
hosted_file_obj?.hosted_file_id ||
|
||||||
|
hosted_file_id;
|
||||||
|
if (file_id && $ae_sess?.api_download_kv[file_id]?.percent_completed) {
|
||||||
|
download_percent = $ae_sess.api_download_kv[file_id].percent_completed;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Reactive timer to alternate views during active download
|
||||||
|
$effect(() => {
|
||||||
|
const file_id =
|
||||||
|
hosted_file_obj?.id ||
|
||||||
|
hosted_file_obj?.hosted_file_id ||
|
||||||
|
hosted_file_id;
|
||||||
|
const is_actively_downloading =
|
||||||
|
ae_promises[file_id] && download_complete === undefined;
|
||||||
|
|
||||||
|
if (is_actively_downloading) {
|
||||||
|
if (!status_interval) {
|
||||||
|
status_interval = setInterval(() => {
|
||||||
|
show_filename_view = !show_filename_view;
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (status_interval) {
|
||||||
|
clearInterval(status_interval);
|
||||||
|
status_interval = null;
|
||||||
|
}
|
||||||
|
show_filename_view = true; // Default view when not downloading
|
||||||
}
|
}
|
||||||
|
|
||||||
let {
|
return () => {
|
||||||
log_lvl = 0,
|
if (status_interval) {
|
||||||
hosted_file_id,
|
clearInterval(status_interval);
|
||||||
hosted_file_obj,
|
status_interval = null;
|
||||||
filename = $bindable(null),
|
|
||||||
max_filename = $bindable(30),
|
|
||||||
auto_download = true,
|
|
||||||
linked_to_type = $bindable(null),
|
|
||||||
linked_to_id = $bindable(null),
|
|
||||||
download_complete = $bindable(),
|
|
||||||
download_percent = $bindable(),
|
|
||||||
download_status_msg = $bindable('Not started'),
|
|
||||||
variant = 'tonal',
|
|
||||||
color = 'primary',
|
|
||||||
show_divider = true,
|
|
||||||
show_direct_download = false,
|
|
||||||
require_auth = true,
|
|
||||||
classes = '',
|
|
||||||
click,
|
|
||||||
label
|
|
||||||
}: Props = $props();
|
|
||||||
|
|
||||||
// Map variant/color to classes using literal strings so Tailwind can find them
|
|
||||||
const color_map: Record<string, Record<string, string>> = {
|
|
||||||
primary: {
|
|
||||||
tonal: 'preset-tonal-primary border border-primary-500/30 hover:preset-filled-primary-500',
|
|
||||||
filled: 'preset-filled-primary-500 hover:preset-filled-primary-600',
|
|
||||||
outline: 'border border-primary-500 hover:preset-tonal-primary',
|
|
||||||
ghost: 'hover:preset-tonal-primary'
|
|
||||||
},
|
|
||||||
secondary: {
|
|
||||||
tonal: 'preset-tonal-secondary border border-secondary-500/30 hover:preset-filled-secondary-500',
|
|
||||||
filled: 'preset-filled-secondary-500 hover:preset-filled-secondary-600',
|
|
||||||
outline: 'border border-secondary-500 hover:preset-tonal-secondary',
|
|
||||||
ghost: 'hover:preset-tonal-secondary'
|
|
||||||
},
|
|
||||||
tertiary: {
|
|
||||||
tonal: 'preset-tonal-tertiary border border-tertiary-500/30 hover:preset-filled-tertiary-500',
|
|
||||||
filled: 'preset-filled-tertiary-500 hover:preset-filled-tertiary-600',
|
|
||||||
outline: 'border border-tertiary-500 hover:preset-tonal-tertiary',
|
|
||||||
ghost: 'hover:preset-tonal-tertiary'
|
|
||||||
},
|
|
||||||
success: {
|
|
||||||
tonal: 'preset-tonal-success border border-success-500/30 hover:preset-filled-success-500',
|
|
||||||
filled: 'preset-filled-success-500 hover:preset-filled-success-600',
|
|
||||||
outline: 'border border-success-500 hover:preset-tonal-success',
|
|
||||||
ghost: 'hover:preset-tonal-success'
|
|
||||||
},
|
|
||||||
warning: {
|
|
||||||
tonal: 'preset-tonal-warning border border-warning-500/30 hover:preset-filled-warning-500',
|
|
||||||
filled: 'preset-filled-warning-500 hover:preset-filled-warning-600',
|
|
||||||
outline: 'border border-warning-500 hover:preset-tonal-warning',
|
|
||||||
ghost: 'hover:preset-tonal-warning'
|
|
||||||
},
|
|
||||||
error: {
|
|
||||||
tonal: 'preset-tonal-error border border-error-500/30 hover:preset-filled-error-500',
|
|
||||||
filled: 'preset-filled-error-500 hover:preset-filled-error-600',
|
|
||||||
outline: 'border border-error-500 hover:preset-tonal-error',
|
|
||||||
ghost: 'hover:preset-tonal-error'
|
|
||||||
},
|
|
||||||
surface: {
|
|
||||||
tonal: 'preset-tonal-surface border border-surface-500/30 hover:preset-filled-surface-500',
|
|
||||||
filled: 'preset-filled-surface-500 hover:preset-filled-surface-600',
|
|
||||||
outline: 'border border-surface-500 hover:preset-tonal-surface',
|
|
||||||
ghost: 'hover:preset-tonal-surface'
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
});
|
||||||
|
|
||||||
let variant_classes = $derived.by(() => {
|
let final_filename = $derived(
|
||||||
const base = 'btn btn-sm lg:btn-md min-w-48 transition-all overflow-hidden px-3';
|
filename ?? hosted_file_obj?.filename ?? 'unknown'
|
||||||
const style = color_map[color]?.[variant] || color_map.primary.tonal;
|
);
|
||||||
return `${base} ${style} ${classes}`.trim();
|
let shortened_filename = $derived(
|
||||||
});
|
ae_util.shorten_filename({
|
||||||
|
|
||||||
let show_filename_view = $state(true);
|
|
||||||
let status_interval: any;
|
|
||||||
|
|
||||||
$effect(() => {
|
|
||||||
if (log_lvl) {
|
|
||||||
console.log(
|
|
||||||
`ae_comp__hosted_files_download_button.svelte hosted_file_id=${hosted_file_id}`,
|
|
||||||
hosted_file_obj
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let ae_promises: key_val = $state({});
|
|
||||||
|
|
||||||
$effect(() => {
|
|
||||||
const file_id = hosted_file_obj?.id || hosted_file_obj?.hosted_file_id || hosted_file_id;
|
|
||||||
if (file_id && $ae_sess?.api_download_kv[file_id]?.percent_completed) {
|
|
||||||
download_percent =
|
|
||||||
$ae_sess.api_download_kv[file_id].percent_completed;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Reactive timer to alternate views during active download
|
|
||||||
$effect(() => {
|
|
||||||
const file_id = hosted_file_obj?.id || hosted_file_obj?.hosted_file_id || hosted_file_id;
|
|
||||||
const is_actively_downloading = ae_promises[file_id] && download_complete === undefined;
|
|
||||||
|
|
||||||
if (is_actively_downloading) {
|
|
||||||
if (!status_interval) {
|
|
||||||
status_interval = setInterval(() => {
|
|
||||||
show_filename_view = !show_filename_view;
|
|
||||||
}, 3000);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (status_interval) {
|
|
||||||
clearInterval(status_interval);
|
|
||||||
status_interval = null;
|
|
||||||
}
|
|
||||||
show_filename_view = true; // Default view when not downloading
|
|
||||||
}
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
if (status_interval) {
|
|
||||||
clearInterval(status_interval);
|
|
||||||
status_interval = null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
let final_filename = $derived(filename ?? hosted_file_obj?.filename ?? 'unknown');
|
|
||||||
let shortened_filename = $derived(ae_util.shorten_filename({
|
|
||||||
filename: final_filename,
|
filename: final_filename,
|
||||||
max_length: max_filename
|
max_length: max_filename
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
|
|
||||||
let direct_download_url = $derived.by(() => {
|
let direct_download_url = $derived.by(() => {
|
||||||
if (!show_direct_download || !hosted_file_obj) return '';
|
if (!show_direct_download || !hosted_file_obj) return '';
|
||||||
// IMPORTANT: For Direct Link Mode, we MUST use the V3 Action endpoint to support Random String IDs.
|
// IMPORTANT: For Direct Link Mode, we MUST use the V3 Action endpoint to support Random String IDs.
|
||||||
// Legacy endpoints often expect integer IDs and will return 404 for string IDs.
|
// Legacy endpoints often expect integer IDs and will return 404 for string IDs.
|
||||||
const file_id = hosted_file_obj.event_file_id || hosted_file_obj.hosted_file_id || hosted_file_id;
|
const file_id =
|
||||||
const obj_type_path = hosted_file_obj.event_file_id ? 'event_file' : 'hosted_file';
|
hosted_file_obj.event_file_id ||
|
||||||
return `${$ae_api.base_url}/v3/action/${obj_type_path}/${file_id}/download?filename=${ae_util.clean_filename(final_filename)}&key=${$ae_api.account_id}`;
|
hosted_file_obj.hosted_file_id ||
|
||||||
});
|
hosted_file_id;
|
||||||
|
const obj_type_path = hosted_file_obj.event_file_id
|
||||||
|
? 'event_file'
|
||||||
|
: 'hosted_file';
|
||||||
|
return `${$ae_api.base_url}/v3/action/${obj_type_path}/${file_id}/download?filename=${ae_util.clean_filename(final_filename)}&key=${$ae_api.account_id}`;
|
||||||
|
});
|
||||||
|
|
||||||
async function handle_click() {
|
async function handle_click() {
|
||||||
const file_id = hosted_file_obj?.id || hosted_file_obj?.hosted_file_id || hosted_file_id;
|
const file_id =
|
||||||
download_complete = undefined;
|
hosted_file_obj?.id ||
|
||||||
download_status_msg = 'Downloading...';
|
hosted_file_obj?.hosted_file_id ||
|
||||||
|
hosted_file_id;
|
||||||
|
download_complete = undefined;
|
||||||
|
download_status_msg = 'Downloading...';
|
||||||
|
|
||||||
if (click) {
|
if (click) {
|
||||||
const result = click();
|
const result = click();
|
||||||
// If the override returns a promise, track it so the UI shows progress
|
// If the override returns a promise, track it so the UI shows progress
|
||||||
if (result instanceof Promise) {
|
if (result instanceof Promise) {
|
||||||
ae_promises[file_id] = result;
|
ae_promises[file_id] = result;
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
ae_promises[file_id] = download_ae_obj_id__hosted_file({
|
|
||||||
api_cfg: $ae_api,
|
|
||||||
hosted_file_id: file_id,
|
|
||||||
return_file: true,
|
|
||||||
filename: final_filename,
|
|
||||||
auto_download: auto_download,
|
|
||||||
log_lvl: log_lvl
|
|
||||||
})
|
|
||||||
.then((result) => {
|
|
||||||
if (result === null) {
|
|
||||||
console.log('File not found (404)');
|
|
||||||
download_complete = null;
|
|
||||||
download_status_msg = 'File not found';
|
|
||||||
} else if (result === false) {
|
|
||||||
console.log(
|
|
||||||
'Possible error with API server (check network and server status)'
|
|
||||||
);
|
|
||||||
download_complete = false;
|
|
||||||
download_status_msg = 'Failed to download';
|
|
||||||
} else {
|
|
||||||
// console.log('File found and downloaded');
|
|
||||||
download_complete = true;
|
|
||||||
download_status_msg = 'File downloaded';
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ae_promises[file_id] = download_ae_obj_id__hosted_file({
|
||||||
|
api_cfg: $ae_api,
|
||||||
|
hosted_file_id: file_id,
|
||||||
|
return_file: true,
|
||||||
|
filename: final_filename,
|
||||||
|
auto_download: auto_download,
|
||||||
|
log_lvl: log_lvl
|
||||||
|
}).then((result) => {
|
||||||
|
if (result === null) {
|
||||||
|
console.log('File not found (404)');
|
||||||
|
download_complete = null;
|
||||||
|
download_status_msg = 'File not found';
|
||||||
|
} else if (result === false) {
|
||||||
|
console.log(
|
||||||
|
'Possible error with API server (check network and server status)'
|
||||||
|
);
|
||||||
|
download_complete = false;
|
||||||
|
download_status_msg = 'Failed to download';
|
||||||
|
} else {
|
||||||
|
// console.log('File found and downloaded');
|
||||||
|
download_complete = true;
|
||||||
|
download_status_msg = 'File downloaded';
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#snippet content()}
|
{#snippet content()}
|
||||||
{@const file_id = hosted_file_obj?.id || hosted_file_obj?.hosted_file_id || hosted_file_id}
|
{@const file_id =
|
||||||
|
hosted_file_obj?.id ||
|
||||||
|
hosted_file_obj?.hosted_file_id ||
|
||||||
|
hosted_file_id}
|
||||||
{#await ae_promises[file_id]}
|
{#await ae_promises[file_id]}
|
||||||
<div class="flex items-center w-full min-h-[1.5rem]">
|
<div class="flex min-h-[1.5rem] w-full items-center">
|
||||||
<div
|
<div
|
||||||
class="flex items-center pr-2 shrink-0 {show_divider ? 'border-r border-surface-500/30 mr-2' : ''}"
|
class="flex shrink-0 items-center pr-2 {show_divider
|
||||||
>
|
? 'border-surface-500/30 mr-2 border-r'
|
||||||
|
: ''}">
|
||||||
<Lucide.LoaderCircle class="animate-spin" size={18} />
|
<Lucide.LoaderCircle class="animate-spin" size={18} />
|
||||||
</div>
|
</div>
|
||||||
<div class="grow relative text-left h-full">
|
<div class="relative h-full grow text-left">
|
||||||
{#if show_filename_view}
|
{#if show_filename_view}
|
||||||
<div in:fade={{ duration: 250 }} out:fade={{ duration: 250 }} class="flex items-center h-full">
|
<div
|
||||||
|
in:fade={{ duration: 250 }}
|
||||||
|
out:fade={{ duration: 250 }}
|
||||||
|
class="flex h-full items-center">
|
||||||
<span class="truncate">
|
<span class="truncate">
|
||||||
{shortened_filename}
|
{shortened_filename}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<div in:fade={{ duration: 250 }} out:fade={{ duration: 250 }} class="absolute inset-0 flex items-center h-full">
|
<div
|
||||||
|
in:fade={{ duration: 250 }}
|
||||||
|
out:fade={{ duration: 250 }}
|
||||||
|
class="absolute inset-0 flex h-full items-center">
|
||||||
<span class="font-bold whitespace-nowrap">
|
<span class="font-bold whitespace-nowrap">
|
||||||
Downloading:
|
Downloading:
|
||||||
{#if $ae_sess.api_download_kv[file_id]}
|
{#if $ae_sess.api_download_kv[file_id]}
|
||||||
{$ae_sess.api_download_kv[file_id].percent_completed}%
|
{$ae_sess.api_download_kv[file_id]
|
||||||
|
.percent_completed}%
|
||||||
{:else}
|
{:else}
|
||||||
...
|
...
|
||||||
{/if}
|
{/if}
|
||||||
@@ -250,18 +282,22 @@
|
|||||||
{#if label}
|
{#if label}
|
||||||
{@render label()}
|
{@render label()}
|
||||||
{:else}
|
{:else}
|
||||||
{@const IconComp = ae_util.file_extension_icon_lucide(hosted_file_obj?.extension)}
|
{@const IconComp = ae_util.file_extension_icon_lucide(
|
||||||
<div class="flex items-center w-full">
|
hosted_file_obj?.extension
|
||||||
|
)}
|
||||||
|
<div class="flex w-full items-center">
|
||||||
<div
|
<div
|
||||||
class="flex items-center pr-2 shrink-0 {show_divider ? 'border-r border-surface-500/30 mr-2' : ''}"
|
class="flex shrink-0 items-center pr-2 {show_divider
|
||||||
>
|
? 'border-surface-500/30 mr-2 border-r'
|
||||||
|
: ''}">
|
||||||
<IconComp size={18} />
|
<IconComp size={18} />
|
||||||
</div>
|
</div>
|
||||||
<span class="grow truncate text-left">
|
<span class="grow truncate text-left">
|
||||||
{shortened_filename}
|
{shortened_filename}
|
||||||
</span>
|
</span>
|
||||||
{#if hosted_file_obj?.file_purpose || hosted_file_obj?.group}
|
{#if hosted_file_obj?.file_purpose || hosted_file_obj?.group}
|
||||||
<span class="badge preset-tonal-success ml-2 text-[10px] uppercase font-bold shrink-0">
|
<span
|
||||||
|
class="badge preset-tonal-success ml-2 shrink-0 text-[10px] font-bold uppercase">
|
||||||
{hosted_file_obj.file_purpose || hosted_file_obj.group}
|
{hosted_file_obj.file_purpose || hosted_file_obj.group}
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -270,22 +306,25 @@
|
|||||||
{/await}
|
{/await}
|
||||||
|
|
||||||
{#if download_complete === null}
|
{#if download_complete === null}
|
||||||
<span class="text-red-800 dark:text-red-200 ml-2 whitespace-nowrap">File not found</span>
|
<span class="ml-2 whitespace-nowrap text-red-800 dark:text-red-200"
|
||||||
|
>File not found</span>
|
||||||
{:else if download_complete === false}
|
{:else if download_complete === false}
|
||||||
<span class="text-red-800 dark:text-red-200 ml-2 whitespace-nowrap text-xs">Failed!</span>
|
<span
|
||||||
|
class="ml-2 text-xs whitespace-nowrap text-red-800 dark:text-red-200"
|
||||||
|
>Failed!</span>
|
||||||
{/if}
|
{/if}
|
||||||
{/snippet}
|
{/snippet}
|
||||||
|
|
||||||
{#if hosted_file_id && hosted_file_obj}
|
{#if hosted_file_id && hosted_file_obj}
|
||||||
{@const file_id = hosted_file_obj.id || hosted_file_obj.hosted_file_id || hosted_file_id}
|
{@const file_id =
|
||||||
|
hosted_file_obj.id || hosted_file_obj.hosted_file_id || hosted_file_id}
|
||||||
|
|
||||||
{#if show_direct_download}
|
{#if show_direct_download}
|
||||||
<a
|
<a
|
||||||
href={direct_download_url}
|
href={direct_download_url}
|
||||||
download={ae_util.clean_filename(final_filename)}
|
download={ae_util.clean_filename(final_filename)}
|
||||||
class={variant_classes}
|
class={variant_classes}
|
||||||
title={`Direct download (V3 Action):\n${final_filename}\n[API] SHA256: ${hosted_file_obj?.hash_sha256?.slice(0, 10)}...\nHosted ID: ${file_id}`}
|
title={`Direct download (V3 Action):\n${final_filename}\n[API] SHA256: ${hosted_file_obj?.hash_sha256?.slice(0, 10)}...\nHosted ID: ${file_id}`}>
|
||||||
>
|
|
||||||
{@render content()}
|
{@render content()}
|
||||||
</a>
|
</a>
|
||||||
{:else}
|
{:else}
|
||||||
@@ -294,17 +333,21 @@
|
|||||||
disabled={require_auth && !$ae_loc.authenticated_access}
|
disabled={require_auth && !$ae_loc.authenticated_access}
|
||||||
class={variant_classes}
|
class={variant_classes}
|
||||||
onclick={handle_click}
|
onclick={handle_click}
|
||||||
title={`Download this file:\n${final_filename}\n[API] SHA256: ${hosted_file_obj?.hash_sha256?.slice(0, 10)}...\nHosted ID: ${file_id}\n Linked to: ${linked_to_type} ID: ${linked_to_id}`}
|
title={`Download this file:\n${final_filename}\n[API] SHA256: ${hosted_file_obj?.hash_sha256?.slice(0, 10)}...\nHosted ID: ${file_id}\n Linked to: ${linked_to_type} ID: ${linked_to_id}`}>
|
||||||
>
|
|
||||||
{@render content()}
|
{@render content()}
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
{:else}
|
{:else}
|
||||||
<button type="button" disabled class={variant_classes} title="No file selected">
|
<button
|
||||||
<div class="flex items-center w-full">
|
type="button"
|
||||||
|
disabled
|
||||||
|
class={variant_classes}
|
||||||
|
title="No file selected">
|
||||||
|
<div class="flex w-full items-center">
|
||||||
<div
|
<div
|
||||||
class="flex items-center pr-2 shrink-0 {show_divider ? 'border-r border-surface-500/30 mr-2' : ''}"
|
class="flex shrink-0 items-center pr-2 {show_divider
|
||||||
>
|
? 'border-surface-500/30 mr-2 border-r'
|
||||||
|
: ''}">
|
||||||
<Lucide.FileX size={18} />
|
<Lucide.FileX size={18} />
|
||||||
</div>
|
</div>
|
||||||
<span class="grow text-left"> No file info </span>
|
<span class="grow text-left"> No file info </span>
|
||||||
|
|||||||
@@ -1,281 +1,286 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
// untrack import removed — task_id sync now uses direct $effect (no untrack needed)
|
// untrack import removed — task_id sync now uses direct $effect (no untrack needed)
|
||||||
// Imports
|
// Imports
|
||||||
// Import components and elements
|
// Import components and elements
|
||||||
import * as Lucide from 'lucide-svelte';
|
import * as Lucide from 'lucide-svelte';
|
||||||
import Element_input_files_tbl from '$lib/elements/element_input_files_tbl.svelte';
|
import Element_input_files_tbl from '$lib/elements/element_input_files_tbl.svelte';
|
||||||
|
|
||||||
// Import storage, functions, and libraries
|
// Import storage, functions, and libraries
|
||||||
import type { key_val } from '$lib/stores/ae_stores';
|
import type { key_val } from '$lib/stores/ae_stores';
|
||||||
|
|
||||||
import { api } from '$lib/api/api';
|
import { api } from '$lib/api/api';
|
||||||
import {
|
import {
|
||||||
ae_snip,
|
ae_snip,
|
||||||
ae_loc,
|
ae_loc,
|
||||||
ae_sess,
|
ae_sess,
|
||||||
ae_api,
|
ae_api,
|
||||||
ae_trig,
|
ae_trig,
|
||||||
slct,
|
slct,
|
||||||
slct_trigger
|
slct_trigger
|
||||||
} from '$lib/stores/ae_stores';
|
} from '$lib/stores/ae_stores';
|
||||||
|
|
||||||
// Exports
|
// Exports
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
// Expecting these for link_to_type: 'event', 'event_location', 'archive_content', etc
|
// Expecting these for link_to_type: 'event', 'event_location', 'archive_content', etc
|
||||||
link_to_type: string;
|
link_to_type: string;
|
||||||
link_to_id: string;
|
link_to_id: string;
|
||||||
input_name?: string;
|
input_name?: string;
|
||||||
multiple?: boolean;
|
multiple?: boolean;
|
||||||
required?: boolean;
|
required?: boolean;
|
||||||
accept?: string;
|
accept?: string;
|
||||||
class_li_default?: string;
|
class_li_default?: string;
|
||||||
class_li?: string;
|
class_li?: string;
|
||||||
input_class_li?: string[];
|
input_class_li?: string[];
|
||||||
table_class_li?: string[];
|
table_class_li?: string[];
|
||||||
upload_complete?: boolean;
|
upload_complete?: boolean;
|
||||||
submit_status?: null | string;
|
submit_status?: null | string;
|
||||||
hosted_file_id_li?: string[];
|
hosted_file_id_li?: string[];
|
||||||
hosted_file_obj_li?: any[];
|
hosted_file_obj_li?: any[];
|
||||||
hosted_file_obj_kv?: key_val;
|
hosted_file_obj_kv?: key_val;
|
||||||
label?: import('svelte').Snippet;
|
label?: import('svelte').Snippet;
|
||||||
|
}
|
||||||
|
|
||||||
|
let {
|
||||||
|
log_lvl = 0,
|
||||||
|
link_to_type,
|
||||||
|
link_to_id,
|
||||||
|
input_name = 'file_list',
|
||||||
|
multiple = true,
|
||||||
|
required = true,
|
||||||
|
accept = 'audio/*, image/*, video/*, .bak, .cfg, .css, .csv, .doc, .docx, .gz, .htm, .html, .ini, .iso, .j2, .json, .key, .keynote, .md, .pdf, .ppt, .pptx, .rar, .rtf, .sql, .svelte, ttf, .txt, .xls, .xlsx, .xz, .zip, .bin, .dmg, .exe, .js, .msi, .php, .py, .sh',
|
||||||
|
class_li_default = 'flex flex-col gap-1 items-center justify-center w-full max-w-2xl mx-auto my-1',
|
||||||
|
class_li = '',
|
||||||
|
input_class_li = ['file_drop_area'],
|
||||||
|
table_class_li = ['table', 'table-sm', 'table-striped', '', 'text-sm'],
|
||||||
|
upload_complete = $bindable(false),
|
||||||
|
submit_status = $bindable(null),
|
||||||
|
hosted_file_id_li = $bindable([]),
|
||||||
|
hosted_file_obj_li = $bindable([]),
|
||||||
|
hosted_file_obj_kv = $bindable({}),
|
||||||
|
label
|
||||||
|
}: Props = $props();
|
||||||
|
|
||||||
|
// Local Variables
|
||||||
|
let task_id: string = $state('');
|
||||||
|
let input_file_list: any = $state(null);
|
||||||
|
let ae_promises: key_val = $state({}); // Promise<any>;
|
||||||
|
let ae_triggers: key_val = {};
|
||||||
|
|
||||||
|
let input_element_id = 'ae_comp__hosted_files_upload__input';
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
if (log_lvl) {
|
||||||
|
console.log(`*** ae_comp__hosted_files_upload.svelte ***`);
|
||||||
|
console.log(`link_to_type: ${link_to_type} link_to_id: ${link_to_id}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
// Sync task_id with link_to_id prop so it resets when navigating to a different object.
|
||||||
|
task_id = link_to_id;
|
||||||
|
});
|
||||||
|
|
||||||
|
// *** Functions and Logic
|
||||||
|
async function handle_submit_form_files(event: SubmitEvent) {
|
||||||
|
console.log('*** handle_submit_form() ***');
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
if (!event) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let {
|
$ae_sess.files.disable_submit__hosted_file_obj = true;
|
||||||
log_lvl = 0,
|
$ae_sess.files.submit_status = 'saving';
|
||||||
link_to_type,
|
submit_status = 'saving';
|
||||||
link_to_id,
|
upload_complete = false;
|
||||||
input_name = 'file_list',
|
|
||||||
multiple = true,
|
|
||||||
required = true,
|
|
||||||
accept = 'audio/*, image/*, video/*, .bak, .cfg, .css, .csv, .doc, .docx, .gz, .htm, .html, .ini, .iso, .j2, .json, .key, .keynote, .md, .pdf, .ppt, .pptx, .rar, .rtf, .sql, .svelte, ttf, .txt, .xls, .xlsx, .xz, .zip, .bin, .dmg, .exe, .js, .msi, .php, .py, .sh',
|
|
||||||
class_li_default = 'flex flex-col gap-1 items-center justify-center w-full max-w-2xl mx-auto my-1',
|
|
||||||
class_li = '',
|
|
||||||
input_class_li = ['file_drop_area'],
|
|
||||||
table_class_li = ['table', 'table-sm', 'table-striped', '', 'text-sm'],
|
|
||||||
upload_complete = $bindable(false),
|
|
||||||
submit_status = $bindable(null),
|
|
||||||
hosted_file_id_li = $bindable([]),
|
|
||||||
hosted_file_obj_li = $bindable([]),
|
|
||||||
hosted_file_obj_kv = $bindable({}),
|
|
||||||
label
|
|
||||||
}: Props = $props();
|
|
||||||
|
|
||||||
// Local Variables
|
hosted_file_id_li = [];
|
||||||
let task_id: string = $state('');
|
hosted_file_obj_li = [];
|
||||||
let input_file_list: any = $state(null);
|
hosted_file_obj_kv = {};
|
||||||
let ae_promises: key_val = $state({}); // Promise<any>;
|
|
||||||
let ae_triggers: key_val = {};
|
|
||||||
|
|
||||||
let input_element_id = 'ae_comp__hosted_files_upload__input';
|
let hosted_file_results;
|
||||||
|
|
||||||
$effect(() => {
|
const target = event.currentTarget as HTMLFormElement;
|
||||||
if (log_lvl) {
|
const file_input = target
|
||||||
console.log(`*** ae_comp__hosted_files_upload.svelte ***`);
|
? (target[input_element_id] as HTMLInputElement)
|
||||||
console.log(`link_to_type: ${link_to_type} link_to_id: ${link_to_id}`);
|
: null;
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$effect(() => {
|
if (
|
||||||
// Sync task_id with link_to_id prop so it resets when navigating to a different object.
|
target &&
|
||||||
task_id = link_to_id;
|
file_input &&
|
||||||
});
|
file_input.files &&
|
||||||
|
file_input.files.length > 0
|
||||||
|
) {
|
||||||
|
task_id = link_to_id; // Ideally this should be the file hash, but we may be uploading multiple files at once. This should be done with a loop instead?
|
||||||
|
|
||||||
// *** Functions and Logic
|
// Loop through each file and upload them individually in event.target[input_element_id].files
|
||||||
async function handle_submit_form_files(event: SubmitEvent) {
|
// The task_id should be the file hash.
|
||||||
console.log('*** handle_submit_form() ***');
|
// processed_file_list[i] has the file hash_sha256, hash_sha256_match, warnings, uploaded, uploaded_bytes, filename, and file_size_bytes.
|
||||||
event.preventDefault();
|
for (let i = 0; i < file_input.files.length; i++) {
|
||||||
|
let tmp_file = file_input.files[i];
|
||||||
|
|
||||||
if (!event) {
|
task_id = $ae_sess.files.processed_file_list[i].hash_sha256;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$ae_sess.files.disable_submit__hosted_file_obj = true;
|
// hosted_file_results = await handle_input_upload_files([tmp_file], task_id);
|
||||||
$ae_sess.files.submit_status = 'saving';
|
hosted_file_results = await handle_input_upload_files({
|
||||||
submit_status = 'saving';
|
input_upload_files: [tmp_file],
|
||||||
upload_complete = false;
|
task_id: task_id
|
||||||
|
|
||||||
hosted_file_id_li = [];
|
|
||||||
hosted_file_obj_li = [];
|
|
||||||
hosted_file_obj_kv = {};
|
|
||||||
|
|
||||||
let hosted_file_results;
|
|
||||||
|
|
||||||
const target = event.currentTarget as HTMLFormElement;
|
|
||||||
const file_input = target ? (target[input_element_id] as HTMLInputElement) : null;
|
|
||||||
|
|
||||||
if (
|
|
||||||
target &&
|
|
||||||
file_input &&
|
|
||||||
file_input.files &&
|
|
||||||
file_input.files.length > 0
|
|
||||||
) {
|
|
||||||
task_id = link_to_id; // Ideally this should be the file hash, but we may be uploading multiple files at once. This should be done with a loop instead?
|
|
||||||
|
|
||||||
// Loop through each file and upload them individually in event.target[input_element_id].files
|
|
||||||
// The task_id should be the file hash.
|
|
||||||
// processed_file_list[i] has the file hash_sha256, hash_sha256_match, warnings, uploaded, uploaded_bytes, filename, and file_size_bytes.
|
|
||||||
for (let i = 0; i < file_input.files.length; i++) {
|
|
||||||
let tmp_file = file_input.files[i];
|
|
||||||
|
|
||||||
task_id = $ae_sess.files.processed_file_list[i].hash_sha256;
|
|
||||||
|
|
||||||
// hosted_file_results = await handle_input_upload_files([tmp_file], task_id);
|
|
||||||
hosted_file_results = await handle_input_upload_files({
|
|
||||||
input_upload_files: [tmp_file],
|
|
||||||
task_id: task_id
|
|
||||||
});
|
|
||||||
|
|
||||||
if (hosted_file_results) {
|
|
||||||
console.log(`hosted_file_results:`, hosted_file_results);
|
|
||||||
} else {
|
|
||||||
console.log(`hosted_file_results:`, hosted_file_results);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// hosted_file_results = await handle_input_upload_files(event.target[input_element_id].files, task_id);
|
|
||||||
$ae_sess.files.processed_file_list = [];
|
|
||||||
$ae_sess = $ae_sess; // Is this needed? 2025-03-17
|
|
||||||
target.reset();
|
|
||||||
// await tick();
|
|
||||||
|
|
||||||
if (log_lvl) {
|
|
||||||
console.log(`hosted_file_id_li: ${hosted_file_id_li}`, hosted_file_id_li);
|
|
||||||
} else if (log_lvl > 1) {
|
|
||||||
console.log('hosted_file_results:', hosted_file_results);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$ae_sess.files.disable_submit__hosted_file_obj = false;
|
|
||||||
$ae_sess.files.submit_status = 'saved';
|
|
||||||
submit_status = 'saved';
|
|
||||||
upload_complete = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function handle_input_upload_files({
|
|
||||||
input_upload_files,
|
|
||||||
task_id
|
|
||||||
}: {
|
|
||||||
input_upload_files: any[];
|
|
||||||
task_id: string;
|
|
||||||
}) {
|
|
||||||
console.log('*** handle_input_upload_files() ***');
|
|
||||||
|
|
||||||
const form_data = new FormData();
|
|
||||||
|
|
||||||
form_data.append('account_id', $ae_loc.account_id);
|
|
||||||
form_data.append('link_to_type', link_to_type);
|
|
||||||
form_data.append('link_to_id', link_to_id);
|
|
||||||
|
|
||||||
for (let i = 0; i < input_upload_files.length; i++) {
|
|
||||||
form_data.append(`file_list`, input_upload_files[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// hash_sha256, uploaded, uploaded_bytes
|
|
||||||
// $ae_sess.files.processed_file_list[i] = {
|
|
||||||
// ...$ae_sess.files.processed_file_list[i],
|
|
||||||
// uploaded: $ae_sess.api_upload_kv[link_to_id].percent_completed,
|
|
||||||
// uploaded_bytes: $ae_sess.api_upload_kv[link_to_id].uploaded_bytes,
|
|
||||||
// };
|
|
||||||
|
|
||||||
let params = null;
|
|
||||||
|
|
||||||
let endpoint = '/hosted_file/upload_files';
|
|
||||||
|
|
||||||
console.log(form_data);
|
|
||||||
|
|
||||||
params = null;
|
|
||||||
|
|
||||||
// Uncomment and the post_promise is not seen by the "await" below
|
|
||||||
// post_promise = await api.post_object({api_cfg: $cfg.api, endpoint: endpoint, params: params, data:form_data});
|
|
||||||
// Uncomment so that the post_promise is not seen by the "await" below
|
|
||||||
ae_promises.upload__hosted_file_obj = api
|
|
||||||
.post_object({
|
|
||||||
api_cfg: $ae_api,
|
|
||||||
endpoint: endpoint,
|
|
||||||
// params: params,
|
|
||||||
form_data: form_data,
|
|
||||||
task_id: task_id,
|
|
||||||
log_lvl: log_lvl
|
|
||||||
// retry_count: 1,
|
|
||||||
})
|
|
||||||
.then(async function (result) {
|
|
||||||
// WARNING!!!! ONLY ONE FILE IS EXPECTED TO BE UPLOADED AT A TIME!!!
|
|
||||||
// NOTE: The /hosted_file/upload_files endpoint will always return a list of successful files uploaded. In this case we are only uploading one file and expecting a list of one item.
|
|
||||||
let x = 0;
|
|
||||||
console.log(result[x]);
|
|
||||||
let hosted_file_obj = result[x];
|
|
||||||
|
|
||||||
let hosted_file_id = hosted_file_obj.hosted_file_id;
|
|
||||||
|
|
||||||
hosted_file_id_li.push(hosted_file_id);
|
|
||||||
hosted_file_obj_li.push(hosted_file_obj);
|
|
||||||
|
|
||||||
let hosted_file_data: key_val = {};
|
|
||||||
hosted_file_data['id'] = hosted_file_id; // Same as the hosted_file_id
|
|
||||||
hosted_file_data['hosted_file_id'] = hosted_file_id;
|
|
||||||
hosted_file_data['for_type'] = link_to_type;
|
|
||||||
hosted_file_data['for_id'] = link_to_id;
|
|
||||||
hosted_file_data['hash_sha256'] = hosted_file_obj.hash_sha256;
|
|
||||||
hosted_file_data['filename'] = hosted_file_obj.filename;
|
|
||||||
hosted_file_data['extension'] = hosted_file_obj.extension;
|
|
||||||
hosted_file_data['content_type'] = hosted_file_obj.content_type;
|
|
||||||
hosted_file_data['size'] = hosted_file_obj.size;
|
|
||||||
hosted_file_data['enable'] = true;
|
|
||||||
hosted_file_data['created_on'] = hosted_file_obj.created_on;
|
|
||||||
hosted_file_data['updated_on'] = hosted_file_obj.updated_on;
|
|
||||||
console.log(hosted_file_data);
|
|
||||||
|
|
||||||
hosted_file_obj_kv[hosted_file_id] = hosted_file_data;
|
|
||||||
|
|
||||||
if (log_lvl) {
|
|
||||||
console.log(`hosted_file_data:`, hosted_file_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hosted_file_data;
|
|
||||||
|
|
||||||
// $ae_sess.files.new_upload_list[i].uploaded_bytes = 10; // fake 10 bytes at least...
|
|
||||||
|
|
||||||
// let event_file_id = await events_func.create_hosted_file_obj_from_hosted_file_async({
|
|
||||||
// api_cfg: $ae_api,
|
|
||||||
// hosted_file_id: hosted_file_id,
|
|
||||||
// data: event_file_data,
|
|
||||||
// log_lvl: log_lvl
|
|
||||||
// })
|
|
||||||
// .then(function (create_result) {
|
|
||||||
// console.log(create_result); // NOTE: This should be the event_file_id string
|
|
||||||
// // let event_file_id = create_result;
|
|
||||||
// return create_result;
|
|
||||||
// });
|
|
||||||
|
|
||||||
// return event_file_id;
|
|
||||||
})
|
|
||||||
// .then(function (hosted_file_data) {
|
|
||||||
// return hosted_file_data;
|
|
||||||
// })
|
|
||||||
.catch(function (error: any) {
|
|
||||||
console.log('Something went wrong.');
|
|
||||||
console.log(error);
|
|
||||||
return false;
|
|
||||||
})
|
|
||||||
.finally(function () {
|
|
||||||
$slct_trigger = 'load__hosted_file_obj_li';
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (log_lvl) {
|
if (hosted_file_results) {
|
||||||
console.log(`Waiting for upload__hosted_file_obj promise...`);
|
console.log(`hosted_file_results:`, hosted_file_results);
|
||||||
|
} else {
|
||||||
|
console.log(`hosted_file_results:`, hosted_file_results);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let hosted_file_result = ae_promises.upload__hosted_file_obj;
|
// hosted_file_results = await handle_input_upload_files(event.target[input_element_id].files, task_id);
|
||||||
|
$ae_sess.files.processed_file_list = [];
|
||||||
|
$ae_sess = $ae_sess; // Is this needed? 2025-03-17
|
||||||
|
target.reset();
|
||||||
|
// await tick();
|
||||||
|
|
||||||
return hosted_file_result;
|
if (log_lvl) {
|
||||||
|
console.log(
|
||||||
|
`hosted_file_id_li: ${hosted_file_id_li}`,
|
||||||
|
hosted_file_id_li
|
||||||
|
);
|
||||||
|
} else if (log_lvl > 1) {
|
||||||
|
console.log('hosted_file_results:', hosted_file_results);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$ae_sess.files.disable_submit__hosted_file_obj = false;
|
||||||
|
$ae_sess.files.submit_status = 'saved';
|
||||||
|
submit_status = 'saved';
|
||||||
|
upload_complete = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handle_input_upload_files({
|
||||||
|
input_upload_files,
|
||||||
|
task_id
|
||||||
|
}: {
|
||||||
|
input_upload_files: any[];
|
||||||
|
task_id: string;
|
||||||
|
}) {
|
||||||
|
console.log('*** handle_input_upload_files() ***');
|
||||||
|
|
||||||
|
const form_data = new FormData();
|
||||||
|
|
||||||
|
form_data.append('account_id', $ae_loc.account_id);
|
||||||
|
form_data.append('link_to_type', link_to_type);
|
||||||
|
form_data.append('link_to_id', link_to_id);
|
||||||
|
|
||||||
|
for (let i = 0; i < input_upload_files.length; i++) {
|
||||||
|
form_data.append(`file_list`, input_upload_files[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// hash_sha256, uploaded, uploaded_bytes
|
||||||
|
// $ae_sess.files.processed_file_list[i] = {
|
||||||
|
// ...$ae_sess.files.processed_file_list[i],
|
||||||
|
// uploaded: $ae_sess.api_upload_kv[link_to_id].percent_completed,
|
||||||
|
// uploaded_bytes: $ae_sess.api_upload_kv[link_to_id].uploaded_bytes,
|
||||||
|
// };
|
||||||
|
|
||||||
|
let params = null;
|
||||||
|
|
||||||
|
let endpoint = '/hosted_file/upload_files';
|
||||||
|
|
||||||
|
console.log(form_data);
|
||||||
|
|
||||||
|
params = null;
|
||||||
|
|
||||||
|
// Uncomment and the post_promise is not seen by the "await" below
|
||||||
|
// post_promise = await api.post_object({api_cfg: $cfg.api, endpoint: endpoint, params: params, data:form_data});
|
||||||
|
// Uncomment so that the post_promise is not seen by the "await" below
|
||||||
|
ae_promises.upload__hosted_file_obj = api
|
||||||
|
.post_object({
|
||||||
|
api_cfg: $ae_api,
|
||||||
|
endpoint: endpoint,
|
||||||
|
// params: params,
|
||||||
|
form_data: form_data,
|
||||||
|
task_id: task_id,
|
||||||
|
log_lvl: log_lvl
|
||||||
|
// retry_count: 1,
|
||||||
|
})
|
||||||
|
.then(async function (result) {
|
||||||
|
// WARNING!!!! ONLY ONE FILE IS EXPECTED TO BE UPLOADED AT A TIME!!!
|
||||||
|
// NOTE: The /hosted_file/upload_files endpoint will always return a list of successful files uploaded. In this case we are only uploading one file and expecting a list of one item.
|
||||||
|
let x = 0;
|
||||||
|
console.log(result[x]);
|
||||||
|
let hosted_file_obj = result[x];
|
||||||
|
|
||||||
|
let hosted_file_id = hosted_file_obj.hosted_file_id;
|
||||||
|
|
||||||
|
hosted_file_id_li.push(hosted_file_id);
|
||||||
|
hosted_file_obj_li.push(hosted_file_obj);
|
||||||
|
|
||||||
|
let hosted_file_data: key_val = {};
|
||||||
|
hosted_file_data['id'] = hosted_file_id; // Same as the hosted_file_id
|
||||||
|
hosted_file_data['hosted_file_id'] = hosted_file_id;
|
||||||
|
hosted_file_data['for_type'] = link_to_type;
|
||||||
|
hosted_file_data['for_id'] = link_to_id;
|
||||||
|
hosted_file_data['hash_sha256'] = hosted_file_obj.hash_sha256;
|
||||||
|
hosted_file_data['filename'] = hosted_file_obj.filename;
|
||||||
|
hosted_file_data['extension'] = hosted_file_obj.extension;
|
||||||
|
hosted_file_data['content_type'] = hosted_file_obj.content_type;
|
||||||
|
hosted_file_data['size'] = hosted_file_obj.size;
|
||||||
|
hosted_file_data['enable'] = true;
|
||||||
|
hosted_file_data['created_on'] = hosted_file_obj.created_on;
|
||||||
|
hosted_file_data['updated_on'] = hosted_file_obj.updated_on;
|
||||||
|
console.log(hosted_file_data);
|
||||||
|
|
||||||
|
hosted_file_obj_kv[hosted_file_id] = hosted_file_data;
|
||||||
|
|
||||||
|
if (log_lvl) {
|
||||||
|
console.log(`hosted_file_data:`, hosted_file_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hosted_file_data;
|
||||||
|
|
||||||
|
// $ae_sess.files.new_upload_list[i].uploaded_bytes = 10; // fake 10 bytes at least...
|
||||||
|
|
||||||
|
// let event_file_id = await events_func.create_hosted_file_obj_from_hosted_file_async({
|
||||||
|
// api_cfg: $ae_api,
|
||||||
|
// hosted_file_id: hosted_file_id,
|
||||||
|
// data: event_file_data,
|
||||||
|
// log_lvl: log_lvl
|
||||||
|
// })
|
||||||
|
// .then(function (create_result) {
|
||||||
|
// console.log(create_result); // NOTE: This should be the event_file_id string
|
||||||
|
// // let event_file_id = create_result;
|
||||||
|
// return create_result;
|
||||||
|
// });
|
||||||
|
|
||||||
|
// return event_file_id;
|
||||||
|
})
|
||||||
|
// .then(function (hosted_file_data) {
|
||||||
|
// return hosted_file_data;
|
||||||
|
// })
|
||||||
|
.catch(function (error: any) {
|
||||||
|
console.log('Something went wrong.');
|
||||||
|
console.log(error);
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
.finally(function () {
|
||||||
|
$slct_trigger = 'load__hosted_file_obj_li';
|
||||||
|
});
|
||||||
|
|
||||||
|
if (log_lvl) {
|
||||||
|
console.log(`Waiting for upload__hosted_file_obj promise...`);
|
||||||
|
}
|
||||||
|
let hosted_file_result = ae_promises.upload__hosted_file_obj;
|
||||||
|
|
||||||
|
return hosted_file_result;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- class:hidden={!$ae_loc.trusted_access} -->
|
<!-- class:hidden={!$ae_loc.trusted_access} -->
|
||||||
<form onsubmit={handle_submit_form_files} class="{class_li_default} {class_li}">
|
<form onsubmit={handle_submit_form_files} class="{class_li_default} {class_li}">
|
||||||
{#await ae_promises.upload__hosted_file_obj}
|
{#await ae_promises.upload__hosted_file_obj}
|
||||||
<div class="text-lg flex flex-row gap-1 items-center justify-center">
|
<div class="flex flex-row items-center justify-center gap-1 text-lg">
|
||||||
<Lucide.LoaderCircle class="animate-spin m-1" />
|
<Lucide.LoaderCircle class="m-1 animate-spin" />
|
||||||
<span class="">
|
<span class="">
|
||||||
Uploading
|
Uploading
|
||||||
{#if $ae_sess.api_upload_kv[task_id]}
|
{#if $ae_sess.api_upload_kv[task_id]}
|
||||||
@@ -288,14 +293,14 @@
|
|||||||
<label
|
<label
|
||||||
for="ae_comp__hosted_files_upload__input"
|
for="ae_comp__hosted_files_upload__input"
|
||||||
class="svelte_input_file_label text-center"
|
class="svelte_input_file_label text-center"
|
||||||
class:hidden={$ae_sess.files.disable_submit__hosted_file_obj}
|
class:hidden={$ae_sess.files.disable_submit__hosted_file_obj}>
|
||||||
>
|
|
||||||
{#if label}{@render label()}{:else}
|
{#if label}{@render label()}{:else}
|
||||||
<div class="flex items-center justify-center gap-2 mb-2">
|
<div class="mb-2 flex items-center justify-center gap-2">
|
||||||
<Lucide.Upload class="text-primary-500" />
|
<Lucide.Upload class="text-primary-500" />
|
||||||
<strong class="preset-tonal-primary px-3 py-1 rounded-full">Select Files</strong>
|
<strong class="preset-tonal-primary rounded-full px-3 py-1"
|
||||||
|
>Select Files</strong>
|
||||||
</div>
|
</div>
|
||||||
<span class="text-sm text-gray-600 dark:text-gray-400 italic">
|
<span class="text-sm text-gray-600 italic dark:text-gray-400">
|
||||||
<strong>Supported formats</strong><br />
|
<strong>Supported formats</strong><br />
|
||||||
(PowerPoint, Keynote, PDF, Media, etc)
|
(PowerPoint, Keynote, PDF, Media, etc)
|
||||||
</span>
|
</span>
|
||||||
@@ -313,33 +318,30 @@
|
|||||||
class="
|
class="
|
||||||
svelte_input_file_element
|
svelte_input_file_element
|
||||||
file-dropzone-input
|
file-dropzone-input
|
||||||
px-1
|
|
||||||
block w-full text-lg
|
|
||||||
preset-filled-surface-50-950
|
preset-filled-surface-50-950
|
||||||
text-surface-900 dark:text-surface-100
|
text-surface-900 dark:text-surface-100 border-surface-300
|
||||||
border border-surface-300 dark:border-surface-700 rounded-lg
|
dark:border-surface-700
|
||||||
cursor-pointer
|
focus:ring-primary-500 block
|
||||||
focus:outline-hidden focus:ring-2 focus:ring-primary-500
|
w-full cursor-pointer rounded-lg border
|
||||||
|
px-1
|
||||||
|
text-lg focus:ring-2 focus:outline-hidden
|
||||||
{input_class_li.join(' ')}
|
{input_class_li.join(' ')}
|
||||||
"
|
"
|
||||||
class:hidden={$ae_sess.files.disable_submit__hosted_file_obj}
|
class:hidden={$ae_sess.files.disable_submit__hosted_file_obj} />
|
||||||
/>
|
|
||||||
|
|
||||||
<Element_input_files_tbl
|
<Element_input_files_tbl
|
||||||
bind:input_file_list
|
bind:input_file_list
|
||||||
bind:file_list_status={$ae_sess.files.status__file_list}
|
bind:file_list_status={$ae_sess.files.status__file_list}
|
||||||
bind:processed_file_list={$ae_sess.files.processed_file_list}
|
bind:processed_file_list={$ae_sess.files.processed_file_list}
|
||||||
{table_class_li}
|
{table_class_li} />
|
||||||
/>
|
|
||||||
|
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
class="btn btn-lg btn-primary preset-tonal-primary border border-primary-500 hover:preset-tonal-success hover:border-success-500 w-54"
|
class="btn btn-lg btn-primary preset-tonal-primary border-primary-500 hover:preset-tonal-success hover:border-success-500 w-54 border"
|
||||||
disabled={$ae_sess.files.disable_submit__hosted_file_obj ||
|
disabled={$ae_sess.files.disable_submit__hosted_file_obj ||
|
||||||
$ae_sess.files.status__file_list != 'ready'}
|
$ae_sess.files.status__file_list != 'ready'}>
|
||||||
>
|
|
||||||
{#await ae_promises.upload__hosted_file_obj}
|
{#await ae_promises.upload__hosted_file_obj}
|
||||||
<Lucide.LoaderCircle class="animate-spin m-1" />
|
<Lucide.LoaderCircle class="m-1 animate-spin" />
|
||||||
<span class="">
|
<span class="">
|
||||||
{#if $ae_sess.api_upload_kv[task_id]}
|
{#if $ae_sess.api_upload_kv[task_id]}
|
||||||
{$ae_sess.api_upload_kv[task_id].percent_completed}%
|
{$ae_sess.api_upload_kv[task_id].percent_completed}%
|
||||||
@@ -350,9 +352,12 @@
|
|||||||
{:then}
|
{:then}
|
||||||
<Lucide.UploadCloud class="m-1" size={20} />
|
<Lucide.UploadCloud class="m-1" size={20} />
|
||||||
<span class="text-sm"> Upload </span>
|
<span class="text-sm"> Upload </span>
|
||||||
<span class="grow font-bold ml-2">
|
<span class="ml-2 grow font-bold">
|
||||||
{#if $ae_sess.files.processed_file_list?.length > 0}
|
{#if $ae_sess.files.processed_file_list?.length > 0}
|
||||||
{$ae_sess.files.processed_file_list.length} { $ae_sess.files.processed_file_list.length === 1 ? 'file' : 'files' }
|
{$ae_sess.files.processed_file_list.length}
|
||||||
|
{$ae_sess.files.processed_file_list.length === 1
|
||||||
|
? 'file'
|
||||||
|
: 'files'}
|
||||||
{:else}
|
{:else}
|
||||||
<span class="text-xs"> 0 </span>
|
<span class="text-xs"> 0 </span>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -1,235 +1,358 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { untrack } from 'svelte';
|
import { untrack } from 'svelte';
|
||||||
/**
|
/**
|
||||||
* AE_Comp_Site_Config_Editor.svelte
|
* AE_Comp_Site_Config_Editor.svelte
|
||||||
* Specialized UI for managing site.cfg_json settings.
|
* Specialized UI for managing site.cfg_json settings.
|
||||||
* Supports General, AI, Performance, and IDAA-specific configurations.
|
* Supports General, AI, Performance, and IDAA-specific configurations.
|
||||||
*/
|
*/
|
||||||
import { Modal } from 'flowbite-svelte';
|
import { Modal } from 'flowbite-svelte';
|
||||||
import { Brain, CodeXml, ExternalLink, Globe, Mail, Minus, Palette, Plus, Save, ShieldCheck, Timer } from '@lucide/svelte';
|
import {
|
||||||
import AE_Comp_Editor_CodeMirror from '$lib/elements/element_editor_codemirror.svelte';
|
Brain,
|
||||||
import { ae_loc } from '$lib/stores/ae_stores';
|
CodeXml,
|
||||||
|
ExternalLink,
|
||||||
|
Globe,
|
||||||
|
Mail,
|
||||||
|
Minus,
|
||||||
|
Palette,
|
||||||
|
Plus,
|
||||||
|
Save,
|
||||||
|
ShieldCheck,
|
||||||
|
Timer
|
||||||
|
} from '@lucide/svelte';
|
||||||
|
import AE_Comp_Editor_CodeMirror from '$lib/elements/element_editor_codemirror.svelte';
|
||||||
|
import { ae_loc } from '$lib/stores/ae_stores';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
cfg_json: any;
|
cfg_json: any;
|
||||||
on_save?: () => void;
|
on_save?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
let { cfg_json = $bindable({}), on_save }: Props = $props();
|
let { cfg_json = $bindable({}), on_save }: Props = $props();
|
||||||
|
|
||||||
// Ensure we have a valid object (handle strings/nulls)
|
// Ensure we have a valid object (handle strings/nulls)
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (typeof cfg_json === 'string') {
|
if (typeof cfg_json === 'string') {
|
||||||
try {
|
try {
|
||||||
cfg_json = JSON.parse(cfg_json);
|
cfg_json = JSON.parse(cfg_json);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
cfg_json = {};
|
cfg_json = {};
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!cfg_json) cfg_json = {};
|
}
|
||||||
});
|
|
||||||
|
|
||||||
// Internal State
|
|
||||||
let active_tab: 'visuals' | 'email' | 'ai' | 'refresh' | 'idaa' | 'raw' = $state('visuals');
|
|
||||||
let raw_json_str = $state('');
|
|
||||||
|
|
||||||
// Ensure we have a valid object
|
|
||||||
if (!cfg_json) cfg_json = {};
|
if (!cfg_json) cfg_json = {};
|
||||||
|
});
|
||||||
|
|
||||||
function add_to_list(key: string) {
|
// Internal State
|
||||||
if (!cfg_json[key]) cfg_json[key] = [];
|
let active_tab: 'visuals' | 'email' | 'ai' | 'refresh' | 'idaa' | 'raw' =
|
||||||
const val = prompt('Enter Novi UUID:');
|
$state('visuals');
|
||||||
if (val) cfg_json[key].push(val);
|
let raw_json_str = $state('');
|
||||||
|
|
||||||
|
// Ensure we have a valid object
|
||||||
|
if (!cfg_json) cfg_json = {};
|
||||||
|
|
||||||
|
function add_to_list(key: string) {
|
||||||
|
if (!cfg_json[key]) cfg_json[key] = [];
|
||||||
|
const val = prompt('Enter Novi UUID:');
|
||||||
|
if (val) cfg_json[key].push(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
function remove_from_list(key: string, index: number) {
|
||||||
|
cfg_json[key].splice(index, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sync Raw JSON string when entering the tab
|
||||||
|
$effect(() => {
|
||||||
|
if (active_tab === 'raw') {
|
||||||
|
untrack(() => {
|
||||||
|
raw_json_str = JSON.stringify(cfg_json, null, 2);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
function remove_from_list(key: string, index: number) {
|
// Update cfg_json when raw string changes
|
||||||
cfg_json[key].splice(index, 1);
|
$effect(() => {
|
||||||
|
if (active_tab === 'raw' && raw_json_str) {
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(raw_json_str);
|
||||||
|
cfg_json = parsed;
|
||||||
|
} catch (e) {
|
||||||
|
// Ignore invalid JSON while typing
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
// Sync Raw JSON string when entering the tab
|
|
||||||
$effect(() => {
|
|
||||||
if (active_tab === 'raw') {
|
|
||||||
untrack(() => {
|
|
||||||
raw_json_str = JSON.stringify(cfg_json, null, 2);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update cfg_json when raw string changes
|
|
||||||
$effect(() => {
|
|
||||||
if (active_tab === 'raw' && raw_json_str) {
|
|
||||||
try {
|
|
||||||
const parsed = JSON.parse(raw_json_str);
|
|
||||||
cfg_json = parsed;
|
|
||||||
} catch (e) {
|
|
||||||
// Ignore invalid JSON while typing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="ae-site-config-editor flex flex-col h-full space-y-4">
|
<div class="ae-site-config-editor flex h-full flex-col space-y-4">
|
||||||
<!-- Tab Navigation -->
|
<!-- Tab Navigation -->
|
||||||
<div class="flex flex-wrap gap-1 p-1 bg-surface-500/10 rounded-lg max-w-fit">
|
<div
|
||||||
<button class="btn btn-sm transition-all {active_tab === 'visuals' ? 'variant-filled-primary' : 'variant-soft-surface'}" onclick={() => active_tab = 'visuals'}>
|
class="bg-surface-500/10 flex max-w-fit flex-wrap gap-1 rounded-lg p-1">
|
||||||
|
<button
|
||||||
|
class="btn btn-sm transition-all {active_tab === 'visuals'
|
||||||
|
? 'variant-filled-primary'
|
||||||
|
: 'variant-soft-surface'}"
|
||||||
|
onclick={() => (active_tab = 'visuals')}>
|
||||||
<Palette size="1.1em" class="mr-1" /> Visuals
|
<Palette size="1.1em" class="mr-1" /> Visuals
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-sm transition-all {active_tab === 'email' ? 'variant-filled-primary' : 'variant-soft-surface'}" onclick={() => active_tab = 'email'}>
|
<button
|
||||||
|
class="btn btn-sm transition-all {active_tab === 'email'
|
||||||
|
? 'variant-filled-primary'
|
||||||
|
: 'variant-soft-surface'}"
|
||||||
|
onclick={() => (active_tab = 'email')}>
|
||||||
<Mail size="1.1em" class="mr-1" /> Email
|
<Mail size="1.1em" class="mr-1" /> Email
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-sm transition-all {active_tab === 'ai' ? 'variant-filled-primary' : 'variant-soft-surface'}" onclick={() => active_tab = 'ai'}>
|
<button
|
||||||
|
class="btn btn-sm transition-all {active_tab === 'ai'
|
||||||
|
? 'variant-filled-primary'
|
||||||
|
: 'variant-soft-surface'}"
|
||||||
|
onclick={() => (active_tab = 'ai')}>
|
||||||
<Brain size="1.1em" class="mr-1" /> AI/LLM
|
<Brain size="1.1em" class="mr-1" /> AI/LLM
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-sm transition-all {active_tab === 'refresh' ? 'variant-filled-primary' : 'variant-soft-surface'}" onclick={() => active_tab = 'refresh'}>
|
<button
|
||||||
|
class="btn btn-sm transition-all {active_tab === 'refresh'
|
||||||
|
? 'variant-filled-primary'
|
||||||
|
: 'variant-soft-surface'}"
|
||||||
|
onclick={() => (active_tab = 'refresh')}>
|
||||||
<Timer size="1.1em" class="mr-1" /> Refresh
|
<Timer size="1.1em" class="mr-1" /> Refresh
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-sm transition-all {active_tab === 'idaa' ? 'variant-filled-primary' : 'variant-soft-surface'}" onclick={() => active_tab = 'idaa'}>
|
<button
|
||||||
|
class="btn btn-sm transition-all {active_tab === 'idaa'
|
||||||
|
? 'variant-filled-primary'
|
||||||
|
: 'variant-soft-surface'}"
|
||||||
|
onclick={() => (active_tab = 'idaa')}>
|
||||||
<ShieldCheck size="1.1em" class="mr-1" /> IDAA
|
<ShieldCheck size="1.1em" class="mr-1" /> IDAA
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-sm transition-all {active_tab === 'raw' ? 'variant-filled-primary' : 'variant-soft-surface'}" onclick={() => active_tab = 'raw'}>
|
<button
|
||||||
|
class="btn btn-sm transition-all {active_tab === 'raw'
|
||||||
|
? 'variant-filled-primary'
|
||||||
|
: 'variant-soft-surface'}"
|
||||||
|
onclick={() => (active_tab = 'raw')}>
|
||||||
<CodeXml size="1.1em" class="mr-1" /> Raw JSON
|
<CodeXml size="1.1em" class="mr-1" /> Raw JSON
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Scrollable Content Area -->
|
<!-- Scrollable Content Area -->
|
||||||
<div class="grow overflow-y-auto p-1 pr-2 space-y-6 max-h-[60vh]">
|
<div class="max-h-[60vh] grow space-y-6 overflow-y-auto p-1 pr-2">
|
||||||
|
|
||||||
{#if active_tab === 'visuals'}
|
{#if active_tab === 'visuals'}
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 animate-in fade-in duration-200">
|
<div
|
||||||
|
class="animate-in fade-in grid grid-cols-1 gap-4 duration-200 md:grid-cols-2">
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="text-xs font-bold uppercase opacity-50">Theme Name</span>
|
<span class="text-xs font-bold uppercase opacity-50"
|
||||||
<input type="text" bind:value={cfg_json.theme_name} class="input variant-form-material" placeholder="e.g. AE_OSIT_default" />
|
>Theme Name</span>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
bind:value={cfg_json.theme_name}
|
||||||
|
class="input variant-form-material"
|
||||||
|
placeholder="e.g. AE_OSIT_default" />
|
||||||
</label>
|
</label>
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="text-xs font-bold uppercase opacity-50">Theme Mode</span>
|
<span class="text-xs font-bold uppercase opacity-50"
|
||||||
<select bind:value={cfg_json.theme_mode} class="select variant-form-material">
|
>Theme Mode</span>
|
||||||
|
<select
|
||||||
|
bind:value={cfg_json.theme_mode}
|
||||||
|
class="select variant-form-material">
|
||||||
<option value="light">Light</option>
|
<option value="light">Light</option>
|
||||||
<option value="dark">Dark</option>
|
<option value="dark">Dark</option>
|
||||||
<option value="auto">Auto (System)</option>
|
<option value="auto">Auto (System)</option>
|
||||||
</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
<label class="label md:col-span-2">
|
<label class="label md:col-span-2">
|
||||||
<span class="text-xs font-bold uppercase opacity-50">Header Image Path (URL)</span>
|
<span class="text-xs font-bold uppercase opacity-50"
|
||||||
|
>Header Image Path (URL)</span>
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<input type="text" bind:value={cfg_json.header_image_path} class="input variant-form-material grow" placeholder="https://..." />
|
<input
|
||||||
|
type="text"
|
||||||
|
bind:value={cfg_json.header_image_path}
|
||||||
|
class="input variant-form-material grow"
|
||||||
|
placeholder="https://..." />
|
||||||
{#if cfg_json.header_image_path}
|
{#if cfg_json.header_image_path}
|
||||||
<a href={cfg_json.header_image_path} target="_blank" rel="noopener noreferrer" class="btn-icon variant-soft-surface"><ExternalLink size="1.2em" /></a>
|
<a
|
||||||
|
href={cfg_json.header_image_path}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
class="btn-icon variant-soft-surface"
|
||||||
|
><ExternalLink size="1.2em" /></a>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{:else if active_tab === 'email'}
|
{:else if active_tab === 'email'}
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 animate-in fade-in duration-200">
|
<div
|
||||||
<section class="space-y-4 border-r border-surface-500/10 pr-4">
|
class="animate-in fade-in grid grid-cols-1 gap-4 duration-200 md:grid-cols-2">
|
||||||
<h4 class="text-sm font-black text-primary-500">Admin Contact</h4>
|
<section class="border-surface-500/10 space-y-4 border-r pr-4">
|
||||||
|
<h4 class="text-primary-500 text-sm font-black">
|
||||||
|
Admin Contact
|
||||||
|
</h4>
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="text-xs font-bold uppercase opacity-50">Admin Name</span>
|
<span class="text-xs font-bold uppercase opacity-50"
|
||||||
<input type="text" bind:value={cfg_json.admin_name} class="input variant-form-material" />
|
>Admin Name</span>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
bind:value={cfg_json.admin_name}
|
||||||
|
class="input variant-form-material" />
|
||||||
</label>
|
</label>
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="text-xs font-bold uppercase opacity-50">Admin Email</span>
|
<span class="text-xs font-bold uppercase opacity-50"
|
||||||
<input type="email" bind:value={cfg_json.admin_email} class="input variant-form-material" />
|
>Admin Email</span>
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
bind:value={cfg_json.admin_email}
|
||||||
|
class="input variant-form-material" />
|
||||||
</label>
|
</label>
|
||||||
</section>
|
</section>
|
||||||
<section class="space-y-4">
|
<section class="space-y-4">
|
||||||
<h4 class="text-sm font-black text-secondary-500">System (No-Reply)</h4>
|
<h4 class="text-secondary-500 text-sm font-black">
|
||||||
|
System (No-Reply)
|
||||||
|
</h4>
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="text-xs font-bold uppercase opacity-50">No-Reply Name</span>
|
<span class="text-xs font-bold uppercase opacity-50"
|
||||||
<input type="text" bind:value={cfg_json.noreply_name} class="input variant-form-material" />
|
>No-Reply Name</span>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
bind:value={cfg_json.noreply_name}
|
||||||
|
class="input variant-form-material" />
|
||||||
</label>
|
</label>
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="text-xs font-bold uppercase opacity-50">No-Reply Email</span>
|
<span class="text-xs font-bold uppercase opacity-50"
|
||||||
<input type="email" bind:value={cfg_json.noreply_email} class="input variant-form-material" />
|
>No-Reply Email</span>
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
bind:value={cfg_json.noreply_email}
|
||||||
|
class="input variant-form-material" />
|
||||||
</label>
|
</label>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{:else if active_tab === 'ai'}
|
{:else if active_tab === 'ai'}
|
||||||
<div class="space-y-4 animate-in fade-in duration-200">
|
<div class="animate-in fade-in space-y-4 duration-200">
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="text-xs font-bold uppercase opacity-50">LLM API Base URL</span>
|
<span class="text-xs font-bold uppercase opacity-50"
|
||||||
<input type="text" bind:value={cfg_json.llm__api_base_url} class="input variant-form-material" />
|
>LLM API Base URL</span>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
bind:value={cfg_json.llm__api_base_url}
|
||||||
|
class="input variant-form-material" />
|
||||||
</label>
|
</label>
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="text-xs font-bold uppercase opacity-50">LLM Model</span>
|
<span class="text-xs font-bold uppercase opacity-50"
|
||||||
<input type="text" bind:value={cfg_json.llm__api_model} class="input variant-form-material" />
|
>LLM Model</span>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
bind:value={cfg_json.llm__api_model}
|
||||||
|
class="input variant-form-material" />
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="text-xs font-bold uppercase opacity-50">API Token</span>
|
<span class="text-xs font-bold uppercase opacity-50"
|
||||||
<input type="password" bind:value={cfg_json.llm__api_token} class="input variant-form-material font-mono" />
|
>API Token</span>
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
bind:value={cfg_json.llm__api_token}
|
||||||
|
class="input variant-form-material font-mono" />
|
||||||
</label>
|
</label>
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="text-xs font-bold uppercase opacity-50">System Prompt</span>
|
<span class="text-xs font-bold uppercase opacity-50"
|
||||||
<textarea bind:value={cfg_json.llm__system_prompt} class="textarea variant-form-material h-24 text-sm"></textarea>
|
>System Prompt</span>
|
||||||
|
<textarea
|
||||||
|
bind:value={cfg_json.llm__system_prompt}
|
||||||
|
class="textarea variant-form-material h-24 text-sm"
|
||||||
|
></textarea>
|
||||||
</label>
|
</label>
|
||||||
<label class="flex items-center space-x-2">
|
<label class="flex items-center space-x-2">
|
||||||
<input type="checkbox" bind:checked={cfg_json.llm__api_dangerous_browser} class="checkbox" />
|
<input
|
||||||
<span class="text-xs font-bold uppercase opacity-50">Allow Browser Fetch (Dangerously)</span>
|
type="checkbox"
|
||||||
|
bind:checked={cfg_json.llm__api_dangerous_browser}
|
||||||
|
class="checkbox" />
|
||||||
|
<span class="text-xs font-bold uppercase opacity-50"
|
||||||
|
>Allow Browser Fetch (Dangerously)</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{:else if active_tab === 'refresh'}
|
{:else if active_tab === 'refresh'}
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 animate-in fade-in duration-200">
|
<div
|
||||||
|
class="animate-in fade-in grid grid-cols-1 gap-4 duration-200 md:grid-cols-2">
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="text-xs font-bold uppercase opacity-50">Default (Minutes)</span>
|
<span class="text-xs font-bold uppercase opacity-50"
|
||||||
<input type="number" bind:value={cfg_json.default_refresh_minutes} class="input variant-form-material" />
|
>Default (Minutes)</span>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
bind:value={cfg_json.default_refresh_minutes}
|
||||||
|
class="input variant-form-material" />
|
||||||
</label>
|
</label>
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="text-xs font-bold uppercase opacity-50">Authenticated (Minutes)</span>
|
<span class="text-xs font-bold uppercase opacity-50"
|
||||||
<input type="number" bind:value={cfg_json.authenticated_refresh_time} class="input variant-form-material" />
|
>Authenticated (Minutes)</span>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
bind:value={cfg_json.authenticated_refresh_time}
|
||||||
|
class="input variant-form-material" />
|
||||||
</label>
|
</label>
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="text-xs font-bold uppercase opacity-50">Trusted (Minutes)</span>
|
<span class="text-xs font-bold uppercase opacity-50"
|
||||||
<input type="number" bind:value={cfg_json.trusted_refresh_minutes} class="input variant-form-material" />
|
>Trusted (Minutes)</span>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
bind:value={cfg_json.trusted_refresh_minutes}
|
||||||
|
class="input variant-form-material" />
|
||||||
</label>
|
</label>
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="text-xs font-bold uppercase opacity-50">Manager (Minutes)</span>
|
<span class="text-xs font-bold uppercase opacity-50"
|
||||||
<input type="number" bind:value={cfg_json.manager_refresh_minutes} class="input variant-form-material" />
|
>Manager (Minutes)</span>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
bind:value={cfg_json.manager_refresh_minutes}
|
||||||
|
class="input variant-form-material" />
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{:else if active_tab === 'idaa'}
|
{:else if active_tab === 'idaa'}
|
||||||
<div class="space-y-6 animate-in fade-in duration-200">
|
<div class="animate-in fade-in space-y-6 duration-200">
|
||||||
<!-- Novi API -->
|
<!-- Novi API -->
|
||||||
<section class="space-y-4 p-4 bg-surface-500/5 rounded-xl border border-surface-500/10">
|
<section
|
||||||
<h4 class="text-sm font-black flex items-center gap-2">
|
class="bg-surface-500/5 border-surface-500/10 space-y-4 rounded-xl border p-4">
|
||||||
|
<h4 class="flex items-center gap-2 text-sm font-black">
|
||||||
<Globe size="1.1em" class="text-primary-500" /> Novi API Connection
|
<Globe size="1.1em" class="text-primary-500" /> Novi API Connection
|
||||||
</h4>
|
</h4>
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="text-xs font-bold uppercase opacity-50">Root URL</span>
|
<span class="text-xs font-bold uppercase opacity-50"
|
||||||
<input type="text" bind:value={cfg_json.novi_api_root_url} class="input variant-form-material" />
|
>Root URL</span>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
bind:value={cfg_json.novi_api_root_url}
|
||||||
|
class="input variant-form-material" />
|
||||||
</label>
|
</label>
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="text-xs font-bold uppercase opacity-50">API Key</span>
|
<span class="text-xs font-bold uppercase opacity-50"
|
||||||
<input type="password" bind:value={cfg_json.novi_idaa_api_key} class="input variant-form-material font-mono" />
|
>API Key</span>
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
bind:value={cfg_json.novi_idaa_api_key}
|
||||||
|
class="input variant-form-material font-mono" />
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- UUID Lists -->
|
<!-- UUID Lists -->
|
||||||
<section class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
<section class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||||
{#each [
|
{#each [{ key: 'novi_admin_li', label: 'Novi Admins', color: 'text-error-500' }, { key: 'novi_trusted_li', label: 'Novi Trusted', color: 'text-warning-500' }, { key: 'novi_jitsi_mod_li', label: 'Jitsi Moderators', color: 'text-primary-500' }, { key: 'novi_idaa_group_guid_li', label: 'Member Group GUIDs', color: 'text-secondary-500' }] as list (list.key)}
|
||||||
{ key: 'novi_admin_li', label: 'Novi Admins', color: 'text-error-500' },
|
<div class="bg-surface-500/5 space-y-2 rounded-lg p-3">
|
||||||
{ key: 'novi_trusted_li', label: 'Novi Trusted', color: 'text-warning-500' },
|
<header class="flex items-center justify-between">
|
||||||
{ key: 'novi_jitsi_mod_li', label: 'Jitsi Moderators', color: 'text-primary-500' },
|
<span
|
||||||
{ key: 'novi_idaa_group_guid_li', label: 'Member Group GUIDs', color: 'text-secondary-500' }
|
class="text-[10px] font-black tracking-wider uppercase {list.color}"
|
||||||
] as list (list.key)}
|
>{list.label}</span>
|
||||||
<div class="space-y-2 p-3 bg-surface-500/5 rounded-lg">
|
<button
|
||||||
<header class="flex justify-between items-center">
|
class="btn btn-icon btn-icon-sm variant-soft-primary"
|
||||||
<span class="text-[10px] font-black uppercase tracking-wider {list.color}">{list.label}</span>
|
onclick={() => add_to_list(list.key)}>
|
||||||
<button class="btn btn-icon btn-icon-sm variant-soft-primary" onclick={() => add_to_list(list.key)}>
|
|
||||||
<Plus size="12" />
|
<Plus size="12" />
|
||||||
</button>
|
</button>
|
||||||
</header>
|
</header>
|
||||||
<div class="space-y-1">
|
<div class="space-y-1">
|
||||||
{#each cfg_json[list.key] ?? [] as uuid, i (uuid)}
|
{#each cfg_json[list.key] ?? [] as uuid, i (uuid)}
|
||||||
<div class="flex gap-1 items-center bg-surface-500/10 p-1 rounded font-mono text-[10px]">
|
<div
|
||||||
<span class="grow truncate">{uuid}</span>
|
class="bg-surface-500/10 flex items-center gap-1 rounded p-1 font-mono text-[10px]">
|
||||||
<button class="text-error-500 hover:scale-110 transition-transform" onclick={() => remove_from_list(list.key, i)}>
|
<span class="grow truncate"
|
||||||
|
>{uuid}</span>
|
||||||
|
<button
|
||||||
|
class="text-error-500 transition-transform hover:scale-110"
|
||||||
|
onclick={() =>
|
||||||
|
remove_from_list(list.key, i)}>
|
||||||
<Minus size="12" />
|
<Minus size="12" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -240,62 +363,96 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Notifications -->
|
<!-- Notifications -->
|
||||||
<section class="grid grid-cols-1 md:grid-cols-2 gap-4 p-4 bg-surface-500/5 rounded-xl">
|
<section
|
||||||
|
class="bg-surface-500/5 grid grid-cols-1 gap-4 rounded-xl p-4 md:grid-cols-2">
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
<h4 class="text-[10px] font-black uppercase opacity-50">Bulletin Board</h4>
|
<h4 class="text-[10px] font-black uppercase opacity-50">
|
||||||
|
Bulletin Board
|
||||||
|
</h4>
|
||||||
<label class="flex items-center space-x-2 text-xs">
|
<label class="flex items-center space-x-2 text-xs">
|
||||||
<input type="checkbox" bind:checked={cfg_json.bb_send_staff_new_email} class="checkbox checkbox-sm" />
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
bind:checked={cfg_json.bb_send_staff_new_email}
|
||||||
|
class="checkbox checkbox-sm" />
|
||||||
<span>Notify Staff (New)</span>
|
<span>Notify Staff (New)</span>
|
||||||
</label>
|
</label>
|
||||||
<label class="flex items-center space-x-2 text-xs">
|
<label class="flex items-center space-x-2 text-xs">
|
||||||
<input type="checkbox" bind:checked={cfg_json.bb_send_staff_update_email} class="checkbox checkbox-sm" />
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
bind:checked={
|
||||||
|
cfg_json.bb_send_staff_update_email
|
||||||
|
}
|
||||||
|
class="checkbox checkbox-sm" />
|
||||||
<span>Notify Staff (Update)</span>
|
<span>Notify Staff (Update)</span>
|
||||||
</label>
|
</label>
|
||||||
<label class="flex items-center space-x-2 text-xs">
|
<label class="flex items-center space-x-2 text-xs">
|
||||||
<input type="checkbox" bind:checked={cfg_json.bb_send_poster_email} class="checkbox checkbox-sm" />
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
bind:checked={cfg_json.bb_send_poster_email}
|
||||||
|
class="checkbox checkbox-sm" />
|
||||||
<span>Notify Poster</span>
|
<span>Notify Poster</span>
|
||||||
</label>
|
</label>
|
||||||
<label class="flex items-center space-x-2 text-xs">
|
<label class="flex items-center space-x-2 text-xs">
|
||||||
<input type="checkbox" bind:checked={cfg_json.bb_send_commenter_email} class="checkbox checkbox-sm" />
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
bind:checked={cfg_json.bb_send_commenter_email}
|
||||||
|
class="checkbox checkbox-sm" />
|
||||||
<span>Notify Commenters</span>
|
<span>Notify Commenters</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
<h4 class="text-[10px] font-black uppercase opacity-50">Recovery Meetings</h4>
|
<h4 class="text-[10px] font-black uppercase opacity-50">
|
||||||
|
Recovery Meetings
|
||||||
|
</h4>
|
||||||
<label class="flex items-center space-x-2 text-xs">
|
<label class="flex items-center space-x-2 text-xs">
|
||||||
<input type="checkbox" bind:checked={cfg_json.recovery_mtg_send_staff_new_email} class="checkbox checkbox-sm" />
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
bind:checked={
|
||||||
|
cfg_json.recovery_mtg_send_staff_new_email
|
||||||
|
}
|
||||||
|
class="checkbox checkbox-sm" />
|
||||||
<span>Notify Staff (New)</span>
|
<span>Notify Staff (New)</span>
|
||||||
</label>
|
</label>
|
||||||
<label class="flex items-center space-x-2 text-xs">
|
<label class="flex items-center space-x-2 text-xs">
|
||||||
<input type="checkbox" bind:checked={cfg_json.recovery_mtg_send_staff_update_email} class="checkbox checkbox-sm" />
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
bind:checked={
|
||||||
|
cfg_json.recovery_mtg_send_staff_update_email
|
||||||
|
}
|
||||||
|
class="checkbox checkbox-sm" />
|
||||||
<span>Notify Staff (Update)</span>
|
<span>Notify Staff (Update)</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{:else if active_tab === 'raw'}
|
{:else if active_tab === 'raw'}
|
||||||
<div class="h-[50vh] animate-in fade-in duration-200">
|
<div class="animate-in fade-in h-[50vh] duration-200">
|
||||||
<AE_Comp_Editor_CodeMirror
|
<AE_Comp_Editor_CodeMirror
|
||||||
content={raw_json_str}
|
content={raw_json_str}
|
||||||
bind:new_content={raw_json_str}
|
bind:new_content={raw_json_str}
|
||||||
language="json"
|
language="json"
|
||||||
theme_mode={$ae_loc.theme_mode}
|
theme_mode={$ae_loc.theme_mode}
|
||||||
class_li="h-full border border-surface-500/20 rounded-lg shadow-inner"
|
class_li="h-full border border-surface-500/20 rounded-lg shadow-inner" />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Action Bar -->
|
<!-- Action Bar -->
|
||||||
<div class="flex justify-between items-center pt-4 border-t border-surface-500/10">
|
<div
|
||||||
|
class="border-surface-500/10 flex items-center justify-between border-t pt-4">
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<label class="flex items-center space-x-2 cursor-pointer">
|
<label class="flex cursor-pointer items-center space-x-2">
|
||||||
<input type="checkbox" bind:checked={cfg_json.test} class="checkbox" />
|
<input
|
||||||
<span class="text-xs font-bold uppercase text-warning-500">Test Mode</span>
|
type="checkbox"
|
||||||
|
bind:checked={cfg_json.test}
|
||||||
|
class="checkbox" />
|
||||||
|
<span class="text-warning-500 text-xs font-bold uppercase"
|
||||||
|
>Test Mode</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-sm variant-filled-primary font-bold shadow-lg" onclick={on_save}>
|
<button
|
||||||
|
class="btn btn-sm variant-filled-primary font-bold shadow-lg"
|
||||||
|
onclick={on_save}>
|
||||||
<Save size="1.1em" class="mr-2" /> Save Config
|
<Save size="1.1em" class="mr-2" /> Save Config
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ export async function load_ae_obj_id__account({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_Account | null> {
|
}): Promise<ae_Account | null> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** load_ae_obj_id__account() *** account_id=${account_id}`);
|
console.log(
|
||||||
|
`*** load_ae_obj_id__account() *** account_id=${account_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ae_promises.load__account_obj = await api
|
ae_promises.load__account_obj = await api
|
||||||
@@ -39,10 +41,11 @@ export async function load_ae_obj_id__account({
|
|||||||
.then(async function (account_obj_get_result) {
|
.then(async function (account_obj_get_result) {
|
||||||
if (account_obj_get_result) {
|
if (account_obj_get_result) {
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
const processed_obj_li = await process_ae_obj__account_props({
|
const processed_obj_li =
|
||||||
obj_li: [account_obj_get_result],
|
await process_ae_obj__account_props({
|
||||||
log_lvl: log_lvl
|
obj_li: [account_obj_get_result],
|
||||||
});
|
log_lvl: log_lvl
|
||||||
|
});
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
db_instance: db_core,
|
db_instance: db_core,
|
||||||
table_name: 'account',
|
table_name: 'account',
|
||||||
@@ -114,10 +117,11 @@ export async function load_ae_obj_li__account({
|
|||||||
.then(async function (account_obj_li_get_result) {
|
.then(async function (account_obj_li_get_result) {
|
||||||
if (account_obj_li_get_result) {
|
if (account_obj_li_get_result) {
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
const processed_obj_li = await process_ae_obj__account_props({
|
const processed_obj_li =
|
||||||
obj_li: account_obj_li_get_result,
|
await process_ae_obj__account_props({
|
||||||
log_lvl: log_lvl
|
obj_li: account_obj_li_get_result,
|
||||||
});
|
log_lvl: log_lvl
|
||||||
|
});
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
db_instance: db_core,
|
db_instance: db_core,
|
||||||
table_name: 'account',
|
table_name: 'account',
|
||||||
@@ -164,10 +168,11 @@ export async function create_ae_obj__account({
|
|||||||
.then(async function (account_obj_create_result) {
|
.then(async function (account_obj_create_result) {
|
||||||
if (account_obj_create_result) {
|
if (account_obj_create_result) {
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
const processed_obj_li = await process_ae_obj__account_props({
|
const processed_obj_li =
|
||||||
obj_li: [account_obj_create_result],
|
await process_ae_obj__account_props({
|
||||||
log_lvl: log_lvl
|
obj_li: [account_obj_create_result],
|
||||||
});
|
log_lvl: log_lvl
|
||||||
|
});
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
db_instance: db_core,
|
db_instance: db_core,
|
||||||
table_name: 'account',
|
table_name: 'account',
|
||||||
@@ -206,7 +211,10 @@ export async function update_ae_obj__account({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_Account | null> {
|
}): Promise<ae_Account | null> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** update_ae_obj__account() *** account_id=${account_id}`, data_kv);
|
console.log(
|
||||||
|
`*** update_ae_obj__account() *** account_id=${account_id}`,
|
||||||
|
data_kv
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await api.update_ae_obj({
|
const result = await api.update_ae_obj({
|
||||||
@@ -256,7 +264,9 @@ export async function delete_ae_obj_id__account({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}) {
|
}) {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** delete_ae_obj_id__account() *** account_id=${account_id}`);
|
console.log(
|
||||||
|
`*** delete_ae_obj_id__account() *** account_id=${account_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ae_promises.delete__account_obj = await api
|
ae_promises.delete__account_obj = await api
|
||||||
@@ -337,11 +347,15 @@ async function _process_generic_props<T extends Record<string, any>>({
|
|||||||
const updated = processed_obj.updated_on ?? processed_obj.created_on;
|
const updated = processed_obj.updated_on ?? processed_obj.created_on;
|
||||||
const name = processed_obj.name ?? '';
|
const name = processed_obj.name ?? '';
|
||||||
|
|
||||||
(processed_obj as any).tmp_sort_1 = `${group}_${priority}_${sort}_${updated}`;
|
(processed_obj as any).tmp_sort_1 =
|
||||||
(processed_obj as any).tmp_sort_2 = `${group}_${priority}_${sort}_${name}_${updated}`;
|
`${group}_${priority}_${sort}_${updated}`;
|
||||||
|
(processed_obj as any).tmp_sort_2 =
|
||||||
|
`${group}_${priority}_${sort}_${name}_${updated}`;
|
||||||
|
|
||||||
if (specific_processor) {
|
if (specific_processor) {
|
||||||
processed_obj = await Promise.resolve(specific_processor(processed_obj));
|
processed_obj = await Promise.resolve(
|
||||||
|
specific_processor(processed_obj)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
processed_obj_li.push(processed_obj as T);
|
processed_obj_li.push(processed_obj as T);
|
||||||
|
|||||||
@@ -19,7 +19,9 @@ export async function load_ae_obj_id__activity_log({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_ActivityLog | null> {
|
}): Promise<ae_ActivityLog | null> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** load_ae_obj_id__activity_log() *** activity_log_id=${activity_log_id}`);
|
console.log(
|
||||||
|
`*** load_ae_obj_id__activity_log() *** activity_log_id=${activity_log_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ae_promises.load__activity_log_obj = await api.get_ae_obj({
|
ae_promises.load__activity_log_obj = await api.get_ae_obj({
|
||||||
@@ -61,7 +63,9 @@ export async function load_ae_obj_li__activity_log({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_ActivityLog[]> {
|
}): Promise<ae_ActivityLog[]> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** load_ae_obj_li__activity_log() *** for_obj_id=${for_obj_id}`);
|
console.log(
|
||||||
|
`*** load_ae_obj_li__activity_log() *** for_obj_id=${for_obj_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ae_promises.load__activity_log_obj_li = await api.get_ae_obj_li({
|
ae_promises.load__activity_log_obj_li = await api.get_ae_obj_li({
|
||||||
@@ -96,11 +100,15 @@ export async function create_ae_obj__activity_log({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_ActivityLog | null> {
|
}): Promise<ae_ActivityLog | null> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** create_ae_obj__activity_log() *** account_id=${account_id}`);
|
console.log(
|
||||||
|
`*** create_ae_obj__activity_log() *** account_id=${account_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!account_id) {
|
if (!account_id) {
|
||||||
console.log(`ERROR: Core - Activity Log - account_id required to create`);
|
console.log(
|
||||||
|
`ERROR: Core - Activity Log - account_id required to create`
|
||||||
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,7 +141,9 @@ export async function update_ae_obj__activity_log({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_ActivityLog | null> {
|
}): Promise<ae_ActivityLog | null> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** update_ae_obj__activity_log() *** activity_log_id=${activity_log_id}`);
|
console.log(
|
||||||
|
`*** update_ae_obj__activity_log() *** activity_log_id=${activity_log_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ae_promises.update__activity_log_obj = await api.update_ae_obj({
|
ae_promises.update__activity_log_obj = await api.update_ae_obj({
|
||||||
@@ -151,7 +161,6 @@ export async function update_ae_obj__activity_log({
|
|||||||
// Updated 2026-01-07
|
// Updated 2026-01-07
|
||||||
|
|
||||||
export async function qry__activity_log({
|
export async function qry__activity_log({
|
||||||
|
|
||||||
api_cfg,
|
api_cfg,
|
||||||
|
|
||||||
account_id,
|
account_id,
|
||||||
@@ -173,9 +182,7 @@ export async function qry__activity_log({
|
|||||||
order_by_li = { created_on: 'DESC' },
|
order_by_li = { created_on: 'DESC' },
|
||||||
|
|
||||||
log_lvl = 0
|
log_lvl = 0
|
||||||
|
|
||||||
}: {
|
}: {
|
||||||
|
|
||||||
api_cfg: any;
|
api_cfg: any;
|
||||||
|
|
||||||
account_id: string;
|
account_id: string;
|
||||||
@@ -197,49 +204,36 @@ export async function qry__activity_log({
|
|||||||
order_by_li?: Record<string, 'ASC' | 'DESC'>;
|
order_by_li?: Record<string, 'ASC' | 'DESC'>;
|
||||||
|
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
|
|
||||||
}): Promise<ae_ActivityLog[]> {
|
}): Promise<ae_ActivityLog[]> {
|
||||||
|
|
||||||
const search_query: any = {};
|
const search_query: any = {};
|
||||||
|
|
||||||
const filters: any[] = [];
|
const filters: any[] = [];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (account_id) {
|
if (account_id) {
|
||||||
|
filters.push({
|
||||||
filters.push({ field: 'account_id_random', op: 'eq', value: account_id });
|
field: 'account_id_random',
|
||||||
|
op: 'eq',
|
||||||
|
value: account_id
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (qry_person_id) {
|
if (qry_person_id) {
|
||||||
|
filters.push({
|
||||||
filters.push({ field: 'person_id_random', op: 'eq', value: qry_person_id });
|
field: 'person_id_random',
|
||||||
|
op: 'eq',
|
||||||
|
value: qry_person_id
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (filters.length > 0) {
|
if (filters.length > 0) {
|
||||||
|
|
||||||
search_query.and = filters;
|
search_query.and = filters;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (qry_str) {
|
if (qry_str) {
|
||||||
|
|
||||||
search_query.q = qry_str;
|
search_query.q = qry_str;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ae_promises.load__activity_log_obj_li = await api.search_ae_obj({
|
ae_promises.load__activity_log_obj_li = await api.search_ae_obj({
|
||||||
|
|
||||||
api_cfg,
|
api_cfg,
|
||||||
|
|
||||||
obj_type: 'activity_log',
|
obj_type: 'activity_log',
|
||||||
@@ -259,13 +253,9 @@ export async function qry__activity_log({
|
|||||||
order_by_li,
|
order_by_li,
|
||||||
|
|
||||||
log_lvl
|
log_lvl
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return ae_promises.load__activity_log_obj_li;
|
return ae_promises.load__activity_log_obj_li;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updated 2026-02-16
|
// Updated 2026-02-16
|
||||||
@@ -338,14 +328,21 @@ async function _process_generic_props<T extends Record<string, any>>({
|
|||||||
const group = processed_obj.group ?? '0';
|
const group = processed_obj.group ?? '0';
|
||||||
const priority = processed_obj.priority ? 1 : 0;
|
const priority = processed_obj.priority ? 1 : 0;
|
||||||
const sort = processed_obj.sort ?? '0';
|
const sort = processed_obj.sort ?? '0';
|
||||||
const updated = processed_obj.updated_on ?? processed_obj.created_on ?? new Date(0).toISOString();
|
const updated =
|
||||||
|
processed_obj.updated_on ??
|
||||||
|
processed_obj.created_on ??
|
||||||
|
new Date(0).toISOString();
|
||||||
const name = processed_obj.name ?? '';
|
const name = processed_obj.name ?? '';
|
||||||
|
|
||||||
(processed_obj as any).tmp_sort_1 = `${group}_${priority}_${sort}_${updated}`;
|
(processed_obj as any).tmp_sort_1 =
|
||||||
(processed_obj as any).tmp_sort_2 = `${group}_${priority}_${sort}_${name}_${updated}`;
|
`${group}_${priority}_${sort}_${updated}`;
|
||||||
|
(processed_obj as any).tmp_sort_2 =
|
||||||
|
`${group}_${priority}_${sort}_${name}_${updated}`;
|
||||||
|
|
||||||
if (specific_processor) {
|
if (specific_processor) {
|
||||||
processed_obj = await Promise.resolve(specific_processor(processed_obj));
|
processed_obj = await Promise.resolve(
|
||||||
|
specific_processor(processed_obj)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
processed_obj_li.push(processed_obj as T);
|
processed_obj_li.push(processed_obj as T);
|
||||||
@@ -367,5 +364,3 @@ export async function process_ae_obj__activity_log_props({
|
|||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -23,29 +23,34 @@ export async function load_ae_obj_id__address({
|
|||||||
try_cache?: boolean;
|
try_cache?: boolean;
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_Address | null> {
|
}): Promise<ae_Address | null> {
|
||||||
ae_promises.load__address_obj = await api.get_ae_obj({
|
ae_promises.load__address_obj = await api
|
||||||
api_cfg,
|
.get_ae_obj({
|
||||||
obj_type: 'address',
|
api_cfg,
|
||||||
obj_id: address_id,
|
obj_type: 'address',
|
||||||
view,
|
obj_id: address_id,
|
||||||
params,
|
view,
|
||||||
log_lvl
|
params,
|
||||||
}).then(async (result) => {
|
log_lvl
|
||||||
if (result) {
|
})
|
||||||
if (try_cache) {
|
.then(async (result) => {
|
||||||
const processed = await process_ae_obj__address_props({ obj_li: [result], log_lvl });
|
if (result) {
|
||||||
await db_save_ae_obj_li__ae_obj({
|
if (try_cache) {
|
||||||
db_instance: db_core,
|
const processed = await process_ae_obj__address_props({
|
||||||
table_name: 'address',
|
obj_li: [result],
|
||||||
obj_li: processed,
|
log_lvl
|
||||||
properties_to_save,
|
});
|
||||||
log_lvl
|
await db_save_ae_obj_li__ae_obj({
|
||||||
});
|
db_instance: db_core,
|
||||||
|
table_name: 'address',
|
||||||
|
obj_li: processed,
|
||||||
|
properties_to_save,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
return result;
|
return null;
|
||||||
}
|
});
|
||||||
return null;
|
|
||||||
});
|
|
||||||
return ae_promises.load__address_obj;
|
return ae_promises.load__address_obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,34 +82,39 @@ export async function load_ae_obj_li__address({
|
|||||||
try_cache?: boolean;
|
try_cache?: boolean;
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_Address[]> {
|
}): Promise<ae_Address[]> {
|
||||||
ae_promises.load__address_obj_li = await api.get_ae_obj_li({
|
ae_promises.load__address_obj_li = await api
|
||||||
api_cfg,
|
.get_ae_obj_li({
|
||||||
obj_type: 'address',
|
api_cfg,
|
||||||
for_obj_type,
|
obj_type: 'address',
|
||||||
for_obj_id,
|
for_obj_type,
|
||||||
enabled,
|
for_obj_id,
|
||||||
hidden,
|
enabled,
|
||||||
view,
|
hidden,
|
||||||
limit,
|
view,
|
||||||
offset,
|
limit,
|
||||||
order_by_li,
|
offset,
|
||||||
log_lvl
|
order_by_li,
|
||||||
}).then(async (result) => {
|
log_lvl
|
||||||
if (result && Array.isArray(result)) {
|
})
|
||||||
if (try_cache) {
|
.then(async (result) => {
|
||||||
const processed = await process_ae_obj__address_props({ obj_li: result, log_lvl });
|
if (result && Array.isArray(result)) {
|
||||||
await db_save_ae_obj_li__ae_obj({
|
if (try_cache) {
|
||||||
db_instance: db_core,
|
const processed = await process_ae_obj__address_props({
|
||||||
table_name: 'address',
|
obj_li: result,
|
||||||
obj_li: processed,
|
log_lvl
|
||||||
properties_to_save,
|
});
|
||||||
log_lvl
|
await db_save_ae_obj_li__ae_obj({
|
||||||
});
|
db_instance: db_core,
|
||||||
|
table_name: 'address',
|
||||||
|
obj_li: processed,
|
||||||
|
properties_to_save,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
return result;
|
return [];
|
||||||
}
|
});
|
||||||
return [];
|
|
||||||
});
|
|
||||||
return ae_promises.load__address_obj_li;
|
return ae_promises.load__address_obj_li;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,7 +146,10 @@ export async function create_ae_obj__address({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (result && try_cache) {
|
if (result && try_cache) {
|
||||||
const processed = await process_ae_obj__address_props({ obj_li: [result], log_lvl });
|
const processed = await process_ae_obj__address_props({
|
||||||
|
obj_li: [result],
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
db_instance: db_core,
|
db_instance: db_core,
|
||||||
table_name: 'address',
|
table_name: 'address',
|
||||||
@@ -174,7 +187,10 @@ export async function update_ae_obj__address({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (result && try_cache) {
|
if (result && try_cache) {
|
||||||
const processed = await process_ae_obj__address_props({ obj_li: [result], log_lvl });
|
const processed = await process_ae_obj__address_props({
|
||||||
|
obj_li: [result],
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
db_instance: db_core,
|
db_instance: db_core,
|
||||||
table_name: 'address',
|
table_name: 'address',
|
||||||
@@ -269,7 +285,9 @@ async function _process_generic_props<T extends Record<string, any>>({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (specific_processor) {
|
if (specific_processor) {
|
||||||
processed_obj = await Promise.resolve(specific_processor(processed_obj));
|
processed_obj = await Promise.resolve(
|
||||||
|
specific_processor(processed_obj)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
processed_obj_li.push(processed_obj as T);
|
processed_obj_li.push(processed_obj as T);
|
||||||
|
|||||||
@@ -23,29 +23,34 @@ export async function load_ae_obj_id__contact({
|
|||||||
try_cache?: boolean;
|
try_cache?: boolean;
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_Contact | null> {
|
}): Promise<ae_Contact | null> {
|
||||||
ae_promises.load__contact_obj = await api.get_ae_obj({
|
ae_promises.load__contact_obj = await api
|
||||||
api_cfg,
|
.get_ae_obj({
|
||||||
obj_type: 'contact',
|
api_cfg,
|
||||||
obj_id: contact_id,
|
obj_type: 'contact',
|
||||||
view,
|
obj_id: contact_id,
|
||||||
params,
|
view,
|
||||||
log_lvl
|
params,
|
||||||
}).then(async (result) => {
|
log_lvl
|
||||||
if (result) {
|
})
|
||||||
if (try_cache) {
|
.then(async (result) => {
|
||||||
const processed = await process_ae_obj__contact_props({ obj_li: [result], log_lvl });
|
if (result) {
|
||||||
await db_save_ae_obj_li__ae_obj({
|
if (try_cache) {
|
||||||
db_instance: db_core,
|
const processed = await process_ae_obj__contact_props({
|
||||||
table_name: 'contact',
|
obj_li: [result],
|
||||||
obj_li: processed,
|
log_lvl
|
||||||
properties_to_save,
|
});
|
||||||
log_lvl
|
await db_save_ae_obj_li__ae_obj({
|
||||||
});
|
db_instance: db_core,
|
||||||
|
table_name: 'contact',
|
||||||
|
obj_li: processed,
|
||||||
|
properties_to_save,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
return result;
|
return null;
|
||||||
}
|
});
|
||||||
return null;
|
|
||||||
});
|
|
||||||
return ae_promises.load__contact_obj;
|
return ae_promises.load__contact_obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,34 +80,39 @@ export async function load_ae_obj_li__contact({
|
|||||||
try_cache?: boolean;
|
try_cache?: boolean;
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_Contact[]> {
|
}): Promise<ae_Contact[]> {
|
||||||
ae_promises.load__contact_obj_li = await api.get_ae_obj_li({
|
ae_promises.load__contact_obj_li = await api
|
||||||
api_cfg,
|
.get_ae_obj_li({
|
||||||
obj_type: 'contact',
|
api_cfg,
|
||||||
for_obj_type,
|
obj_type: 'contact',
|
||||||
for_obj_id,
|
for_obj_type,
|
||||||
enabled,
|
for_obj_id,
|
||||||
hidden,
|
enabled,
|
||||||
view,
|
hidden,
|
||||||
limit,
|
view,
|
||||||
offset,
|
limit,
|
||||||
order_by_li,
|
offset,
|
||||||
log_lvl
|
order_by_li,
|
||||||
}).then(async (result) => {
|
log_lvl
|
||||||
if (result && Array.isArray(result)) {
|
})
|
||||||
if (try_cache) {
|
.then(async (result) => {
|
||||||
const processed = await process_ae_obj__contact_props({ obj_li: result, log_lvl });
|
if (result && Array.isArray(result)) {
|
||||||
await db_save_ae_obj_li__ae_obj({
|
if (try_cache) {
|
||||||
db_instance: db_core,
|
const processed = await process_ae_obj__contact_props({
|
||||||
table_name: 'contact',
|
obj_li: result,
|
||||||
obj_li: processed,
|
log_lvl
|
||||||
properties_to_save,
|
});
|
||||||
log_lvl
|
await db_save_ae_obj_li__ae_obj({
|
||||||
});
|
db_instance: db_core,
|
||||||
|
table_name: 'contact',
|
||||||
|
obj_li: processed,
|
||||||
|
properties_to_save,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
return result;
|
return [];
|
||||||
}
|
});
|
||||||
return [];
|
|
||||||
});
|
|
||||||
return ae_promises.load__contact_obj_li;
|
return ae_promises.load__contact_obj_li;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,7 +144,10 @@ export async function create_ae_obj__contact({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (result && try_cache) {
|
if (result && try_cache) {
|
||||||
const processed = await process_ae_obj__contact_props({ obj_li: [result], log_lvl });
|
const processed = await process_ae_obj__contact_props({
|
||||||
|
obj_li: [result],
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
db_instance: db_core,
|
db_instance: db_core,
|
||||||
table_name: 'contact',
|
table_name: 'contact',
|
||||||
@@ -172,7 +185,10 @@ export async function update_ae_obj__contact({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (result && try_cache) {
|
if (result && try_cache) {
|
||||||
const processed = await process_ae_obj__contact_props({ obj_li: [result], log_lvl });
|
const processed = await process_ae_obj__contact_props({
|
||||||
|
obj_li: [result],
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
db_instance: db_core,
|
db_instance: db_core,
|
||||||
table_name: 'contact',
|
table_name: 'contact',
|
||||||
@@ -267,7 +283,9 @@ async function _process_generic_props<T extends Record<string, any>>({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (specific_processor) {
|
if (specific_processor) {
|
||||||
processed_obj = await Promise.resolve(specific_processor(processed_obj));
|
processed_obj = await Promise.resolve(
|
||||||
|
specific_processor(processed_obj)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
processed_obj_li.push(processed_obj as T);
|
processed_obj_li.push(processed_obj as T);
|
||||||
|
|||||||
@@ -39,10 +39,12 @@ export async function load_ae_obj_id__person({
|
|||||||
.then(async function (result) {
|
.then(async function (result) {
|
||||||
if (result) {
|
if (result) {
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
const processed_obj_li = await process_ae_obj__person_props({
|
const processed_obj_li = await process_ae_obj__person_props(
|
||||||
obj_li: [result],
|
{
|
||||||
log_lvl
|
obj_li: [result],
|
||||||
});
|
log_lvl
|
||||||
|
}
|
||||||
|
);
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
db_instance: db_core,
|
db_instance: db_core,
|
||||||
table_name: 'person',
|
table_name: 'person',
|
||||||
@@ -98,7 +100,9 @@ export async function load_ae_obj_li__person({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_Person[]> {
|
}): Promise<ae_Person[]> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** load_ae_obj_li__person() *** for_obj_id=${for_obj_id}`);
|
console.log(
|
||||||
|
`*** load_ae_obj_li__person() *** for_obj_id=${for_obj_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let promise;
|
let promise;
|
||||||
@@ -109,11 +113,19 @@ export async function load_ae_obj_li__person({
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (qry_user_id) {
|
if (qry_user_id) {
|
||||||
search_query.and.push({ field: 'user_id_random', op: 'eq', value: qry_user_id });
|
search_query.and.push({
|
||||||
|
field: 'user_id_random',
|
||||||
|
op: 'eq',
|
||||||
|
value: qry_user_id
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qry_email) {
|
if (qry_email) {
|
||||||
search_query.and.push({ field: 'primary_email', op: 'eq', value: qry_email });
|
search_query.and.push({
|
||||||
|
field: 'primary_email',
|
||||||
|
op: 'eq',
|
||||||
|
value: qry_email
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (for_obj_id) {
|
if (for_obj_id) {
|
||||||
@@ -161,26 +173,30 @@ export async function load_ae_obj_li__person({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ae_promises.load__person_obj_li = await promise.then(async function (result_li) {
|
ae_promises.load__person_obj_li = await promise.then(
|
||||||
if (result_li) {
|
async function (result_li) {
|
||||||
if (try_cache) {
|
if (result_li) {
|
||||||
const processed_obj_li = await process_ae_obj__person_props({
|
if (try_cache) {
|
||||||
obj_li: result_li,
|
const processed_obj_li = await process_ae_obj__person_props(
|
||||||
log_lvl
|
{
|
||||||
});
|
obj_li: result_li,
|
||||||
await db_save_ae_obj_li__ae_obj({
|
log_lvl
|
||||||
db_instance: db_core,
|
}
|
||||||
table_name: 'person',
|
);
|
||||||
obj_li: processed_obj_li,
|
await db_save_ae_obj_li__ae_obj({
|
||||||
properties_to_save: properties_to_save,
|
db_instance: db_core,
|
||||||
log_lvl
|
table_name: 'person',
|
||||||
});
|
obj_li: processed_obj_li,
|
||||||
|
properties_to_save: properties_to_save,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result_li;
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
return result_li;
|
|
||||||
} else {
|
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
});
|
);
|
||||||
|
|
||||||
return ae_promises.load__person_obj_li;
|
return ae_promises.load__person_obj_li;
|
||||||
}
|
}
|
||||||
@@ -411,11 +427,15 @@ async function _process_generic_props<T extends Record<string, any>>({
|
|||||||
const updated = processed_obj.updated_on ?? processed_obj.created_on;
|
const updated = processed_obj.updated_on ?? processed_obj.created_on;
|
||||||
const name = processed_obj.full_name ?? processed_obj.name ?? '';
|
const name = processed_obj.full_name ?? processed_obj.name ?? '';
|
||||||
|
|
||||||
(processed_obj as any).tmp_sort_1 = `${group}_${priority}_${sort}_${updated}`;
|
(processed_obj as any).tmp_sort_1 =
|
||||||
(processed_obj as any).tmp_sort_2 = `${group}_${priority}_${sort}_${name}_${updated}`;
|
`${group}_${priority}_${sort}_${updated}`;
|
||||||
|
(processed_obj as any).tmp_sort_2 =
|
||||||
|
`${group}_${priority}_${sort}_${name}_${updated}`;
|
||||||
|
|
||||||
if (specific_processor) {
|
if (specific_processor) {
|
||||||
processed_obj = await Promise.resolve(specific_processor(processed_obj));
|
processed_obj = await Promise.resolve(
|
||||||
|
specific_processor(processed_obj)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
processed_obj_li.push(processed_obj as T);
|
processed_obj_li.push(processed_obj as T);
|
||||||
|
|||||||
@@ -113,10 +113,18 @@ export async function lookup_site_domain({
|
|||||||
try {
|
try {
|
||||||
cached = await db_core.site_domain.where('fqdn').equals(fqdn).first();
|
cached = await db_core.site_domain.where('fqdn').equals(fqdn).first();
|
||||||
if (cached) {
|
if (cached) {
|
||||||
if (log_lvl) console.log('BOOTSTRAP: Cache hit. Returning cached site domain immediately.');
|
if (log_lvl)
|
||||||
|
console.log(
|
||||||
|
'BOOTSTRAP: Cache hit. Returning cached site domain immediately.'
|
||||||
|
);
|
||||||
|
|
||||||
// Trigger background refresh to keep cache fresh, but don't await it
|
// Trigger background refresh to keep cache fresh, but don't await it
|
||||||
_refresh_site_domain_background({ api_cfg, fqdn, view, log_lvl: 0 });
|
_refresh_site_domain_background({
|
||||||
|
api_cfg,
|
||||||
|
fqdn,
|
||||||
|
view,
|
||||||
|
log_lvl: 0
|
||||||
|
});
|
||||||
|
|
||||||
return cached as any;
|
return cached as any;
|
||||||
}
|
}
|
||||||
@@ -125,13 +133,23 @@ export async function lookup_site_domain({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 2. SLOW PATH: Wait for API if cache is empty
|
// 2. SLOW PATH: Wait for API if cache is empty
|
||||||
return await _refresh_site_domain_background({ api_cfg, fqdn, view, log_lvl });
|
return await _refresh_site_domain_background({
|
||||||
|
api_cfg,
|
||||||
|
fqdn,
|
||||||
|
view,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal helper to perform the actual API fetch and cache update
|
* Internal helper to perform the actual API fetch and cache update
|
||||||
*/
|
*/
|
||||||
async function _refresh_site_domain_background({ api_cfg, fqdn, view, log_lvl }: any) {
|
async function _refresh_site_domain_background({
|
||||||
|
api_cfg,
|
||||||
|
fqdn,
|
||||||
|
view,
|
||||||
|
log_lvl
|
||||||
|
}: any) {
|
||||||
try {
|
try {
|
||||||
const guest_api_cfg = { ...api_cfg };
|
const guest_api_cfg = { ...api_cfg };
|
||||||
guest_api_cfg.headers = { ...api_cfg.headers };
|
guest_api_cfg.headers = { ...api_cfg.headers };
|
||||||
@@ -144,7 +162,7 @@ async function _refresh_site_domain_background({ api_cfg, fqdn, view, log_lvl }:
|
|||||||
'JWT'
|
'JWT'
|
||||||
];
|
];
|
||||||
|
|
||||||
auth_props.forEach(prop => {
|
auth_props.forEach((prop) => {
|
||||||
delete guest_api_cfg.headers[prop];
|
delete guest_api_cfg.headers[prop];
|
||||||
delete guest_api_cfg.headers[prop.toLowerCase()];
|
delete guest_api_cfg.headers[prop.toLowerCase()];
|
||||||
delete guest_api_cfg.headers[prop.replaceAll('-', '_')];
|
delete guest_api_cfg.headers[prop.replaceAll('-', '_')];
|
||||||
@@ -481,11 +499,12 @@ export async function load_ae_obj_li__site_domain({
|
|||||||
.then(async function (domain_li) {
|
.then(async function (domain_li) {
|
||||||
if (domain_li) {
|
if (domain_li) {
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
const processed_obj_li = await process_ae_obj__site_domain_props({
|
const processed_obj_li =
|
||||||
obj_li: domain_li,
|
await process_ae_obj__site_domain_props({
|
||||||
site_id,
|
obj_li: domain_li,
|
||||||
log_lvl
|
site_id,
|
||||||
});
|
log_lvl
|
||||||
|
});
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
db_instance: db_core,
|
db_instance: db_core,
|
||||||
table_name: 'site_domain',
|
table_name: 'site_domain',
|
||||||
@@ -729,11 +748,15 @@ async function _process_generic_props<T extends Record<string, any>>({
|
|||||||
const updated = processed_obj.updated_on ?? processed_obj.created_on;
|
const updated = processed_obj.updated_on ?? processed_obj.created_on;
|
||||||
const name = processed_obj.name ?? processed_obj.fqdn ?? '';
|
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_1 =
|
||||||
(processed_obj as any).tmp_sort_2 = `${group}_${priority}_${sort}_${name}_${updated}`;
|
`${group}_${priority}_${sort}_${updated}`;
|
||||||
|
(processed_obj as any).tmp_sort_2 =
|
||||||
|
`${group}_${priority}_${sort}_${name}_${updated}`;
|
||||||
|
|
||||||
if (specific_processor) {
|
if (specific_processor) {
|
||||||
processed_obj = await Promise.resolve(specific_processor(processed_obj));
|
processed_obj = await Promise.resolve(
|
||||||
|
specific_processor(processed_obj)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
processed_obj_li.push(processed_obj as T);
|
processed_obj_li.push(processed_obj as T);
|
||||||
|
|||||||
@@ -93,7 +93,9 @@ export async function load_ae_obj_li__user({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_User[]> {
|
}): Promise<ae_User[]> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** load_ae_obj_li__user() *** for_obj_id=${for_obj_id} include_global=${include_global} qry_str=${qry_str}`);
|
console.log(
|
||||||
|
`*** load_ae_obj_li__user() *** for_obj_id=${for_obj_id} include_global=${include_global} qry_str=${qry_str}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// SCENARIO A: Text Search
|
// SCENARIO A: Text Search
|
||||||
@@ -107,9 +109,17 @@ export async function load_ae_obj_li__user({
|
|||||||
]
|
]
|
||||||
});
|
});
|
||||||
} else if (for_obj_id) {
|
} else if (for_obj_id) {
|
||||||
search_query.and.push({ field: `account_id_random`, op: 'eq', value: for_obj_id });
|
search_query.and.push({
|
||||||
|
field: `account_id_random`,
|
||||||
|
op: 'eq',
|
||||||
|
value: for_obj_id
|
||||||
|
});
|
||||||
} else if (include_global) {
|
} else if (include_global) {
|
||||||
search_query.and.push({ field: `account_id_random`, op: 'eq', value: null });
|
search_query.and.push({
|
||||||
|
field: `account_id_random`,
|
||||||
|
op: 'eq',
|
||||||
|
value: null
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return await api.search_ae_obj({
|
return await api.search_ae_obj({
|
||||||
@@ -130,13 +140,33 @@ export async function load_ae_obj_li__user({
|
|||||||
if (for_obj_id && include_global) {
|
if (for_obj_id && include_global) {
|
||||||
if (log_lvl) console.log('Strategy: Multi-call (Account + Global)');
|
if (log_lvl) console.log('Strategy: Multi-call (Account + Global)');
|
||||||
const [acct_users, global_users] = await Promise.all([
|
const [acct_users, global_users] = await Promise.all([
|
||||||
load_ae_obj_li__user({ api_cfg, for_obj_id, include_global: false, enabled, hidden, view, limit, log_lvl }),
|
load_ae_obj_li__user({
|
||||||
load_ae_obj_li__user({ api_cfg, for_obj_id: null, include_global: true, enabled, hidden, view, limit, log_lvl })
|
api_cfg,
|
||||||
|
for_obj_id,
|
||||||
|
include_global: false,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
view,
|
||||||
|
limit,
|
||||||
|
log_lvl
|
||||||
|
}),
|
||||||
|
load_ae_obj_li__user({
|
||||||
|
api_cfg,
|
||||||
|
for_obj_id: null,
|
||||||
|
include_global: true,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
view,
|
||||||
|
limit,
|
||||||
|
log_lvl
|
||||||
|
})
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Merge and unique-ify by ID
|
// Merge and unique-ify by ID
|
||||||
const merged = [...acct_users, ...global_users];
|
const merged = [...acct_users, ...global_users];
|
||||||
const unique = Array.from(new Map(merged.map(u => [u.user_id_random, u])).values());
|
const unique = Array.from(
|
||||||
|
new Map(merged.map((u) => [u.user_id_random, u])).values()
|
||||||
|
);
|
||||||
return unique;
|
return unique;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,7 +192,8 @@ export async function load_ae_obj_li__user({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SCENARIO D: Account Only or Everything (confirmed working List API)
|
// SCENARIO D: Account Only or Everything (confirmed working List API)
|
||||||
if (log_lvl) console.log(`Strategy: Standard List API (for_obj_id=${for_obj_id})`);
|
if (log_lvl)
|
||||||
|
console.log(`Strategy: Standard List API (for_obj_id=${for_obj_id})`);
|
||||||
return await api.get_ae_obj_li({
|
return await api.get_ae_obj_li({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
obj_type: 'user',
|
obj_type: 'user',
|
||||||
@@ -383,7 +414,10 @@ export async function auth_ae_obj__username_password({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log('ae_promises.auth__username_password:', ae_promises.auth__username_password);
|
console.log(
|
||||||
|
'ae_promises.auth__username_password:',
|
||||||
|
ae_promises.auth__username_password
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return ae_promises.auth__username_password;
|
return ae_promises.auth__username_password;
|
||||||
}
|
}
|
||||||
@@ -450,7 +484,10 @@ export async function auth_ae_obj__user_id_user_auth_key({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log('ae_promises.auth__user_id_user_key:', ae_promises.auth__user_id_user_key);
|
console.log(
|
||||||
|
'ae_promises.auth__user_id_user_key:',
|
||||||
|
ae_promises.auth__user_id_user_key
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return ae_promises.auth__user_id_user_key;
|
return ae_promises.auth__user_id_user_key;
|
||||||
}
|
}
|
||||||
@@ -525,7 +562,9 @@ export async function qry_ae_obj_li__user_email({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}) {
|
}) {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** qry_ae_obj_li__user_email() *** account_id=${account_id} email=${email}`);
|
console.log(
|
||||||
|
`*** qry_ae_obj_li__user_email() *** account_id=${account_id} email=${email}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const endpoint = '/user/lookup_email';
|
const endpoint = '/user/lookup_email';
|
||||||
@@ -676,11 +715,15 @@ async function _process_generic_props<T extends Record<string, any>>({
|
|||||||
const updated = processed_obj.updated_on ?? processed_obj.created_on;
|
const updated = processed_obj.updated_on ?? processed_obj.created_on;
|
||||||
const name = processed_obj.username ?? processed_obj.name ?? '';
|
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_1 =
|
||||||
(processed_obj as any).tmp_sort_2 = `${group}_${priority}_${sort}_${name}_${updated}`;
|
`${group}_${priority}_${sort}_${updated}`;
|
||||||
|
(processed_obj as any).tmp_sort_2 =
|
||||||
|
`${group}_${priority}_${sort}_${name}_${updated}`;
|
||||||
|
|
||||||
if (specific_processor) {
|
if (specific_processor) {
|
||||||
processed_obj = await Promise.resolve(specific_processor(processed_obj));
|
processed_obj = await Promise.resolve(
|
||||||
|
specific_processor(processed_obj)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
processed_obj_li.push(processed_obj as T);
|
processed_obj_li.push(processed_obj as T);
|
||||||
|
|||||||
@@ -25,7 +25,10 @@ import {
|
|||||||
auth_ae_obj__user_id_change_password
|
auth_ae_obj__user_id_change_password
|
||||||
} from '$lib/ae_core/ae_core__user';
|
} from '$lib/ae_core/ae_core__user';
|
||||||
|
|
||||||
import { generate_qr_code, js_generate_qr_code } from '$lib/ae_core/core__qr_code';
|
import {
|
||||||
|
generate_qr_code,
|
||||||
|
js_generate_qr_code
|
||||||
|
} from '$lib/ae_core/core__qr_code';
|
||||||
|
|
||||||
import { check_hosted_file_obj_w_hash } from '$lib/ae_core/core__check_hosted_file_obj_w_hash';
|
import { check_hosted_file_obj_w_hash } from '$lib/ae_core/core__check_hosted_file_obj_w_hash';
|
||||||
|
|
||||||
@@ -161,7 +164,9 @@ async function load_ae_obj_code__data_store({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!get_ds_result.data_store_id_random) {
|
if (!get_ds_result.data_store_id_random) {
|
||||||
console.log('*ae_func* Something went wrong? No data store ID found.');
|
console.log(
|
||||||
|
'*ae_func* Something went wrong? No data store ID found.'
|
||||||
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,7 +245,10 @@ async function load_ae_obj_code__data_store({
|
|||||||
get_ds_result
|
get_ds_result
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
localStorage.setItem(`${key_prefix}${code}`, JSON.stringify(get_ds_result));
|
localStorage.setItem(
|
||||||
|
`${key_prefix}${code}`,
|
||||||
|
JSON.stringify(get_ds_result)
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(
|
console.log(
|
||||||
@@ -491,7 +499,10 @@ async function download_export__obj_type({
|
|||||||
log_lvl: log_lvl
|
log_lvl: log_lvl
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('ae_promises.download__export_file:', ae_promises.download__export_file);
|
console.log(
|
||||||
|
'ae_promises.download__export_file:',
|
||||||
|
ae_promises.download__export_file
|
||||||
|
);
|
||||||
return ae_promises.download__export_file;
|
return ae_promises.download__export_file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,12 +13,17 @@ export function add_url_params({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}) {
|
}) {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** add_url_params() *** base_url=${base_url} endpoint=${endpoint}`, params);
|
console.log(
|
||||||
|
`*** add_url_params() *** base_url=${base_url} endpoint=${endpoint}`,
|
||||||
|
params
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const url_obj = new URL(endpoint, base_url);
|
const url_obj = new URL(endpoint, base_url);
|
||||||
|
|
||||||
Object.keys(params).forEach((key) => url_obj.searchParams.append(key, params[key]));
|
Object.keys(params).forEach((key) =>
|
||||||
|
url_obj.searchParams.append(key, params[key])
|
||||||
|
);
|
||||||
|
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log('New URL:', url_obj.toString());
|
console.log('New URL:', url_obj.toString());
|
||||||
@@ -30,7 +35,13 @@ export function add_url_params({
|
|||||||
|
|
||||||
// This is used to clean the header property names. Not underscores allowed in the header names.
|
// This is used to clean the header property names. Not underscores allowed in the header names.
|
||||||
// Updated 2025-01-28
|
// Updated 2025-01-28
|
||||||
export function clean_headers({ headers, log_lvl = 0 }: { headers: any; log_lvl?: number }) {
|
export function clean_headers({
|
||||||
|
headers,
|
||||||
|
log_lvl = 0
|
||||||
|
}: {
|
||||||
|
headers: any;
|
||||||
|
log_lvl?: number;
|
||||||
|
}) {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** clean_headers() ***`, headers);
|
console.log(`*** clean_headers() ***`, headers);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,8 +33,14 @@ async function _refresh_lu_country_background({
|
|||||||
if (result?.length) {
|
if (result?.length) {
|
||||||
await db_lookups.lu_country.clear();
|
await db_lookups.lu_country.clear();
|
||||||
await db_lookups.lu_country.bulkPut(result);
|
await db_lookups.lu_country.bulkPut(result);
|
||||||
await db_lookups.lu_cache_meta.put({ lu_type: 'country', refreshed_at: Date.now() });
|
await db_lookups.lu_cache_meta.put({
|
||||||
if (log_lvl) console.log(`lu_country: saved ${result.length} records to IDB`);
|
lu_type: 'country',
|
||||||
|
refreshed_at: Date.now()
|
||||||
|
});
|
||||||
|
if (log_lvl)
|
||||||
|
console.log(
|
||||||
|
`lu_country: saved ${result.length} records to IDB`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('lu_country refresh failed:', error);
|
console.error('lu_country refresh failed:', error);
|
||||||
@@ -59,6 +65,8 @@ export async function load_ae_obj_li__country({
|
|||||||
// Fire-and-forget — liveQuery subscribers receive updates when IDB is written
|
// Fire-and-forget — liveQuery subscribers receive updates when IDB is written
|
||||||
_refresh_lu_country_background({ api_cfg, log_lvl });
|
_refresh_lu_country_background({ api_cfg, log_lvl });
|
||||||
} else if (log_lvl) {
|
} else if (log_lvl) {
|
||||||
console.log(`lu_country: IDB fresh (${count} records), skipping refresh`);
|
console.log(
|
||||||
|
`lu_country: IDB fresh (${count} records), skipping refresh`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,8 @@ async function _refresh_lu_country_subdivision_background({
|
|||||||
api_cfg: any;
|
api_cfg: any;
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}) {
|
}) {
|
||||||
if (log_lvl) console.log('*** _refresh_lu_country_subdivision_background() ***');
|
if (log_lvl)
|
||||||
|
console.log('*** _refresh_lu_country_subdivision_background() ***');
|
||||||
try {
|
try {
|
||||||
const result = await api.get_ae_obj_li_for_lu({
|
const result = await api.get_ae_obj_li_for_lu({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
@@ -37,7 +38,9 @@ async function _refresh_lu_country_subdivision_background({
|
|||||||
refreshed_at: Date.now()
|
refreshed_at: Date.now()
|
||||||
});
|
});
|
||||||
if (log_lvl)
|
if (log_lvl)
|
||||||
console.log(`lu_country_subdivision: saved ${result.length} records to IDB`);
|
console.log(
|
||||||
|
`lu_country_subdivision: saved ${result.length} records to IDB`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('lu_country_subdivision refresh failed:', error);
|
console.error('lu_country_subdivision refresh failed:', error);
|
||||||
@@ -61,6 +64,8 @@ export async function load_ae_obj_li__country_subdivision({
|
|||||||
if (count === 0 || is_stale) {
|
if (count === 0 || is_stale) {
|
||||||
_refresh_lu_country_subdivision_background({ api_cfg, log_lvl });
|
_refresh_lu_country_subdivision_background({ api_cfg, log_lvl });
|
||||||
} else if (log_lvl) {
|
} else if (log_lvl) {
|
||||||
console.log(`lu_country_subdivision: IDB fresh (${count} records), skipping refresh`);
|
console.log(
|
||||||
|
`lu_country_subdivision: IDB fresh (${count} records), skipping refresh`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,16 +50,24 @@ export async function load_ae_obj_by_code__data_store({
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ds_id = get_ds_result.data_store_id_random || get_ds_result.id_random;
|
const ds_id =
|
||||||
|
get_ds_result.data_store_id_random || get_ds_result.id_random;
|
||||||
|
|
||||||
if (!ds_id) {
|
if (!ds_id) {
|
||||||
if (log_lvl) console.log('*ae_func* Something went wrong? No data store ID found.');
|
if (log_lvl)
|
||||||
|
console.log(
|
||||||
|
'*ae_func* Something went wrong? No data store ID found.'
|
||||||
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map content fields for convenience
|
// Map content fields for convenience
|
||||||
const text_val = get_ds_result.text || '';
|
const text_val = get_ds_result.text || '';
|
||||||
const json_val = get_ds_result.json || (get_ds_result.json_str ? JSON.parse(get_ds_result.json_str) : null);
|
const json_val =
|
||||||
|
get_ds_result.json ||
|
||||||
|
(get_ds_result.json_str
|
||||||
|
? JSON.parse(get_ds_result.json_str)
|
||||||
|
: null);
|
||||||
|
|
||||||
const mapped_ds: ae_DataStore = {
|
const mapped_ds: ae_DataStore = {
|
||||||
...get_ds_result,
|
...get_ds_result,
|
||||||
@@ -77,7 +85,6 @@ export async function load_ae_obj_by_code__data_store({
|
|||||||
if (data_type === 'html') return mapped_ds.html;
|
if (data_type === 'html') return mapped_ds.html;
|
||||||
if (data_type === 'json') return mapped_ds.json;
|
if (data_type === 'json') return mapped_ds.json;
|
||||||
return mapped_ds.text;
|
return mapped_ds.text;
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (log_lvl) console.error('*ae_func* Fetch failed.', error);
|
if (log_lvl) console.error('*ae_func* Fetch failed.', error);
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -22,7 +22,9 @@ export async function load_ae_obj_id__hosted_file({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_HostedFile | null> {
|
}): Promise<ae_HostedFile | null> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** load_ae_obj_id__hosted_file() *** [V3] id=${hosted_file_id}`);
|
console.log(
|
||||||
|
`*** load_ae_obj_id__hosted_file() *** [V3] id=${hosted_file_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -36,10 +38,11 @@ export async function load_ae_obj_id__hosted_file({
|
|||||||
|
|
||||||
if (ae_promises.load__hosted_file_obj) {
|
if (ae_promises.load__hosted_file_obj) {
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
const processed_obj_li = await process_ae_obj__hosted_file_props({
|
const processed_obj_li =
|
||||||
obj_li: [ae_promises.load__hosted_file_obj],
|
await process_ae_obj__hosted_file_props({
|
||||||
log_lvl
|
obj_li: [ae_promises.load__hosted_file_obj],
|
||||||
});
|
log_lvl
|
||||||
|
});
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
db_instance: db_core,
|
db_instance: db_core,
|
||||||
table_name: 'file',
|
table_name: 'file',
|
||||||
@@ -49,12 +52,14 @@ export async function load_ae_obj_id__hosted_file({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (try_cache) {
|
} else if (try_cache) {
|
||||||
ae_promises.load__hosted_file_obj = await db_core.file.get(hosted_file_id);
|
ae_promises.load__hosted_file_obj =
|
||||||
|
await db_core.file.get(hosted_file_id);
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log('V3 Request failed.', error);
|
console.log('V3 Request failed.', error);
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
ae_promises.load__hosted_file_obj = await db_core.file.get(hosted_file_id);
|
ae_promises.load__hosted_file_obj =
|
||||||
|
await db_core.file.get(hosted_file_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +95,9 @@ export async function load_ae_obj_li__hosted_file({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_HostedFile[]> {
|
}): Promise<ae_HostedFile[]> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** load_ae_obj_li__hosted_file() *** [V3] for=${for_obj_type}:${for_obj_id}`);
|
console.log(
|
||||||
|
`*** load_ae_obj_li__hosted_file() *** [V3] for=${for_obj_type}:${for_obj_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -109,10 +116,11 @@ export async function load_ae_obj_li__hosted_file({
|
|||||||
|
|
||||||
if (ae_promises.load__hosted_file_obj_li) {
|
if (ae_promises.load__hosted_file_obj_li) {
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
const processed_obj_li = await process_ae_obj__hosted_file_props({
|
const processed_obj_li =
|
||||||
obj_li: ae_promises.load__hosted_file_obj_li,
|
await process_ae_obj__hosted_file_props({
|
||||||
log_lvl
|
obj_li: ae_promises.load__hosted_file_obj_li,
|
||||||
});
|
log_lvl
|
||||||
|
});
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
db_instance: db_core,
|
db_instance: db_core,
|
||||||
table_name: 'file',
|
table_name: 'file',
|
||||||
@@ -123,14 +131,16 @@ export async function load_ae_obj_li__hosted_file({
|
|||||||
}
|
}
|
||||||
} else if (try_cache) {
|
} else if (try_cache) {
|
||||||
ae_promises.load__hosted_file_obj_li = await db_core.file
|
ae_promises.load__hosted_file_obj_li = await db_core.file
|
||||||
.where('for_id').equals(for_obj_id)
|
.where('for_id')
|
||||||
|
.equals(for_obj_id)
|
||||||
.toArray();
|
.toArray();
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log('V3 List Request failed.', error);
|
console.log('V3 List Request failed.', error);
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
ae_promises.load__hosted_file_obj_li = await db_core.file
|
ae_promises.load__hosted_file_obj_li = await db_core.file
|
||||||
.where('for_id').equals(for_obj_id)
|
.where('for_id')
|
||||||
|
.equals(for_obj_id)
|
||||||
.toArray();
|
.toArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -159,7 +169,9 @@ export async function delete_ae_obj_id__hosted_file({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}) {
|
}) {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** delete_ae_obj_id__hosted_file() *** [Special] id=${hosted_file_id}`);
|
console.log(
|
||||||
|
`*** delete_ae_obj_id__hosted_file() *** [Special] id=${hosted_file_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use the specialized hosted file delete endpoint
|
// Use the specialized hosted file delete endpoint
|
||||||
@@ -203,7 +215,9 @@ export async function download_ae_obj_id__hosted_file({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}) {
|
}) {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** download_ae_obj_id__hosted_file() *** id=${hosted_file_id}`);
|
console.log(
|
||||||
|
`*** download_ae_obj_id__hosted_file() *** id=${hosted_file_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const task_id = hosted_file_id;
|
const task_id = hosted_file_id;
|
||||||
@@ -290,11 +304,15 @@ async function _process_generic_props<T extends Record<string, any>>({
|
|||||||
const updated = processed_obj.updated_on ?? processed_obj.created_on;
|
const updated = processed_obj.updated_on ?? processed_obj.created_on;
|
||||||
const name = processed_obj.name ?? '';
|
const name = processed_obj.name ?? '';
|
||||||
|
|
||||||
(processed_obj as any).tmp_sort_1 = `${group}_${priority}_${sort}_${updated}`;
|
(processed_obj as any).tmp_sort_1 =
|
||||||
(processed_obj as any).tmp_sort_2 = `${group}_${priority}_${sort}_${name}_${updated}`;
|
`${group}_${priority}_${sort}_${updated}`;
|
||||||
|
(processed_obj as any).tmp_sort_2 =
|
||||||
|
`${group}_${priority}_${sort}_${name}_${updated}`;
|
||||||
|
|
||||||
if (specific_processor) {
|
if (specific_processor) {
|
||||||
processed_obj = await Promise.resolve(specific_processor(processed_obj));
|
processed_obj = await Promise.resolve(
|
||||||
|
specific_processor(processed_obj)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
processed_obj_li.push(processed_obj as T);
|
processed_obj_li.push(processed_obj as T);
|
||||||
|
|||||||
@@ -115,7 +115,9 @@ export async function db_save_ae_obj_li__ae_obj<T extends Record<string, any>>({
|
|||||||
|
|
||||||
if (data_to_save.length === 0) {
|
if (data_to_save.length === 0) {
|
||||||
if (log_lvl > 0) {
|
if (log_lvl > 0) {
|
||||||
console.warn('All objects were skipped, likely due to missing IDs.');
|
console.warn(
|
||||||
|
'All objects were skipped, likely due to missing IDs.'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@@ -124,7 +126,9 @@ export async function db_save_ae_obj_li__ae_obj<T extends Record<string, any>>({
|
|||||||
// bulkPut efficiently handles both inserts and updates.
|
// bulkPut efficiently handles both inserts and updates.
|
||||||
const keys = await db_table.bulkPut(data_to_save);
|
const keys = await db_table.bulkPut(data_to_save);
|
||||||
if (log_lvl > 0) {
|
if (log_lvl > 0) {
|
||||||
console.log(`Successfully saved ${data_to_save.length} objects to "${table_name}".`);
|
console.log(
|
||||||
|
`Successfully saved ${data_to_save.length} objects to "${table_name}".`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return keys;
|
return keys;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -49,7 +49,8 @@ export async function generate_qr_code({
|
|||||||
|
|
||||||
if (qr_type == 'vcard') {
|
if (qr_type == 'vcard') {
|
||||||
if (qr_data.informal_name) {
|
if (qr_data.informal_name) {
|
||||||
params['n'] = `${qr_data.family_name};${qr_data.given_name};${qr_data.informal_name}`;
|
params['n'] =
|
||||||
|
`${qr_data.family_name};${qr_data.given_name};${qr_data.informal_name}`;
|
||||||
} else {
|
} else {
|
||||||
params['n'] = `${qr_data.family_name};${qr_data.given_name}`;
|
params['n'] = `${qr_data.family_name};${qr_data.given_name}`;
|
||||||
}
|
}
|
||||||
@@ -99,7 +100,8 @@ export async function generate_qr_code({
|
|||||||
|
|
||||||
// If return_blob is true, ensure we return an object URL for use in <img src=...>
|
// If return_blob is true, ensure we return an object URL for use in <img src=...>
|
||||||
if (return_blob) {
|
if (return_blob) {
|
||||||
const data = ae_promises.generate_qr_code.data ?? ae_promises.generate_qr_code;
|
const data =
|
||||||
|
ae_promises.generate_qr_code.data ?? ae_promises.generate_qr_code;
|
||||||
|
|
||||||
// If already a Blob, use it directly
|
// If already a Blob, use it directly
|
||||||
if (data instanceof Blob) {
|
if (data instanceof Blob) {
|
||||||
@@ -133,7 +135,8 @@ export async function generate_qr_code({
|
|||||||
const blob = new Blob([data as BlobPart], { type: 'image/png' });
|
const blob = new Blob([data as BlobPart], { type: 'image/png' });
|
||||||
return URL.createObjectURL(blob);
|
return URL.createObjectURL(blob);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (log_lvl) console.error('Could not create QR code image blob:', e, data);
|
if (log_lvl)
|
||||||
|
console.error('Could not create QR code image blob:', e, data);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -155,7 +158,10 @@ export async function generate_qr_code({
|
|||||||
* @returns {Promise<string>} A promise that resolves to a Base64 data URL of the QR code image.
|
* @returns {Promise<string>} A promise that resolves to a Base64 data URL of the QR code image.
|
||||||
* @throws {Error} If the qr_type is unknown or data is missing.
|
* @throws {Error} If the qr_type is unknown or data is missing.
|
||||||
*/
|
*/
|
||||||
export async function js_generate_qr_code(qr_type: string, params: key_val = {}) {
|
export async function js_generate_qr_code(
|
||||||
|
qr_type: string,
|
||||||
|
params: key_val = {}
|
||||||
|
) {
|
||||||
const {
|
const {
|
||||||
n = '',
|
n = '',
|
||||||
fn = '',
|
fn = '',
|
||||||
@@ -179,7 +185,8 @@ export async function js_generate_qr_code(qr_type: string, params: key_val = {})
|
|||||||
log_lvl = 0
|
log_lvl = 0
|
||||||
} = params;
|
} = params;
|
||||||
|
|
||||||
if (log_lvl >= 2) console.log(`*** js_generate_qr_code() *** qr_type=${qr_type}`, params);
|
if (log_lvl >= 2)
|
||||||
|
console.log(`*** js_generate_qr_code() *** qr_type=${qr_type}`, params);
|
||||||
|
|
||||||
let qr_data: string | null = null;
|
let qr_data: string | null = null;
|
||||||
|
|
||||||
@@ -211,13 +218,15 @@ export async function js_generate_qr_code(qr_type: string, params: key_val = {})
|
|||||||
|
|
||||||
case 'obj':
|
case 'obj':
|
||||||
// Custom format: OBJ:ot:obj_type,oi:obj_id
|
// Custom format: OBJ:ot:obj_type,oi:obj_id
|
||||||
if (!obj_type || !obj_id) throw new Error('Missing obj_type or obj_id for type "obj".');
|
if (!obj_type || !obj_id)
|
||||||
|
throw new Error('Missing obj_type or obj_id for type "obj".');
|
||||||
qr_data = `OBJ:ot:${obj_type},oi:${obj_id}`;
|
qr_data = `OBJ:ot:${obj_type},oi:${obj_id}`;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'kv':
|
case 'kv':
|
||||||
// Custom format: KV:k:"key",v:"val"
|
// Custom format: KV:k:"key",v:"val"
|
||||||
if (!key || !val) throw new Error('Missing key or val for type "kv".');
|
if (!key || !val)
|
||||||
|
throw new Error('Missing key or val for type "kv".');
|
||||||
qr_data = `KV:k:"${key}",v:"${val}"`;
|
qr_data = `KV:k:"${key}",v:"${val}"`;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -229,7 +238,8 @@ export async function js_generate_qr_code(qr_type: string, params: key_val = {})
|
|||||||
|
|
||||||
case 'str':
|
case 'str':
|
||||||
// Raw string data
|
// Raw string data
|
||||||
if (!str) throw new Error('Missing raw string data for type "str".');
|
if (!str)
|
||||||
|
throw new Error('Missing raw string data for type "str".');
|
||||||
qr_data = str;
|
qr_data = str;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ async function _refresh_lu_time_zone_background({
|
|||||||
for_lu_type: 'time_zone',
|
for_lu_type: 'time_zone',
|
||||||
enabled: 'enabled',
|
enabled: 'enabled',
|
||||||
hidden: 'not_hidden',
|
hidden: 'not_hidden',
|
||||||
only_priority: true, // ~72 priority timezone records
|
only_priority: true, // ~72 priority timezone records
|
||||||
limit: 1800,
|
limit: 1800,
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
@@ -38,7 +38,10 @@ async function _refresh_lu_time_zone_background({
|
|||||||
lu_type: 'time_zone',
|
lu_type: 'time_zone',
|
||||||
refreshed_at: Date.now()
|
refreshed_at: Date.now()
|
||||||
});
|
});
|
||||||
if (log_lvl) console.log(`lu_time_zone: saved ${result.length} records to IDB`);
|
if (log_lvl)
|
||||||
|
console.log(
|
||||||
|
`lu_time_zone: saved ${result.length} records to IDB`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('lu_time_zone refresh failed:', error);
|
console.error('lu_time_zone refresh failed:', error);
|
||||||
@@ -62,6 +65,8 @@ export async function load_ae_obj_li__time_zone({
|
|||||||
if (count === 0 || is_stale) {
|
if (count === 0 || is_stale) {
|
||||||
_refresh_lu_time_zone_background({ api_cfg, log_lvl });
|
_refresh_lu_time_zone_background({ api_cfg, log_lvl });
|
||||||
} else if (log_lvl) {
|
} else if (log_lvl) {
|
||||||
console.log(`lu_time_zone: IDB fresh (${count} records), skipping refresh`);
|
console.log(
|
||||||
|
`lu_time_zone: IDB fresh (${count} records), skipping refresh`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import Dexie, { type Table } from 'dexie';
|
|||||||
|
|
||||||
export interface LuCountry {
|
export interface LuCountry {
|
||||||
id: number;
|
id: number;
|
||||||
group: string; // dedup key = alpha_2_code (e.g. "US")
|
group: string; // dedup key = alpha_2_code (e.g. "US")
|
||||||
alpha_2_code: string;
|
alpha_2_code: string;
|
||||||
name: string;
|
name: string;
|
||||||
english_short_name?: string;
|
english_short_name?: string;
|
||||||
@@ -22,12 +22,12 @@ export interface LuCountry {
|
|||||||
priority?: number;
|
priority?: number;
|
||||||
sort?: number;
|
sort?: number;
|
||||||
account_id?: number | null;
|
account_id?: number | null;
|
||||||
[key: string]: unknown; // allow extra fields from API without TS errors
|
[key: string]: unknown; // allow extra fields from API without TS errors
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LuCountrySubdivision {
|
export interface LuCountrySubdivision {
|
||||||
id: number;
|
id: number;
|
||||||
group: string; // dedup key = code (e.g. "US-NY")
|
group: string; // dedup key = code (e.g. "US-NY")
|
||||||
code: string;
|
code: string;
|
||||||
name: string;
|
name: string;
|
||||||
country_alpha_2_code?: string;
|
country_alpha_2_code?: string;
|
||||||
@@ -42,9 +42,9 @@ export interface LuCountrySubdivision {
|
|||||||
|
|
||||||
export interface LuTimeZone {
|
export interface LuTimeZone {
|
||||||
id: number;
|
id: number;
|
||||||
group: string; // dedup key = name (IANA identifier, e.g. "US/Eastern")
|
group: string; // dedup key = name (IANA identifier, e.g. "US/Eastern")
|
||||||
name: string;
|
name: string;
|
||||||
name_override?: string; // display label override; prefer this over name when set
|
name_override?: string; // display label override; prefer this over name when set
|
||||||
enable?: number;
|
enable?: number;
|
||||||
hide?: number;
|
hide?: number;
|
||||||
priority?: number;
|
priority?: number;
|
||||||
@@ -55,7 +55,7 @@ export interface LuTimeZone {
|
|||||||
|
|
||||||
export interface LuCacheMeta {
|
export interface LuCacheMeta {
|
||||||
lu_type: 'country' | 'country_subdivision' | 'time_zone';
|
lu_type: 'country' | 'country_subdivision' | 'time_zone';
|
||||||
refreshed_at: number; // Unix timestamp ms — used for 24h TTL check
|
refreshed_at: number; // Unix timestamp ms — used for 24h TTL check
|
||||||
}
|
}
|
||||||
|
|
||||||
class LookupsDexie extends Dexie {
|
class LookupsDexie extends Dexie {
|
||||||
@@ -67,10 +67,10 @@ class LookupsDexie extends Dexie {
|
|||||||
constructor() {
|
constructor() {
|
||||||
super('ae_lookups_db');
|
super('ae_lookups_db');
|
||||||
this.version(1).stores({
|
this.version(1).stores({
|
||||||
lu_country: 'id, alpha_2_code, group',
|
lu_country: 'id, alpha_2_code, group',
|
||||||
lu_country_subdivision: 'id, code, country_alpha_2_code, group',
|
lu_country_subdivision: 'id, code, country_alpha_2_code, group',
|
||||||
lu_time_zone: 'id, name, group',
|
lu_time_zone: 'id, name, group',
|
||||||
lu_cache_meta: 'lu_type'
|
lu_cache_meta: 'lu_type'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,125 +1,140 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
/**
|
/**
|
||||||
* AE_AITools.svelte
|
* AE_AITools.svelte
|
||||||
* GENERIC Aether AI Toolset (Runes/Svelte 5)
|
* GENERIC Aether AI Toolset (Runes/Svelte 5)
|
||||||
* Extracted logic from Journals module to be system-wide.
|
* Extracted logic from Journals module to be system-wide.
|
||||||
*/
|
*/
|
||||||
import OpenAI from 'openai';
|
import OpenAI from 'openai';
|
||||||
import { Modal } from 'flowbite-svelte';
|
import { Modal } from 'flowbite-svelte';
|
||||||
import {
|
import {
|
||||||
Bot, BotMessageSquare, Loader, FileText,
|
Bot,
|
||||||
Save, FilePenLine, RotateCcw, Settings,
|
BotMessageSquare,
|
||||||
RefreshCcw, Globe, Copy
|
Loader,
|
||||||
} from '@lucide/svelte';
|
FileText,
|
||||||
import { ae_loc, ae_api } from '$lib/stores/ae_stores';
|
Save,
|
||||||
import AE_Comp_Editor_CodeMirror from '$lib/elements/element_editor_codemirror.svelte';
|
FilePenLine,
|
||||||
|
RotateCcw,
|
||||||
|
Settings,
|
||||||
|
RefreshCcw,
|
||||||
|
Globe,
|
||||||
|
Copy
|
||||||
|
} from '@lucide/svelte';
|
||||||
|
import { ae_loc, ae_api } from '$lib/stores/ae_stores';
|
||||||
|
import AE_Comp_Editor_CodeMirror from '$lib/elements/element_editor_codemirror.svelte';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
// Core Props
|
// Core Props
|
||||||
content: string; // The text to summarize/analyze
|
content: string; // The text to summarize/analyze
|
||||||
summary: string; // The result (bindable)
|
summary: string; // The result (bindable)
|
||||||
|
|
||||||
// Configuration (Bindable for global settings persistence)
|
// Configuration (Bindable for global settings persistence)
|
||||||
model?: string;
|
model?: string;
|
||||||
baseUrl?: string;
|
baseUrl?: string;
|
||||||
token?: string;
|
token?: string;
|
||||||
systemPrompt?: string;
|
systemPrompt?: string;
|
||||||
maxTokens?: number;
|
maxTokens?: number;
|
||||||
temperature?: number;
|
temperature?: number;
|
||||||
|
|
||||||
// Callbacks
|
// Callbacks
|
||||||
onSave?: (newSummary: string) => void;
|
onSave?: (newSummary: string) => void;
|
||||||
onSyncConfig?: () => void; // Optional: callback to sync from global site config
|
onSyncConfig?: () => void; // Optional: callback to sync from global site config
|
||||||
|
|
||||||
// UI Customization
|
// UI Customization
|
||||||
buttonClass?: string;
|
buttonClass?: string;
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
let {
|
||||||
|
content,
|
||||||
|
summary = $bindable(),
|
||||||
|
model = $bindable(),
|
||||||
|
baseUrl = $bindable(),
|
||||||
|
token = $bindable(),
|
||||||
|
systemPrompt = $bindable(),
|
||||||
|
maxTokens = $bindable(),
|
||||||
|
temperature = $bindable(),
|
||||||
|
onSave,
|
||||||
|
onSyncConfig,
|
||||||
|
buttonClass = 'btn btn-sm preset-tonal-primary shadow-lg hover:scale-105 transition-all',
|
||||||
|
log_lvl = 0
|
||||||
|
}: Props = $props();
|
||||||
|
|
||||||
|
// Apply defaults if undefined (Safe for Svelte 5 Runes)
|
||||||
|
if (model === undefined) model = 'dgrzone-deepseek-8b-quick';
|
||||||
|
if (baseUrl === undefined) baseUrl = 'https://ai.dgrzone.com/api';
|
||||||
|
if (token === undefined) token = '';
|
||||||
|
if (systemPrompt === undefined) systemPrompt = 'You are a helpful assistant.';
|
||||||
|
if (maxTokens === undefined) maxTokens = 512;
|
||||||
|
if (temperature === undefined) temperature = 0.7;
|
||||||
|
|
||||||
|
// Internal State
|
||||||
|
let ae_promises: any = $state(null);
|
||||||
|
let show_modal = $state(false);
|
||||||
|
let active_tab: 'result' | 'settings' = $state('result');
|
||||||
|
let tmp_summary = $state('');
|
||||||
|
|
||||||
|
async function generate_ai_result() {
|
||||||
|
if (!content) {
|
||||||
|
alert('No content available to analyze.');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let {
|
active_tab = 'result';
|
||||||
content,
|
|
||||||
summary = $bindable(),
|
|
||||||
model = $bindable(),
|
|
||||||
baseUrl = $bindable(),
|
|
||||||
token = $bindable(),
|
|
||||||
systemPrompt = $bindable(),
|
|
||||||
maxTokens = $bindable(),
|
|
||||||
temperature = $bindable(),
|
|
||||||
onSave,
|
|
||||||
onSyncConfig,
|
|
||||||
buttonClass = "btn btn-sm preset-tonal-primary shadow-lg hover:scale-105 transition-all",
|
|
||||||
log_lvl = 0
|
|
||||||
}: Props = $props();
|
|
||||||
|
|
||||||
// Apply defaults if undefined (Safe for Svelte 5 Runes)
|
// If no token is provided, trigger a "Demo Mode" placeholder after a fake delay
|
||||||
if (model === undefined) model = 'dgrzone-deepseek-8b-quick';
|
if (!token || token === '') {
|
||||||
if (baseUrl === undefined) baseUrl = 'https://ai.dgrzone.com/api';
|
console.log('AE_AITools: No token provided. Entering Demo Mode.');
|
||||||
if (token === undefined) token = '';
|
ae_promises = new Promise((resolve) => {
|
||||||
if (systemPrompt === undefined) systemPrompt = 'You are a helpful assistant.';
|
setTimeout(() => {
|
||||||
if (maxTokens === undefined) maxTokens = 512;
|
tmp_summary = `### AI Summary (DEMO MODE)\n\nThis is a placeholder summary because no API token was provided in the settings. \n\n**Original Content Length:** ${content.length} characters.\n\n**System Prompt:** ${systemPrompt}\n\n**Model:** ${model}`;
|
||||||
if (temperature === undefined) temperature = 0.7;
|
show_modal = true;
|
||||||
|
resolve(true);
|
||||||
// Internal State
|
}, 1500);
|
||||||
let ae_promises: any = $state(null);
|
|
||||||
let show_modal = $state(false);
|
|
||||||
let active_tab: 'result' | 'settings' = $state('result');
|
|
||||||
let tmp_summary = $state('');
|
|
||||||
|
|
||||||
async function generate_ai_result() {
|
|
||||||
if (!content) {
|
|
||||||
alert('No content available to analyze.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
active_tab = 'result';
|
|
||||||
|
|
||||||
// If no token is provided, trigger a "Demo Mode" placeholder after a fake delay
|
|
||||||
if (!token || token === '') {
|
|
||||||
console.log('AE_AITools: No token provided. Entering Demo Mode.');
|
|
||||||
ae_promises = new Promise((resolve) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
tmp_summary = `### AI Summary (DEMO MODE)\n\nThis is a placeholder summary because no API token was provided in the settings. \n\n**Original Content Length:** ${content.length} characters.\n\n**System Prompt:** ${systemPrompt}\n\n**Model:** ${model}`;
|
|
||||||
show_modal = true;
|
|
||||||
resolve(true);
|
|
||||||
}, 1500);
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ai_client = new OpenAI({
|
|
||||||
apiKey: token,
|
|
||||||
baseURL: baseUrl,
|
|
||||||
dangerouslyAllowBrowser: true
|
|
||||||
});
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
const ai_client = new OpenAI({
|
||||||
ae_promises = ai_client.chat.completions.create({
|
apiKey: token,
|
||||||
|
baseURL: baseUrl,
|
||||||
|
dangerouslyAllowBrowser: true
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
ae_promises = ai_client.chat.completions
|
||||||
|
.create({
|
||||||
model: model || 'dgrzone-deepseek-8b-quick',
|
model: model || 'dgrzone-deepseek-8b-quick',
|
||||||
max_tokens: maxTokens,
|
max_tokens: maxTokens,
|
||||||
temperature: temperature,
|
temperature: temperature,
|
||||||
messages: [
|
messages: [
|
||||||
{ role: 'system', content: systemPrompt || 'You are a helpful assistant.' },
|
{
|
||||||
|
role: 'system',
|
||||||
|
content: systemPrompt || 'You are a helpful assistant.'
|
||||||
|
},
|
||||||
{ role: 'user', content: content }
|
{ role: 'user', content: content }
|
||||||
]
|
]
|
||||||
}).then((resp) => {
|
})
|
||||||
const result = resp?.choices?.[0]?.message?.content || 'No result generated.';
|
.then((resp) => {
|
||||||
|
const result =
|
||||||
|
resp?.choices?.[0]?.message?.content ||
|
||||||
|
'No result generated.';
|
||||||
tmp_summary = result;
|
tmp_summary = result;
|
||||||
show_modal = true;
|
show_modal = true;
|
||||||
});
|
});
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
console.error('AE_AITools: AI Error:', err);
|
console.error('AE_AITools: AI Error:', err);
|
||||||
// Even on error, show the modal with the error message so the UI can be inspected
|
// Even on error, show the modal with the error message so the UI can be inspected
|
||||||
tmp_summary = `### AI Error\n\nFailed to connect to the AI service.\n\n**Error:** ${err.message}\n\nCheck your Settings tab for Base URL and Token configuration.`;
|
tmp_summary = `### AI Error\n\nFailed to connect to the AI service.\n\n**Error:** ${err.message}\n\nCheck your Settings tab for Base URL and Token configuration.`;
|
||||||
show_modal = true;
|
show_modal = true;
|
||||||
ae_promises = Promise.resolve();
|
ae_promises = Promise.resolve();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function handle_save() {
|
function handle_save() {
|
||||||
summary = tmp_summary;
|
summary = tmp_summary;
|
||||||
if (onSave) onSave(tmp_summary);
|
if (onSave) onSave(tmp_summary);
|
||||||
show_modal = false;
|
show_modal = false;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="ae-ai-tools-wrapper inline-flex items-center gap-1">
|
<div class="ae-ai-tools-wrapper inline-flex items-center gap-1">
|
||||||
@@ -128,13 +143,12 @@
|
|||||||
type="button"
|
type="button"
|
||||||
onclick={generate_ai_result}
|
onclick={generate_ai_result}
|
||||||
class={buttonClass}
|
class={buttonClass}
|
||||||
title="Generate AI summary/analysis"
|
title="Generate AI summary/analysis">
|
||||||
>
|
|
||||||
{#await ae_promises}
|
{#await ae_promises}
|
||||||
<Loader class="inline-block mr-1 animate-spin" size="1.2em" />
|
<Loader class="mr-1 inline-block animate-spin" size="1.2em" />
|
||||||
<span class="text-sm">Processing...</span>
|
<span class="text-sm">Processing...</span>
|
||||||
{:then}
|
{:then}
|
||||||
<BotMessageSquare class="inline-block mr-1" size="1.2em" />
|
<BotMessageSquare class="mr-1 inline-block" size="1.2em" />
|
||||||
<span class="text-sm">Summarize</span>
|
<span class="text-sm">Summarize</span>
|
||||||
{:catch}
|
{:catch}
|
||||||
<span class="text-sm text-red-500">Error</span>
|
<span class="text-sm text-red-500">Error</span>
|
||||||
@@ -149,8 +163,7 @@
|
|||||||
show_modal = true;
|
show_modal = true;
|
||||||
}}
|
}}
|
||||||
class="btn btn-sm variant-soft-surface shadow-md"
|
class="btn btn-sm variant-soft-surface shadow-md"
|
||||||
title="AI Settings"
|
title="AI Settings">
|
||||||
>
|
|
||||||
<Settings size="1.2em" />
|
<Settings size="1.2em" />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@@ -160,32 +173,37 @@
|
|||||||
title="Aether AI Assistant"
|
title="Aether AI Assistant"
|
||||||
bind:open={show_modal}
|
bind:open={show_modal}
|
||||||
size="lg"
|
size="lg"
|
||||||
class="bg-white dark:bg-gray-800"
|
class="bg-white dark:bg-gray-800">
|
||||||
>
|
|
||||||
<div class="space-y-4 p-2">
|
<div class="space-y-4 p-2">
|
||||||
<!-- Tab Navigation -->
|
<!-- Tab Navigation -->
|
||||||
<div class="flex gap-1 border-b border-surface-500/20 pb-2">
|
<div class="border-surface-500/20 flex gap-1 border-b pb-2">
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm {active_tab === 'result' ? 'variant-filled-primary' : 'variant-soft-surface'}"
|
class="btn btn-sm {active_tab === 'result'
|
||||||
onclick={() => active_tab = 'result'}
|
? 'variant-filled-primary'
|
||||||
>
|
: 'variant-soft-surface'}"
|
||||||
|
onclick={() => (active_tab = 'result')}>
|
||||||
<Bot size="1.1em" class="mr-1" /> Result
|
<Bot size="1.1em" class="mr-1" /> Result
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm {active_tab === 'settings' ? 'variant-filled-secondary' : 'variant-soft-surface'}"
|
class="btn btn-sm {active_tab === 'settings'
|
||||||
onclick={() => active_tab = 'settings'}
|
? 'variant-filled-secondary'
|
||||||
>
|
: 'variant-soft-surface'}"
|
||||||
|
onclick={() => (active_tab = 'settings')}>
|
||||||
<Settings size="1.1em" class="mr-1" /> Settings
|
<Settings size="1.1em" class="mr-1" /> Settings
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if active_tab === 'result'}
|
{#if active_tab === 'result'}
|
||||||
<div class="space-y-4 animate-in fade-in duration-200">
|
<div class="animate-in fade-in space-y-4 duration-200">
|
||||||
<div class="flex gap-2 justify-start">
|
<div class="flex justify-start gap-2">
|
||||||
<button class="btn btn-sm variant-filled-success" onclick={handle_save}>
|
<button
|
||||||
|
class="btn btn-sm variant-filled-success"
|
||||||
|
onclick={handle_save}>
|
||||||
<Save size="1.1em" class="mr-1" /> Save Result
|
<Save size="1.1em" class="mr-1" /> Save Result
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-sm variant-ghost-primary" onclick={generate_ai_result}>
|
<button
|
||||||
|
class="btn btn-sm variant-ghost-primary"
|
||||||
|
onclick={generate_ai_result}>
|
||||||
<RotateCcw size="1.1em" class="mr-1" /> Re-run
|
<RotateCcw size="1.1em" class="mr-1" /> Re-run
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -195,57 +213,84 @@
|
|||||||
bind:new_content={tmp_summary}
|
bind:new_content={tmp_summary}
|
||||||
theme_mode={$ae_loc.theme_mode}
|
theme_mode={$ae_loc.theme_mode}
|
||||||
placeholder="AI Result will appear here..."
|
placeholder="AI Result will appear here..."
|
||||||
class_li="p-2 border rounded-lg h-96 shadow-inner bg-surface-500/5"
|
class_li="p-2 border rounded-lg h-96 shadow-inner bg-surface-500/5" />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<div class="space-y-6 animate-in slide-in-from-left-4 duration-200">
|
<div
|
||||||
|
class="animate-in slide-in-from-left-4 space-y-6 duration-200">
|
||||||
<!-- Connection Settings -->
|
<!-- Connection Settings -->
|
||||||
<div class="space-y-4">
|
<div class="space-y-4">
|
||||||
<h3 class="text-sm font-bold uppercase tracking-widest text-surface-500 flex items-center gap-2">
|
<h3
|
||||||
|
class="text-surface-500 flex items-center gap-2 text-sm font-bold tracking-widest uppercase">
|
||||||
<Globe size="1.1em" /> API Connection
|
<Globe size="1.1em" /> API Connection
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
{#if onSyncConfig}
|
{#if onSyncConfig}
|
||||||
<button class="btn btn-sm variant-soft-primary" onclick={onSyncConfig}>
|
<button
|
||||||
<Copy size="1.1em" class="mr-1" /> Sync Global Defaults
|
class="btn btn-sm variant-soft-primary"
|
||||||
|
onclick={onSyncConfig}>
|
||||||
|
<Copy size="1.1em" class="mr-1" /> Sync Global
|
||||||
|
Defaults
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span>Base URL</span>
|
<span>Base URL</span>
|
||||||
<input type="text" bind:value={baseUrl} class="input input-sm" />
|
<input
|
||||||
|
type="text"
|
||||||
|
bind:value={baseUrl}
|
||||||
|
class="input input-sm" />
|
||||||
</label>
|
</label>
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span>Model</span>
|
<span>Model</span>
|
||||||
<input type="text" bind:value={model} class="input input-sm" />
|
<input
|
||||||
|
type="text"
|
||||||
|
bind:value={model}
|
||||||
|
class="input input-sm" />
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span>API Token</span>
|
<span>API Token</span>
|
||||||
<input type="password" bind:value={token} class="input input-sm font-mono" />
|
<input
|
||||||
|
type="password"
|
||||||
|
bind:value={token}
|
||||||
|
class="input input-sm font-mono" />
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Model Parameters -->
|
<!-- Model Parameters -->
|
||||||
<div class="space-y-4 pt-4 border-t border-surface-500/10">
|
<div
|
||||||
<h3 class="text-sm font-bold uppercase tracking-widest text-surface-500 flex items-center gap-2">
|
class="border-surface-500/10 space-y-4 border-t pt-4">
|
||||||
|
<h3
|
||||||
|
class="text-surface-500 flex items-center gap-2 text-sm font-bold tracking-widest uppercase">
|
||||||
<FilePenLine size="1.1em" /> Inference Parameters
|
<FilePenLine size="1.1em" /> Inference Parameters
|
||||||
</h3>
|
</h3>
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span>Temperature ({temperature})</span>
|
<span>Temperature ({temperature})</span>
|
||||||
<input type="range" bind:value={temperature} min="0" max="1" step="0.1" class="range" />
|
<input
|
||||||
|
type="range"
|
||||||
|
bind:value={temperature}
|
||||||
|
min="0"
|
||||||
|
max="1"
|
||||||
|
step="0.1"
|
||||||
|
class="range" />
|
||||||
</label>
|
</label>
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span>Max Tokens</span>
|
<span>Max Tokens</span>
|
||||||
<input type="number" bind:value={maxTokens} class="input input-sm" />
|
<input
|
||||||
|
type="number"
|
||||||
|
bind:value={maxTokens}
|
||||||
|
class="input input-sm" />
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span>System Prompt</span>
|
<span>System Prompt</span>
|
||||||
<textarea bind:value={systemPrompt} class="textarea h-24 text-xs font-mono"></textarea>
|
<textarea
|
||||||
|
bind:value={systemPrompt}
|
||||||
|
class="textarea h-24 font-mono text-xs"
|
||||||
|
></textarea>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,58 +1,64 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
/**
|
/**
|
||||||
* AE_ObjectFlags.svelte
|
* AE_ObjectFlags.svelte
|
||||||
* GENERIC Aether Object Flags & Visibility Toggles
|
* GENERIC Aether Object Flags & Visibility Toggles
|
||||||
* Manages: alert, private, public, personal, professional, template
|
* Manages: alert, private, public, personal, professional, template
|
||||||
*/
|
*/
|
||||||
import {
|
import {
|
||||||
Siren, MessageSquareWarning, Fingerprint,
|
Siren,
|
||||||
Globe, BookHeart, BriefcaseBusiness, NotepadTextDashed,
|
MessageSquareWarning,
|
||||||
Settings
|
Fingerprint,
|
||||||
} from '@lucide/svelte';
|
Globe,
|
||||||
import { ae_loc } from '$lib/stores/ae_stores';
|
BookHeart,
|
||||||
|
BriefcaseBusiness,
|
||||||
|
NotepadTextDashed,
|
||||||
|
Settings
|
||||||
|
} from '@lucide/svelte';
|
||||||
|
import { ae_loc } from '$lib/stores/ae_stores';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
// The object containing the flags (bindable)
|
// The object containing the flags (bindable)
|
||||||
obj: any;
|
obj: any;
|
||||||
|
|
||||||
// Visibility configuration (optional overrides)
|
// Visibility configuration (optional overrides)
|
||||||
show_labels?: boolean;
|
show_labels?: boolean;
|
||||||
hide_alert?: boolean;
|
hide_alert?: boolean;
|
||||||
hide_private?: boolean;
|
hide_private?: boolean;
|
||||||
hide_public?: boolean;
|
hide_public?: boolean;
|
||||||
hide_personal?: boolean;
|
hide_personal?: boolean;
|
||||||
hide_professional?: boolean;
|
hide_professional?: boolean;
|
||||||
hide_template?: boolean;
|
hide_template?: boolean;
|
||||||
|
|
||||||
// Callbacks
|
// Callbacks
|
||||||
on_toggle?: (prop: string, newValue: boolean) => void;
|
on_toggle?: (prop: string, newValue: boolean) => void;
|
||||||
|
|
||||||
// Styling
|
// Styling
|
||||||
container_class?: string;
|
container_class?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
let {
|
let {
|
||||||
obj = $bindable(),
|
obj = $bindable(),
|
||||||
show_labels = true,
|
show_labels = true,
|
||||||
hide_alert: hide_alert = false,
|
hide_alert: hide_alert = false,
|
||||||
hide_private: hide_private = false,
|
hide_private: hide_private = false,
|
||||||
hide_public: hide_public = false,
|
hide_public: hide_public = false,
|
||||||
hide_personal: hide_personal = false,
|
hide_personal: hide_personal = false,
|
||||||
hide_professional: hide_professional = false,
|
hide_professional: hide_professional = false,
|
||||||
hide_template: hide_template = false,
|
hide_template: hide_template = false,
|
||||||
on_toggle: onToggle,
|
on_toggle: onToggle,
|
||||||
container_class = "flex flex-row flex-wrap gap-1 items-center justify-evenly py-2 border-y border-surface-500/10"
|
container_class = 'flex flex-row flex-wrap gap-1 items-center justify-evenly py-2 border-y border-surface-500/10'
|
||||||
}: Props = $props();
|
}: Props = $props();
|
||||||
|
|
||||||
function handle_toggle(prop: string) {
|
function handle_toggle(prop: string) {
|
||||||
obj[prop] = !obj[prop];
|
obj[prop] = !obj[prop];
|
||||||
if (onToggle) onToggle(prop, obj[prop]);
|
if (onToggle) onToggle(prop, obj[prop]);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class={container_class}>
|
<div class={container_class}>
|
||||||
{#if show_labels}
|
{#if show_labels}
|
||||||
<span class="text-xs text-surface-500 flex items-center gap-1 uppercase font-bold tracking-wider mr-2">
|
<span
|
||||||
|
class="text-surface-500 mr-2 flex items-center gap-1 text-xs font-bold tracking-wider uppercase">
|
||||||
<Settings size="1.1em" /> Flags:
|
<Settings size="1.1em" /> Flags:
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -63,9 +69,10 @@
|
|||||||
type="button"
|
type="button"
|
||||||
onclick={() => handle_toggle('alert')}
|
onclick={() => handle_toggle('alert')}
|
||||||
class="btn-icon btn-icon-sm preset-tonal-secondary hover:preset-filled-secondary-500 transition"
|
class="btn-icon btn-icon-sm preset-tonal-secondary hover:preset-filled-secondary-500 transition"
|
||||||
title="Toggle Alert Status"
|
title="Toggle Alert Status">
|
||||||
>
|
<Siren
|
||||||
<Siren size="1.2em" class={obj?.alert ? 'text-error-500' : 'opacity-40'} />
|
size="1.2em"
|
||||||
|
class={obj?.alert ? 'text-error-500' : 'opacity-40'} />
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
@@ -75,9 +82,10 @@
|
|||||||
type="button"
|
type="button"
|
||||||
onclick={() => handle_toggle('private')}
|
onclick={() => handle_toggle('private')}
|
||||||
class="btn-icon btn-icon-sm preset-tonal-secondary hover:preset-filled-secondary-500 transition"
|
class="btn-icon btn-icon-sm preset-tonal-secondary hover:preset-filled-secondary-500 transition"
|
||||||
title="Toggle Private/Encrypted"
|
title="Toggle Private/Encrypted">
|
||||||
>
|
<Fingerprint
|
||||||
<Fingerprint size="1.2em" class={obj?.private ? 'text-success-500' : 'opacity-40'} />
|
size="1.2em"
|
||||||
|
class={obj?.private ? 'text-success-500' : 'opacity-40'} />
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
@@ -87,9 +95,10 @@
|
|||||||
type="button"
|
type="button"
|
||||||
onclick={() => handle_toggle('public')}
|
onclick={() => handle_toggle('public')}
|
||||||
class="btn-icon btn-icon-sm preset-tonal-secondary hover:preset-filled-secondary-500 transition"
|
class="btn-icon btn-icon-sm preset-tonal-secondary hover:preset-filled-secondary-500 transition"
|
||||||
title="Toggle Public Visibility"
|
title="Toggle Public Visibility">
|
||||||
>
|
<Globe
|
||||||
<Globe size="1.2em" class={obj?.public ? 'text-success-500' : 'opacity-40'} />
|
size="1.2em"
|
||||||
|
class={obj?.public ? 'text-success-500' : 'opacity-40'} />
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
@@ -99,9 +108,10 @@
|
|||||||
type="button"
|
type="button"
|
||||||
onclick={() => handle_toggle('personal')}
|
onclick={() => handle_toggle('personal')}
|
||||||
class="btn-icon btn-icon-sm preset-tonal-secondary hover:preset-filled-secondary-500 transition"
|
class="btn-icon btn-icon-sm preset-tonal-secondary hover:preset-filled-secondary-500 transition"
|
||||||
title="Toggle Personal Scope"
|
title="Toggle Personal Scope">
|
||||||
>
|
<BookHeart
|
||||||
<BookHeart size="1.2em" class={obj?.personal ? 'text-success-500' : 'opacity-40'} />
|
size="1.2em"
|
||||||
|
class={obj?.personal ? 'text-success-500' : 'opacity-40'} />
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
@@ -111,9 +121,10 @@
|
|||||||
type="button"
|
type="button"
|
||||||
onclick={() => handle_toggle('professional')}
|
onclick={() => handle_toggle('professional')}
|
||||||
class="btn-icon btn-icon-sm preset-tonal-secondary hover:preset-filled-secondary-500 transition"
|
class="btn-icon btn-icon-sm preset-tonal-secondary hover:preset-filled-secondary-500 transition"
|
||||||
title="Toggle Professional Scope"
|
title="Toggle Professional Scope">
|
||||||
>
|
<BriefcaseBusiness
|
||||||
<BriefcaseBusiness size="1.2em" class={obj?.professional ? 'text-success-500' : 'opacity-40'} />
|
size="1.2em"
|
||||||
|
class={obj?.professional ? 'text-success-500' : 'opacity-40'} />
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
@@ -123,9 +134,10 @@
|
|||||||
type="button"
|
type="button"
|
||||||
onclick={() => handle_toggle('template')}
|
onclick={() => handle_toggle('template')}
|
||||||
class="btn-icon btn-icon-sm preset-tonal-secondary hover:preset-filled-secondary-500 transition"
|
class="btn-icon btn-icon-sm preset-tonal-secondary hover:preset-filled-secondary-500 transition"
|
||||||
title="Toggle Template Mode"
|
title="Toggle Template Mode">
|
||||||
>
|
<NotepadTextDashed
|
||||||
<NotepadTextDashed size="1.2em" class={obj?.template ? 'text-success-500' : 'opacity-40'} />
|
size="1.2em"
|
||||||
|
class={obj?.template ? 'text-success-500' : 'opacity-40'} />
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,95 +1,96 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
/**
|
/**
|
||||||
* AE_Record_Controls.svelte
|
* AE_Record_Controls.svelte
|
||||||
* GENERIC Aether Record Management Controls
|
* GENERIC Aether Record Management Controls
|
||||||
* Manages: priority, hide, enable, alert, delete/disable
|
* Manages: priority, hide, enable, alert, delete/disable
|
||||||
*
|
*
|
||||||
* Emits events — NO API calls. Parent is responsible for:
|
* Emits events — NO API calls. Parent is responsible for:
|
||||||
* 1. Calling the API (update_ae_obj, delete_ae_obj_id__*)
|
* 1. Calling the API (update_ae_obj, delete_ae_obj_id__*)
|
||||||
* 2. Refreshing the object from cache/API
|
* 2. Refreshing the object from cache/API
|
||||||
* 3. Navigating away on delete
|
* 3. Navigating away on delete
|
||||||
*
|
*
|
||||||
* Usage:
|
* Usage:
|
||||||
* <AE_Record_Controls
|
* <AE_Record_Controls
|
||||||
* obj={$lq__event_session_obj}
|
* obj={$lq__event_session_obj}
|
||||||
* obj_label="session"
|
* obj_label="session"
|
||||||
* allow_delete={$ae_loc.manager_access}
|
* allow_delete={$ae_loc.manager_access}
|
||||||
* allow_disable={$ae_loc.administrator_access}
|
* allow_disable={$ae_loc.administrator_access}
|
||||||
* on_toggle={(field, val) => { ... }}
|
* on_toggle={(field, val) => { ... }}
|
||||||
* on_delete={(method) => { ... }}
|
* on_delete={(method) => { ... }}
|
||||||
* />
|
* />
|
||||||
*/
|
*/
|
||||||
import {
|
import {
|
||||||
Star,
|
Star,
|
||||||
Eye,
|
Eye,
|
||||||
EyeOff,
|
EyeOff,
|
||||||
ToggleLeft,
|
ToggleLeft,
|
||||||
ToggleRight,
|
ToggleRight,
|
||||||
Bell,
|
Bell,
|
||||||
BellOff,
|
BellOff,
|
||||||
Trash2,
|
Trash2,
|
||||||
CircleMinus,
|
CircleMinus,
|
||||||
Settings
|
Settings
|
||||||
} from '@lucide/svelte';
|
} from '@lucide/svelte';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
// The object whose flags are being displayed (read-only — parent owns state)
|
// The object whose flags are being displayed (read-only — parent owns state)
|
||||||
obj: any;
|
obj: any;
|
||||||
|
|
||||||
// Human-readable label for confirm dialogs ("session", "presenter", "location", etc.)
|
// Human-readable label for confirm dialogs ("session", "presenter", "location", etc.)
|
||||||
obj_label?: string;
|
obj_label?: string;
|
||||||
|
|
||||||
// Visibility — hide any control that doesn't apply for this object type
|
// Visibility — hide any control that doesn't apply for this object type
|
||||||
show_alert?: boolean;
|
show_alert?: boolean;
|
||||||
show_priority?: boolean;
|
show_priority?: boolean;
|
||||||
show_enable?: boolean;
|
show_enable?: boolean;
|
||||||
show_hide?: boolean;
|
show_hide?: boolean;
|
||||||
show_labels?: boolean;
|
show_labels?: boolean;
|
||||||
|
|
||||||
// Permission gates — parent passes booleans derived from $ae_loc
|
// Permission gates — parent passes booleans derived from $ae_loc
|
||||||
allow_delete?: boolean; // Hard permanent delete (manager+)
|
allow_delete?: boolean; // Hard permanent delete (manager+)
|
||||||
allow_disable?: boolean; // Soft disable/remove (administrator+)
|
allow_disable?: boolean; // Soft disable/remove (administrator+)
|
||||||
|
|
||||||
// Callbacks — parent handles API + refresh + navigation
|
// Callbacks — parent handles API + refresh + navigation
|
||||||
on_toggle?: (field: string, new_val: boolean) => void;
|
on_toggle?: (field: string, new_val: boolean) => void;
|
||||||
on_delete?: (method: 'delete' | 'disable') => void;
|
on_delete?: (method: 'delete' | 'disable') => void;
|
||||||
|
|
||||||
// Styling
|
// Styling
|
||||||
container_class?: string;
|
container_class?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
let {
|
let {
|
||||||
obj,
|
obj,
|
||||||
obj_label = 'record',
|
obj_label = 'record',
|
||||||
show_alert = true,
|
show_alert = true,
|
||||||
show_priority = true,
|
show_priority = true,
|
||||||
show_enable = true,
|
show_enable = true,
|
||||||
show_hide = true,
|
show_hide = true,
|
||||||
show_labels = true,
|
show_labels = true,
|
||||||
allow_delete = false,
|
allow_delete = false,
|
||||||
allow_disable = false,
|
allow_disable = false,
|
||||||
on_toggle,
|
on_toggle,
|
||||||
on_delete,
|
on_delete,
|
||||||
container_class = 'flex flex-row flex-wrap gap-1 items-center justify-evenly py-2 border-y border-surface-500/10'
|
container_class = 'flex flex-row flex-wrap gap-1 items-center justify-evenly py-2 border-y border-surface-500/10'
|
||||||
}: Props = $props();
|
}: Props = $props();
|
||||||
|
|
||||||
function toggle(field: string) {
|
function toggle(field: string) {
|
||||||
if (on_toggle) on_toggle(field, !obj?.[field]);
|
if (on_toggle) on_toggle(field, !obj?.[field]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handle_delete(method: 'delete' | 'disable') {
|
function handle_delete(method: 'delete' | 'disable') {
|
||||||
const msg =
|
const msg =
|
||||||
method === 'delete'
|
method === 'delete'
|
||||||
? `Permanently delete this ${obj_label}? This cannot be undone.`
|
? `Permanently delete this ${obj_label}? This cannot be undone.`
|
||||||
: `Remove (disable) this ${obj_label}?`;
|
: `Remove (disable) this ${obj_label}?`;
|
||||||
if (!confirm(msg)) return;
|
if (!confirm(msg)) return;
|
||||||
if (on_delete) on_delete(method);
|
if (on_delete) on_delete(method);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class={container_class}>
|
<div class={container_class}>
|
||||||
{#if show_labels}
|
{#if show_labels}
|
||||||
<span class="text-xs text-surface-500 flex items-center gap-1 uppercase font-bold tracking-wider mr-2">
|
<span
|
||||||
|
class="text-surface-500 mr-2 flex items-center gap-1 text-xs font-bold tracking-wider uppercase">
|
||||||
<Settings size="1.1em" /> Controls:
|
<Settings size="1.1em" /> Controls:
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -103,12 +104,10 @@
|
|||||||
class:preset-filled-warning-500={obj?.priority}
|
class:preset-filled-warning-500={obj?.priority}
|
||||||
class:preset-tonal-secondary={!obj?.priority}
|
class:preset-tonal-secondary={!obj?.priority}
|
||||||
class:hover:preset-filled-warning-500={!obj?.priority}
|
class:hover:preset-filled-warning-500={!obj?.priority}
|
||||||
title={obj?.priority ? 'Remove priority flag' : 'Mark as priority'}
|
title={obj?.priority ? 'Remove priority flag' : 'Mark as priority'}>
|
||||||
>
|
|
||||||
<Star
|
<Star
|
||||||
size="1.2em"
|
size="1.2em"
|
||||||
class={obj?.priority ? 'fill-current' : 'opacity-50'}
|
class={obj?.priority ? 'fill-current' : 'opacity-50'} />
|
||||||
/>
|
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
@@ -121,8 +120,7 @@
|
|||||||
class:preset-filled-warning-500={obj?.hide}
|
class:preset-filled-warning-500={obj?.hide}
|
||||||
class:preset-tonal-secondary={!obj?.hide}
|
class:preset-tonal-secondary={!obj?.hide}
|
||||||
class:hover:preset-filled-warning-500={!obj?.hide}
|
class:hover:preset-filled-warning-500={!obj?.hide}
|
||||||
title={obj?.hide ? 'Unhide this record' : 'Hide this record'}
|
title={obj?.hide ? 'Unhide this record' : 'Hide this record'}>
|
||||||
>
|
|
||||||
{#if obj?.hide}
|
{#if obj?.hide}
|
||||||
<EyeOff size="1.2em" class="text-warning-500" />
|
<EyeOff size="1.2em" class="text-warning-500" />
|
||||||
{:else}
|
{:else}
|
||||||
@@ -140,8 +138,7 @@
|
|||||||
class:preset-filled-success-500={obj?.enable}
|
class:preset-filled-success-500={obj?.enable}
|
||||||
class:preset-filled-error-500={!obj?.enable}
|
class:preset-filled-error-500={!obj?.enable}
|
||||||
class:hover:preset-filled-success-500={!obj?.enable}
|
class:hover:preset-filled-success-500={!obj?.enable}
|
||||||
title={obj?.enable ? 'Disable this record' : 'Enable this record'}
|
title={obj?.enable ? 'Disable this record' : 'Enable this record'}>
|
||||||
>
|
|
||||||
{#if obj?.enable}
|
{#if obj?.enable}
|
||||||
<ToggleRight size="1.2em" class="text-success-300" />
|
<ToggleRight size="1.2em" class="text-success-300" />
|
||||||
{:else}
|
{:else}
|
||||||
@@ -159,8 +156,7 @@
|
|||||||
class:preset-filled-error-500={obj?.alert}
|
class:preset-filled-error-500={obj?.alert}
|
||||||
class:preset-tonal-secondary={!obj?.alert}
|
class:preset-tonal-secondary={!obj?.alert}
|
||||||
class:hover:preset-filled-error-500={!obj?.alert}
|
class:hover:preset-filled-error-500={!obj?.alert}
|
||||||
title={obj?.alert ? 'Remove alert status' : 'Mark as alert'}
|
title={obj?.alert ? 'Remove alert status' : 'Mark as alert'}>
|
||||||
>
|
|
||||||
{#if obj?.alert}
|
{#if obj?.alert}
|
||||||
<Bell size="1.2em" class="text-error-300" />
|
<Bell size="1.2em" class="text-error-300" />
|
||||||
{:else}
|
{:else}
|
||||||
@@ -175,8 +171,7 @@
|
|||||||
type="button"
|
type="button"
|
||||||
onclick={() => handle_delete('delete')}
|
onclick={() => handle_delete('delete')}
|
||||||
class="btn-icon btn-icon-sm preset-filled-error-500 hover:preset-filled-error-600 transition"
|
class="btn-icon btn-icon-sm preset-filled-error-500 hover:preset-filled-error-600 transition"
|
||||||
title="Permanently delete this {obj_label}"
|
title="Permanently delete this {obj_label}">
|
||||||
>
|
|
||||||
<Trash2 size="1.2em" />
|
<Trash2 size="1.2em" />
|
||||||
</button>
|
</button>
|
||||||
{:else if allow_disable}
|
{:else if allow_disable}
|
||||||
@@ -184,8 +179,7 @@
|
|||||||
type="button"
|
type="button"
|
||||||
onclick={() => handle_delete('disable')}
|
onclick={() => handle_delete('disable')}
|
||||||
class="btn-icon btn-icon-sm preset-filled-warning-500 hover:preset-filled-warning-600 transition"
|
class="btn-icon btn-icon-sm preset-filled-warning-500 hover:preset-filled-warning-600 transition"
|
||||||
title="Disable / soft-remove this {obj_label}"
|
title="Disable / soft-remove this {obj_label}">
|
||||||
>
|
|
||||||
<CircleMinus size="1.2em" />
|
<CircleMinus size="1.2em" />
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -46,7 +46,9 @@ export async function load_ae_obj_id__event({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_Event | null> {
|
}): Promise<ae_Event | null> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** load_ae_obj_id__event() *** event_id=${event_id} (SWR Optimization)`);
|
console.log(
|
||||||
|
`*** load_ae_obj_id__event() *** event_id=${event_id} (SWR Optimization)`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hierarchy Enforcement: Pulling presentations/presenters requires pulling sessions first
|
// Hierarchy Enforcement: Pulling presentations/presenters requires pulling sessions first
|
||||||
@@ -57,20 +59,43 @@ export async function load_ae_obj_id__event({
|
|||||||
try {
|
try {
|
||||||
const cached_event = await db_events.event.get(event_id);
|
const cached_event = await db_events.event.get(event_id);
|
||||||
if (cached_event) {
|
if (cached_event) {
|
||||||
if (log_lvl) console.log('EVENT LOAD: Cache hit. Returning stale data immediately.');
|
if (log_lvl)
|
||||||
|
console.log(
|
||||||
|
'EVENT LOAD: Cache hit. Returning stale data immediately.'
|
||||||
|
);
|
||||||
|
|
||||||
// Trigger background refresh
|
// Trigger background refresh
|
||||||
_refresh_event_background({
|
_refresh_event_background({
|
||||||
api_cfg, event_id, view, try_cache,
|
api_cfg,
|
||||||
inc_device_li, inc_file_li, inc_location_li, inc_session_li, inc_presentation_li, inc_presenter_li, inc_template_li,
|
event_id,
|
||||||
enabled, hidden,
|
view,
|
||||||
|
try_cache,
|
||||||
|
inc_device_li,
|
||||||
|
inc_file_li,
|
||||||
|
inc_location_li,
|
||||||
|
inc_session_li,
|
||||||
|
inc_presentation_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
inc_template_li,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
log_lvl: 0
|
log_lvl: 0
|
||||||
});
|
});
|
||||||
|
|
||||||
// Still handle nested loads for the cached version to ensure UI richness
|
// Still handle nested loads for the cached version to ensure UI richness
|
||||||
return await _handle_nested_loads(cached_event, {
|
return await _handle_nested_loads(cached_event, {
|
||||||
api_cfg, inc_device_li, inc_file_li, inc_location_li, inc_session_li, inc_presentation_li, inc_presenter_li, inc_template_li,
|
api_cfg,
|
||||||
enabled, hidden, try_cache, log_lvl
|
inc_device_li,
|
||||||
|
inc_file_li,
|
||||||
|
inc_location_li,
|
||||||
|
inc_session_li,
|
||||||
|
inc_presentation_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
inc_template_li,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
try_cache,
|
||||||
|
log_lvl
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -80,9 +105,19 @@ export async function load_ae_obj_id__event({
|
|||||||
|
|
||||||
// 2. SLOW PATH: Wait for API if cache is empty or try_cache is false
|
// 2. SLOW PATH: Wait for API if cache is empty or try_cache is false
|
||||||
return await _refresh_event_background({
|
return await _refresh_event_background({
|
||||||
api_cfg, event_id, view, try_cache,
|
api_cfg,
|
||||||
inc_device_li, inc_file_li, inc_location_li, inc_session_li, inc_presentation_li, inc_presenter_li, inc_template_li,
|
event_id,
|
||||||
enabled, hidden,
|
view,
|
||||||
|
try_cache,
|
||||||
|
inc_device_li,
|
||||||
|
inc_file_li,
|
||||||
|
inc_location_li,
|
||||||
|
inc_session_li,
|
||||||
|
inc_presentation_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
inc_template_li,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -91,9 +126,19 @@ export async function load_ae_obj_id__event({
|
|||||||
* Internal helper to perform the actual API fetch and cache update for events
|
* Internal helper to perform the actual API fetch and cache update for events
|
||||||
*/
|
*/
|
||||||
async function _refresh_event_background({
|
async function _refresh_event_background({
|
||||||
api_cfg, event_id, view, try_cache,
|
api_cfg,
|
||||||
inc_device_li, inc_file_li, inc_location_li, inc_session_li, inc_presentation_li, inc_presenter_li, inc_template_li,
|
event_id,
|
||||||
enabled, hidden,
|
view,
|
||||||
|
try_cache,
|
||||||
|
inc_device_li,
|
||||||
|
inc_file_li,
|
||||||
|
inc_location_li,
|
||||||
|
inc_session_li,
|
||||||
|
inc_presentation_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
inc_template_li,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
log_lvl
|
log_lvl
|
||||||
}: any) {
|
}: any) {
|
||||||
// Check if offline
|
// Check if offline
|
||||||
@@ -129,8 +174,18 @@ async function _refresh_event_background({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return await _handle_nested_loads(processed_obj, {
|
return await _handle_nested_loads(processed_obj, {
|
||||||
api_cfg, inc_device_li, inc_file_li, inc_location_li, inc_session_li, inc_presentation_li, inc_presenter_li, inc_template_li,
|
api_cfg,
|
||||||
enabled, hidden, try_cache: false, log_lvl
|
inc_device_li,
|
||||||
|
inc_file_li,
|
||||||
|
inc_location_li,
|
||||||
|
inc_session_li,
|
||||||
|
inc_presentation_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
inc_template_li,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
try_cache: false,
|
||||||
|
log_lvl
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
@@ -142,8 +197,27 @@ async function _refresh_event_background({
|
|||||||
/**
|
/**
|
||||||
* Shared logic for loading nested child collections
|
* Shared logic for loading nested child collections
|
||||||
*/
|
*/
|
||||||
async function _handle_nested_loads(event_obj: any, { api_cfg, inc_device_li, inc_file_li, inc_location_li, inc_session_li, inc_presentation_li, inc_presenter_li, inc_template_li, enabled, hidden, try_cache, log_lvl }: any) {
|
async function _handle_nested_loads(
|
||||||
if (log_lvl) console.log(`Loading nested collections for event: ${event_obj.event_id} (Devices: ${inc_device_li}, Files: ${inc_file_li}, Locations: ${inc_location_li}, Sessions: ${inc_session_li}, Presentations: ${inc_presentation_li}, Presenters: ${inc_presenter_li}, Templates: ${inc_template_li})`);
|
event_obj: any,
|
||||||
|
{
|
||||||
|
api_cfg,
|
||||||
|
inc_device_li,
|
||||||
|
inc_file_li,
|
||||||
|
inc_location_li,
|
||||||
|
inc_session_li,
|
||||||
|
inc_presentation_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
inc_template_li,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
try_cache,
|
||||||
|
log_lvl
|
||||||
|
}: any
|
||||||
|
) {
|
||||||
|
if (log_lvl)
|
||||||
|
console.log(
|
||||||
|
`Loading nested collections for event: ${event_obj.event_id} (Devices: ${inc_device_li}, Files: ${inc_file_li}, Locations: ${inc_location_li}, Sessions: ${inc_session_li}, Presentations: ${inc_presentation_li}, Presenters: ${inc_presenter_li}, Templates: ${inc_template_li})`
|
||||||
|
);
|
||||||
// String-Only ID Vision: the '_id' field IS the string ID
|
// String-Only ID Vision: the '_id' field IS the string ID
|
||||||
const current_event_id = event_obj.id || event_obj.event_id;
|
const current_event_id = event_obj.id || event_obj.event_id;
|
||||||
|
|
||||||
@@ -151,56 +225,66 @@ async function _handle_nested_loads(event_obj: any, { api_cfg, inc_device_li, in
|
|||||||
const tasks = [];
|
const tasks = [];
|
||||||
|
|
||||||
if (inc_device_li) {
|
if (inc_device_li) {
|
||||||
tasks.push(load_ae_obj_li__event_device({
|
tasks.push(
|
||||||
api_cfg,
|
load_ae_obj_li__event_device({
|
||||||
for_obj_type: 'event',
|
api_cfg,
|
||||||
for_obj_id: current_event_id,
|
for_obj_type: 'event',
|
||||||
try_cache,
|
for_obj_id: current_event_id,
|
||||||
log_lvl
|
try_cache,
|
||||||
}).then(res => event_obj.event_device_obj_li = res));
|
log_lvl
|
||||||
|
}).then((res) => (event_obj.event_device_obj_li = res))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (inc_file_li) {
|
if (inc_file_li) {
|
||||||
tasks.push(load_ae_obj_li__event_file({
|
tasks.push(
|
||||||
api_cfg,
|
load_ae_obj_li__event_file({
|
||||||
for_obj_type: 'event',
|
api_cfg,
|
||||||
for_obj_id: current_event_id,
|
for_obj_type: 'event',
|
||||||
enabled: 'all',
|
for_obj_id: current_event_id,
|
||||||
limit: 100,
|
enabled: 'all',
|
||||||
try_cache,
|
limit: 100,
|
||||||
log_lvl
|
try_cache,
|
||||||
}).then(res => event_obj.event_file_li = res));
|
log_lvl
|
||||||
|
}).then((res) => (event_obj.event_file_li = res))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (inc_location_li) {
|
if (inc_location_li) {
|
||||||
tasks.push(load_ae_obj_li__event_location({
|
tasks.push(
|
||||||
api_cfg,
|
load_ae_obj_li__event_location({
|
||||||
for_obj_type: 'event',
|
api_cfg,
|
||||||
for_obj_id: current_event_id,
|
for_obj_type: 'event',
|
||||||
enabled,
|
for_obj_id: current_event_id,
|
||||||
hidden,
|
enabled,
|
||||||
try_cache,
|
hidden,
|
||||||
log_lvl
|
try_cache,
|
||||||
}).then(res => event_obj.event_location_obj_li = res));
|
log_lvl
|
||||||
|
}).then((res) => (event_obj.event_location_obj_li = res))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (inc_session_li) {
|
if (inc_session_li) {
|
||||||
tasks.push(load_ae_obj_li__event_session({
|
tasks.push(
|
||||||
api_cfg,
|
load_ae_obj_li__event_session({
|
||||||
for_obj_type: 'event',
|
api_cfg,
|
||||||
for_obj_id: current_event_id,
|
for_obj_type: 'event',
|
||||||
inc_presentation_li,
|
for_obj_id: current_event_id,
|
||||||
inc_presenter_li,
|
inc_presentation_li,
|
||||||
enabled,
|
inc_presenter_li,
|
||||||
hidden,
|
enabled,
|
||||||
try_cache,
|
hidden,
|
||||||
log_lvl
|
try_cache,
|
||||||
}).then(res => event_obj.event_session_obj_li = res));
|
log_lvl
|
||||||
|
}).then((res) => (event_obj.event_session_obj_li = res))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (inc_template_li) {
|
if (inc_template_li) {
|
||||||
tasks.push(load_ae_obj_li__event_badge_template({
|
tasks.push(
|
||||||
api_cfg,
|
load_ae_obj_li__event_badge_template({
|
||||||
event_id: current_event_id,
|
api_cfg,
|
||||||
try_cache,
|
event_id: current_event_id,
|
||||||
log_lvl
|
try_cache,
|
||||||
}).then(res => event_obj.event_badge_template_obj_li = res));
|
log_lvl
|
||||||
|
}).then((res) => (event_obj.event_badge_template_obj_li = res))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tasks.length > 0) await Promise.all(tasks);
|
if (tasks.length > 0) await Promise.all(tasks);
|
||||||
@@ -238,20 +322,25 @@ export async function load_ae_obj_li__event({
|
|||||||
inc_presenter_li?: boolean;
|
inc_presenter_li?: boolean;
|
||||||
limit?: number;
|
limit?: number;
|
||||||
offset?: number;
|
offset?: number;
|
||||||
order_by_li?: Record<string, 'ASC' | 'DESC'> | Record<string, 'ASC' | 'DESC'>[];
|
order_by_li?:
|
||||||
|
| Record<string, 'ASC' | 'DESC'>
|
||||||
|
| Record<string, 'ASC' | 'DESC'>[];
|
||||||
params?: key_val;
|
params?: key_val;
|
||||||
try_cache?: boolean;
|
try_cache?: boolean;
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_Event[]> {
|
}): Promise<ae_Event[]> {
|
||||||
|
|
||||||
// Hierarchy Enforcement: Pulling presentations/presenters requires pulling sessions first
|
// Hierarchy Enforcement: Pulling presentations/presenters requires pulling sessions first
|
||||||
if (inc_presenter_li || inc_presentation_li) inc_session_li = true;
|
if (inc_presenter_li || inc_presentation_li) inc_session_li = true;
|
||||||
|
|
||||||
// Check if offline
|
// Check if offline
|
||||||
if (typeof navigator !== 'undefined' && !navigator.onLine) {
|
if (typeof navigator !== 'undefined' && !navigator.onLine) {
|
||||||
if (log_lvl) console.log('Browser is offline. Skipping API and attempting cache load.');
|
if (log_lvl)
|
||||||
|
console.log(
|
||||||
|
'Browser is offline. Skipping API and attempting cache load.'
|
||||||
|
);
|
||||||
ae_promises.load__event_obj_li = await db_events.event
|
ae_promises.load__event_obj_li = await db_events.event
|
||||||
.where('account_id').equals(for_obj_id)
|
.where('account_id')
|
||||||
|
.equals(for_obj_id)
|
||||||
.toArray();
|
.toArray();
|
||||||
return ae_promises.load__event_obj_li || [];
|
return ae_promises.load__event_obj_li || [];
|
||||||
}
|
}
|
||||||
@@ -264,7 +353,11 @@ export async function load_ae_obj_li__event({
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (for_obj_id) {
|
if (for_obj_id) {
|
||||||
search_query.and.push({ field: `${for_obj_type}_id`, op: 'eq', value: for_obj_id });
|
search_query.and.push({
|
||||||
|
field: `${for_obj_type}_id`,
|
||||||
|
op: 'eq',
|
||||||
|
value: for_obj_id
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
promise = api.search_ae_obj({
|
promise = api.search_ae_obj({
|
||||||
@@ -319,9 +412,11 @@ export async function load_ae_obj_li__event({
|
|||||||
} else {
|
} else {
|
||||||
console.log('No results returned from API.');
|
console.log('No results returned from API.');
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
if (log_lvl) console.log('Attempting to load from local cache...');
|
if (log_lvl)
|
||||||
|
console.log('Attempting to load from local cache...');
|
||||||
ae_promises.load__event_obj_li = await db_events.event
|
ae_promises.load__event_obj_li = await db_events.event
|
||||||
.where('account_id').equals(for_obj_id)
|
.where('account_id')
|
||||||
|
.equals(for_obj_id)
|
||||||
.toArray();
|
.toArray();
|
||||||
} else {
|
} else {
|
||||||
ae_promises.load__event_obj_li = [];
|
ae_promises.load__event_obj_li = [];
|
||||||
@@ -330,9 +425,13 @@ export async function load_ae_obj_li__event({
|
|||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log('API request failed.', error);
|
console.log('API request failed.', error);
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
if (log_lvl) console.log('Attempting to load from local cache after error...');
|
if (log_lvl)
|
||||||
|
console.log(
|
||||||
|
'Attempting to load from local cache after error...'
|
||||||
|
);
|
||||||
ae_promises.load__event_obj_li = await db_events.event
|
ae_promises.load__event_obj_li = await db_events.event
|
||||||
.where('account_id').equals(for_obj_id)
|
.where('account_id')
|
||||||
|
.equals(for_obj_id)
|
||||||
.toArray();
|
.toArray();
|
||||||
} else {
|
} else {
|
||||||
ae_promises.load__event_obj_li = [];
|
ae_promises.load__event_obj_li = [];
|
||||||
@@ -340,18 +439,20 @@ export async function load_ae_obj_li__event({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (inc_session_li && ae_promises.load__event_obj_li) {
|
if (inc_session_li && ae_promises.load__event_obj_li) {
|
||||||
const session_tasks = ae_promises.load__event_obj_li.map((event_obj: any) => {
|
const session_tasks = ae_promises.load__event_obj_li.map(
|
||||||
const current_event_id = event_obj.id || event_obj.event_id;
|
(event_obj: any) => {
|
||||||
return load_ae_obj_li__event_session({
|
const current_event_id = event_obj.id || event_obj.event_id;
|
||||||
api_cfg,
|
return load_ae_obj_li__event_session({
|
||||||
for_obj_type: 'event',
|
api_cfg,
|
||||||
for_obj_id: current_event_id,
|
for_obj_type: 'event',
|
||||||
inc_presentation_li,
|
for_obj_id: current_event_id,
|
||||||
inc_presenter_li,
|
inc_presentation_li,
|
||||||
try_cache,
|
inc_presenter_li,
|
||||||
log_lvl
|
try_cache,
|
||||||
}).then((res) => (event_obj.event_session_obj_li = res));
|
log_lvl
|
||||||
});
|
}).then((res) => (event_obj.event_session_obj_li = res));
|
||||||
|
}
|
||||||
|
);
|
||||||
await Promise.all(session_tasks);
|
await Promise.all(session_tasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -543,13 +644,21 @@ export async function search__event({
|
|||||||
};
|
};
|
||||||
const params: key_val = {};
|
const params: key_val = {};
|
||||||
|
|
||||||
search_query.and.push({ field: 'default_qry_str', op: 'like', value: `%${qry_str.trim()}%` });
|
search_query.and.push({
|
||||||
params['lk_qry'] = { 'default_qry_str': qry_str.trim() };
|
field: 'default_qry_str',
|
||||||
|
op: 'like',
|
||||||
|
value: `%${qry_str.trim()}%`
|
||||||
|
});
|
||||||
|
params['lk_qry'] = { default_qry_str: qry_str.trim() };
|
||||||
|
|
||||||
if (for_obj_id) {
|
if (for_obj_id) {
|
||||||
// V3 Standard: Use random string ID for body filters.
|
// V3 Standard: Use random string ID for body filters.
|
||||||
// The API resolves this to the integer column automatically.
|
// The API resolves this to the integer column automatically.
|
||||||
search_query.and.push({ field: `${for_obj_type}_id_random`, op: 'eq', value: for_obj_id });
|
search_query.and.push({
|
||||||
|
field: `${for_obj_type}_id_random`,
|
||||||
|
op: 'eq',
|
||||||
|
value: for_obj_id
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: We do NOT push 'physical' and 'virtual' to the server-side query here.
|
// NOTE: We do NOT push 'physical' and 'virtual' to the server-side query here.
|
||||||
@@ -593,7 +702,11 @@ export async function search__event({
|
|||||||
let valid_result_li: ae_Event[] = [];
|
let valid_result_li: ae_Event[] = [];
|
||||||
if (Array.isArray(result_li)) {
|
if (Array.isArray(result_li)) {
|
||||||
valid_result_li = result_li;
|
valid_result_li = result_li;
|
||||||
} else if (result_li && typeof result_li === 'object' && Array.isArray((result_li as any).data)) {
|
} else if (
|
||||||
|
result_li &&
|
||||||
|
typeof result_li === 'object' &&
|
||||||
|
Array.isArray((result_li as any).data)
|
||||||
|
) {
|
||||||
valid_result_li = (result_li as any).data;
|
valid_result_li = (result_li as any).data;
|
||||||
} else {
|
} else {
|
||||||
return [];
|
return [];
|
||||||
@@ -641,13 +754,12 @@ export async function search__event({
|
|||||||
|
|
||||||
// Handle person ID filter
|
// Handle person ID filter
|
||||||
if (qry_person_id) {
|
if (qry_person_id) {
|
||||||
const match = (
|
const match =
|
||||||
ev.external_person_id === qry_person_id ||
|
ev.external_person_id === qry_person_id ||
|
||||||
ev.poc_person_id === qry_person_id ||
|
ev.poc_person_id === qry_person_id ||
|
||||||
ev.poc_person_id_random === qry_person_id ||
|
ev.poc_person_id_random === qry_person_id ||
|
||||||
ev.poc_event_person_id === qry_person_id ||
|
ev.poc_event_person_id === qry_person_id ||
|
||||||
ev.poc_event_person_id_random === qry_person_id
|
ev.poc_event_person_id_random === qry_person_id;
|
||||||
);
|
|
||||||
if (!match) return false;
|
if (!match) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -655,7 +767,9 @@ export async function search__event({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`Filter results (Hybrid): Input=${processed_obj_li.length}, Output=${filtered_obj_li.length}`);
|
console.log(
|
||||||
|
`Filter results (Hybrid): Input=${processed_obj_li.length}, Output=${filtered_obj_li.length}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return filtered_obj_li.slice(0, limit);
|
return filtered_obj_li.slice(0, limit);
|
||||||
@@ -663,7 +777,6 @@ export async function search__event({
|
|||||||
|
|
||||||
export const qry_ae_obj_li__event = search__event;
|
export const qry_ae_obj_li__event = search__event;
|
||||||
|
|
||||||
|
|
||||||
// Updated 2026-03-10
|
// Updated 2026-03-10
|
||||||
export const properties_to_save = [
|
export const properties_to_save = [
|
||||||
'id',
|
'id',
|
||||||
@@ -780,14 +893,21 @@ async function _process_generic_props<T extends Record<string, any>>({
|
|||||||
const group = processed_obj.group ?? '0';
|
const group = processed_obj.group ?? '0';
|
||||||
const priority = processed_obj.priority ? 1 : 0;
|
const priority = processed_obj.priority ? 1 : 0;
|
||||||
const sort = processed_obj.sort ?? '0';
|
const sort = processed_obj.sort ?? '0';
|
||||||
const updated = processed_obj.updated_on ?? processed_obj.created_on ?? new Date(0).toISOString();
|
const updated =
|
||||||
|
processed_obj.updated_on ??
|
||||||
|
processed_obj.created_on ??
|
||||||
|
new Date(0).toISOString();
|
||||||
const name = processed_obj.name ?? '';
|
const name = processed_obj.name ?? '';
|
||||||
|
|
||||||
(processed_obj as any).tmp_sort_1 = `${group}_${priority}_${sort}_${updated}`;
|
(processed_obj as any).tmp_sort_1 =
|
||||||
(processed_obj as any).tmp_sort_2 = `${group}_${priority}_${sort}_${name}_${updated}`;
|
`${group}_${priority}_${sort}_${updated}`;
|
||||||
|
(processed_obj as any).tmp_sort_2 =
|
||||||
|
`${group}_${priority}_${sort}_${name}_${updated}`;
|
||||||
|
|
||||||
if (specific_processor) {
|
if (specific_processor) {
|
||||||
processed_obj = await Promise.resolve(specific_processor(processed_obj));
|
processed_obj = await Promise.resolve(
|
||||||
|
specific_processor(processed_obj)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
processed_obj_li.push(processed_obj as T);
|
processed_obj_li.push(processed_obj as T);
|
||||||
@@ -849,7 +969,8 @@ export function sync_config__event_pres_mgmt({
|
|||||||
pres_mgmt_cfg_remote?.label__session_poc_name_short ?? 'POC';
|
pres_mgmt_cfg_remote?.label__session_poc_name_short ?? 'POC';
|
||||||
pres_mgmt_cfg_local.label__session_poc_name =
|
pres_mgmt_cfg_local.label__session_poc_name =
|
||||||
pres_mgmt_cfg_remote?.label__session_poc_name ?? 'Point of Contact';
|
pres_mgmt_cfg_remote?.label__session_poc_name ?? 'Point of Contact';
|
||||||
pres_mgmt_cfg_local.hide__session_poc = pres_mgmt_cfg_remote?.hide__session_poc ?? false;
|
pres_mgmt_cfg_local.hide__session_poc =
|
||||||
|
pres_mgmt_cfg_remote?.hide__session_poc ?? false;
|
||||||
pres_mgmt_cfg_local.require__presenter_agree =
|
pres_mgmt_cfg_local.require__presenter_agree =
|
||||||
pres_mgmt_cfg_remote?.require__presenter_agree ?? false;
|
pres_mgmt_cfg_remote?.require__presenter_agree ?? false;
|
||||||
pres_mgmt_cfg_local.require__session_agree =
|
pres_mgmt_cfg_local.require__session_agree =
|
||||||
@@ -874,24 +995,28 @@ export function sync_config__event_pres_mgmt({
|
|||||||
pres_mgmt_cfg_local.hide__presentation_datetime =
|
pres_mgmt_cfg_local.hide__presentation_datetime =
|
||||||
pres_mgmt_cfg_remote?.hide__presentation_datetime ?? false;
|
pres_mgmt_cfg_remote?.hide__presentation_datetime ?? false;
|
||||||
pres_mgmt_cfg_local.show_content__presentation_description =
|
pres_mgmt_cfg_local.show_content__presentation_description =
|
||||||
pres_mgmt_cfg_remote?.show_content__presentation_description ?? false;
|
pres_mgmt_cfg_remote?.show_content__presentation_description ??
|
||||||
|
false;
|
||||||
pres_mgmt_cfg_local.hide__presenter_code =
|
pres_mgmt_cfg_local.hide__presenter_code =
|
||||||
pres_mgmt_cfg_remote?.hide__presenter_code ?? false;
|
pres_mgmt_cfg_remote?.hide__presenter_code ?? false;
|
||||||
pres_mgmt_cfg_local.hide__presenter_biography =
|
pres_mgmt_cfg_local.hide__presenter_biography =
|
||||||
pres_mgmt_cfg_remote?.hide__presenter_biography ?? false;
|
pres_mgmt_cfg_remote?.hide__presenter_biography ?? false;
|
||||||
pres_mgmt_cfg_local.hide__session_code = pres_mgmt_cfg_remote?.hide__session_code ?? false;
|
pres_mgmt_cfg_local.hide__session_code =
|
||||||
|
pres_mgmt_cfg_remote?.hide__session_code ?? false;
|
||||||
pres_mgmt_cfg_local.hide__session_description =
|
pres_mgmt_cfg_local.hide__session_description =
|
||||||
pres_mgmt_cfg_remote?.hide__session_description ?? false;
|
pres_mgmt_cfg_remote?.hide__session_description ?? false;
|
||||||
pres_mgmt_cfg_local.hide__session_location =
|
pres_mgmt_cfg_local.hide__session_location =
|
||||||
pres_mgmt_cfg_remote?.hide__session_location ?? false;
|
pres_mgmt_cfg_remote?.hide__session_location ?? false;
|
||||||
pres_mgmt_cfg_local.hide__session_msg = pres_mgmt_cfg_remote?.hide__session_msg ?? false;
|
pres_mgmt_cfg_local.hide__session_msg =
|
||||||
|
pres_mgmt_cfg_remote?.hide__session_msg ?? false;
|
||||||
pres_mgmt_cfg_local.hide__session_poc_profile =
|
pres_mgmt_cfg_local.hide__session_poc_profile =
|
||||||
pres_mgmt_cfg_remote?.hide__session_poc_profile ?? false;
|
pres_mgmt_cfg_remote?.hide__session_poc_profile ?? false;
|
||||||
pres_mgmt_cfg_local.hide__session_poc_biography =
|
pres_mgmt_cfg_local.hide__session_poc_biography =
|
||||||
pres_mgmt_cfg_remote?.hide__session_poc_biography ?? false;
|
pres_mgmt_cfg_remote?.hide__session_poc_biography ?? false;
|
||||||
pres_mgmt_cfg_local.hide__session_poc_profile_pic =
|
pres_mgmt_cfg_local.hide__session_poc_profile_pic =
|
||||||
pres_mgmt_cfg_remote?.hide__session_poc_profile_pic ?? false;
|
pres_mgmt_cfg_remote?.hide__session_poc_profile_pic ?? false;
|
||||||
pres_mgmt_cfg_local.hide_launcher_link = pres_mgmt_cfg_remote?.hide_launcher_link ?? false;
|
pres_mgmt_cfg_local.hide_launcher_link =
|
||||||
|
pres_mgmt_cfg_remote?.hide_launcher_link ?? false;
|
||||||
pres_mgmt_cfg_local.hide_launcher_link_legacy =
|
pres_mgmt_cfg_local.hide_launcher_link_legacy =
|
||||||
pres_mgmt_cfg_remote?.hide_launcher_link_legacy ?? false;
|
pres_mgmt_cfg_remote?.hide_launcher_link_legacy ?? false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,9 +9,15 @@ vi.mock('$lib/api/api', () => ({
|
|||||||
search_ae_obj: vi.fn()
|
search_ae_obj: vi.fn()
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
vi.mock('$lib/ae_core/core__idb_dexie', () => ({ db_save_ae_obj_li__ae_obj: vi.fn() }));
|
vi.mock('$lib/ae_core/core__idb_dexie', () => ({
|
||||||
vi.mock('$lib/ae_events/db_events', () => ({ db_events: { badge: { get: vi.fn(), delete: vi.fn() } } }));
|
db_save_ae_obj_li__ae_obj: vi.fn()
|
||||||
vi.mock('$lib/ae_events/ae_events__event_badge_template', () => ({ load_ae_obj_id__event_badge_template: vi.fn() }));
|
}));
|
||||||
|
vi.mock('$lib/ae_events/db_events', () => ({
|
||||||
|
db_events: { badge: { get: vi.fn(), delete: vi.fn() } }
|
||||||
|
}));
|
||||||
|
vi.mock('$lib/ae_events/ae_events__event_badge_template', () => ({
|
||||||
|
load_ae_obj_id__event_badge_template: vi.fn()
|
||||||
|
}));
|
||||||
|
|
||||||
import { create_ae_obj__event_badge } from './ae_events__event_badge';
|
import { create_ae_obj__event_badge } from './ae_events__event_badge';
|
||||||
|
|
||||||
@@ -25,9 +31,17 @@ describe('create_ae_obj__event_badge', () => {
|
|||||||
|
|
||||||
const api_cfg = { base_url: 'http://localhost', headers: {} };
|
const api_cfg = { base_url: 'http://localhost', headers: {} };
|
||||||
const event_id = 'evt1';
|
const event_id = 'evt1';
|
||||||
const data_kv = { full_name_override: 'Test User', email: 't@example.com' };
|
const data_kv = {
|
||||||
|
full_name_override: 'Test User',
|
||||||
|
email: 't@example.com'
|
||||||
|
};
|
||||||
|
|
||||||
const result = await create_ae_obj__event_badge({ api_cfg, event_id, data_kv, try_cache: false });
|
const result = await create_ae_obj__event_badge({
|
||||||
|
api_cfg,
|
||||||
|
event_id,
|
||||||
|
data_kv,
|
||||||
|
try_cache: false
|
||||||
|
});
|
||||||
|
|
||||||
expect(mockCreateNested).toHaveBeenCalled();
|
expect(mockCreateNested).toHaveBeenCalled();
|
||||||
expect(mockCreateNested).toHaveBeenCalledWith({
|
expect(mockCreateNested).toHaveBeenCalledWith({
|
||||||
@@ -51,9 +65,16 @@ describe('update_ae_obj__event_badge', () => {
|
|||||||
const fakeResult = { event_badge_id: 'eb999', full_name: 'Updated' };
|
const fakeResult = { event_badge_id: 'eb999', full_name: 'Updated' };
|
||||||
mockUpdate.mockResolvedValue(fakeResult);
|
mockUpdate.mockResolvedValue(fakeResult);
|
||||||
|
|
||||||
const { update_ae_obj__event_badge } = await import('./ae_events__event_badge');
|
const { update_ae_obj__event_badge } =
|
||||||
|
await import('./ae_events__event_badge');
|
||||||
const api_cfg = { base_url: 'http://localhost', headers: {} };
|
const api_cfg = { base_url: 'http://localhost', headers: {} };
|
||||||
const res = await update_ae_obj__event_badge({ api_cfg, event_id: 'evt1', event_badge_id: 'eb999', data_kv: { full_name_override: 'Updated' }, try_cache: false });
|
const res = await update_ae_obj__event_badge({
|
||||||
|
api_cfg,
|
||||||
|
event_id: 'evt1',
|
||||||
|
event_badge_id: 'eb999',
|
||||||
|
data_kv: { full_name_override: 'Updated' },
|
||||||
|
try_cache: false
|
||||||
|
});
|
||||||
|
|
||||||
expect(mockUpdate).toHaveBeenCalled();
|
expect(mockUpdate).toHaveBeenCalled();
|
||||||
expect(mockUpdate).toHaveBeenCalledWith({
|
expect(mockUpdate).toHaveBeenCalledWith({
|
||||||
@@ -79,10 +100,16 @@ describe('delete_ae_obj_id__event_badge', () => {
|
|||||||
const db = await import('$lib/ae_events/db_events');
|
const db = await import('$lib/ae_events/db_events');
|
||||||
const dbDelete = db.db_events.badge.delete as any;
|
const dbDelete = db.db_events.badge.delete as any;
|
||||||
|
|
||||||
const { delete_ae_obj_id__event_badge } = await import('./ae_events__event_badge');
|
const { delete_ae_obj_id__event_badge } =
|
||||||
|
await import('./ae_events__event_badge');
|
||||||
|
|
||||||
const api_cfg = { base_url: 'http://localhost', headers: {} };
|
const api_cfg = { base_url: 'http://localhost', headers: {} };
|
||||||
const res = await delete_ae_obj_id__event_badge({ api_cfg, event_id: 'evt1', event_badge_id: 'ebDel', try_cache: true });
|
const res = await delete_ae_obj_id__event_badge({
|
||||||
|
api_cfg,
|
||||||
|
event_id: 'evt1',
|
||||||
|
event_badge_id: 'ebDel',
|
||||||
|
try_cache: true
|
||||||
|
});
|
||||||
|
|
||||||
expect(mockDelete).toHaveBeenCalled();
|
expect(mockDelete).toHaveBeenCalled();
|
||||||
expect(dbDelete).toHaveBeenCalledWith('ebDel');
|
expect(dbDelete).toHaveBeenCalledWith('ebDel');
|
||||||
@@ -97,9 +124,15 @@ describe('search__event_badge', () => {
|
|||||||
const fakeList = [{ event_badge_id: 'eb1' }, { event_badge_id: 'eb2' }];
|
const fakeList = [{ event_badge_id: 'eb1' }, { event_badge_id: 'eb2' }];
|
||||||
mockSearch.mockResolvedValue({ data: fakeList });
|
mockSearch.mockResolvedValue({ data: fakeList });
|
||||||
|
|
||||||
const { search__event_badge } = await import('./ae_events__event_badge');
|
const { search__event_badge } =
|
||||||
|
await import('./ae_events__event_badge');
|
||||||
const api_cfg = { base_url: 'http://localhost', headers: {} };
|
const api_cfg = { base_url: 'http://localhost', headers: {} };
|
||||||
const res = await search__event_badge({ api_cfg, event_id: 'evt1', fulltext_search_qry_str: 'Test', try_cache: false });
|
const res = await search__event_badge({
|
||||||
|
api_cfg,
|
||||||
|
event_id: 'evt1',
|
||||||
|
fulltext_search_qry_str: 'Test',
|
||||||
|
try_cache: false
|
||||||
|
});
|
||||||
|
|
||||||
expect(mockSearch).toHaveBeenCalled();
|
expect(mockSearch).toHaveBeenCalled();
|
||||||
expect(Array.isArray(res)).toBe(true);
|
expect(Array.isArray(res)).toBe(true);
|
||||||
|
|||||||
@@ -35,29 +35,36 @@ export async function load_ae_obj_id__event_badge({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_EventBadge | null> {
|
}): Promise<ae_EventBadge | null> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** load_ae_obj_id__event_badge() *** event_badge_id=${event_badge_id}`);
|
console.log(
|
||||||
|
`*** load_ae_obj_id__event_badge() *** event_badge_id=${event_badge_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ae_promises.load__event_badge_obj = await api
|
ae_promises.load__event_badge_obj = await api.get_ae_obj({
|
||||||
.get_ae_obj({
|
api_cfg,
|
||||||
api_cfg,
|
obj_type: 'event_badge',
|
||||||
obj_type: 'event_badge',
|
obj_id: event_badge_id,
|
||||||
obj_id: event_badge_id,
|
view,
|
||||||
view,
|
log_lvl
|
||||||
log_lvl
|
});
|
||||||
});
|
|
||||||
|
|
||||||
if (ae_promises.load__event_badge_obj) {
|
if (ae_promises.load__event_badge_obj) {
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
// In theory we should be able to use the event_id found in the Badge load object. 2026-02-04
|
// In theory we should be able to use the event_id found in the Badge load object. 2026-02-04
|
||||||
// This keeps coming up as undefined: ae_promises.load__event_badge_obj.event_id
|
// This keeps coming up as undefined: ae_promises.load__event_badge_obj.event_id
|
||||||
if (log_lvl) console.log(`Saving to local cache... Event ID: ${event_id} or ${ae_promises.load__event_badge_obj.event_id}`);
|
if (log_lvl)
|
||||||
const processed_obj_li = await process_ae_obj__event_badge_props({
|
console.log(
|
||||||
obj_li: [ae_promises.load__event_badge_obj],
|
`Saving to local cache... Event ID: ${event_id} or ${ae_promises.load__event_badge_obj.event_id}`
|
||||||
event_id: event_id || ae_promises.load__event_badge_obj.event_id,
|
);
|
||||||
log_lvl
|
const processed_obj_li =
|
||||||
});
|
await process_ae_obj__event_badge_props({
|
||||||
|
obj_li: [ae_promises.load__event_badge_obj],
|
||||||
|
event_id:
|
||||||
|
event_id ||
|
||||||
|
ae_promises.load__event_badge_obj.event_id,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
db_instance: db_events,
|
db_instance: db_events,
|
||||||
table_name: 'badge',
|
table_name: 'badge',
|
||||||
@@ -71,15 +78,21 @@ export async function load_ae_obj_id__event_badge({
|
|||||||
} else {
|
} else {
|
||||||
console.log('No results returned from API.');
|
console.log('No results returned from API.');
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
if (log_lvl) console.log('Attempting to load from local cache...');
|
if (log_lvl)
|
||||||
ae_promises.load__event_badge_obj = await db_events.badge.get(event_badge_id);
|
console.log('Attempting to load from local cache...');
|
||||||
|
ae_promises.load__event_badge_obj =
|
||||||
|
await db_events.badge.get(event_badge_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log('API request failed.', error);
|
console.log('API request failed.', error);
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
if (log_lvl) console.log('Attempting to load from local cache after error...');
|
if (log_lvl)
|
||||||
ae_promises.load__event_badge_obj = await db_events.badge.get(event_badge_id);
|
console.log(
|
||||||
|
'Attempting to load from local cache after error...'
|
||||||
|
);
|
||||||
|
ae_promises.load__event_badge_obj =
|
||||||
|
await db_events.badge.get(event_badge_id);
|
||||||
} else {
|
} else {
|
||||||
ae_promises.load__event_badge_obj = null;
|
ae_promises.load__event_badge_obj = null;
|
||||||
}
|
}
|
||||||
@@ -87,14 +100,16 @@ export async function load_ae_obj_id__event_badge({
|
|||||||
|
|
||||||
if (inc_template && ae_promises.load__event_badge_obj) {
|
if (inc_template && ae_promises.load__event_badge_obj) {
|
||||||
// Load the templates for the event badge
|
// Load the templates for the event badge
|
||||||
const current_template_id = ae_promises.load__event_badge_obj.event_badge_template_id;
|
const current_template_id =
|
||||||
|
ae_promises.load__event_badge_obj.event_badge_template_id;
|
||||||
if (current_template_id) {
|
if (current_template_id) {
|
||||||
ae_promises.load__event_badge_obj.event_badge_template = await load_ae_obj_id__event_badge_template({
|
ae_promises.load__event_badge_obj.event_badge_template =
|
||||||
api_cfg: api_cfg,
|
await load_ae_obj_id__event_badge_template({
|
||||||
event_badge_template_id: current_template_id,
|
api_cfg: api_cfg,
|
||||||
try_cache: try_cache,
|
event_badge_template_id: current_template_id,
|
||||||
log_lvl: log_lvl
|
try_cache: try_cache,
|
||||||
});
|
log_lvl: log_lvl
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,7 +126,12 @@ export async function load_ae_obj_li__event_badge({
|
|||||||
view = 'default',
|
view = 'default',
|
||||||
limit = 99,
|
limit = 99,
|
||||||
offset = 0,
|
offset = 0,
|
||||||
order_by_li = { priority: 'DESC', sort: 'DESC', updated_on: 'DESC', created_on: 'DESC' },
|
order_by_li = {
|
||||||
|
priority: 'DESC',
|
||||||
|
sort: 'DESC',
|
||||||
|
updated_on: 'DESC',
|
||||||
|
created_on: 'DESC'
|
||||||
|
},
|
||||||
params = {},
|
params = {},
|
||||||
try_cache = true,
|
try_cache = true,
|
||||||
log_lvl = 0
|
log_lvl = 0
|
||||||
@@ -130,32 +150,34 @@ export async function load_ae_obj_li__event_badge({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_EventBadge[]> {
|
}): Promise<ae_EventBadge[]> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** load_ae_obj_li__event_badge() *** event_id=${event_id}`);
|
console.log(
|
||||||
|
`*** load_ae_obj_li__event_badge() *** event_id=${event_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ae_promises.load__event_badge_obj_li = await api
|
ae_promises.load__event_badge_obj_li = await api.get_ae_obj_li({
|
||||||
.get_ae_obj_li({
|
api_cfg,
|
||||||
api_cfg,
|
obj_type: 'event_badge',
|
||||||
obj_type: 'event_badge',
|
for_obj_type: 'event',
|
||||||
for_obj_type: 'event',
|
for_obj_id: event_id,
|
||||||
for_obj_id: event_id,
|
enabled: enabled,
|
||||||
enabled: enabled,
|
hidden: hidden,
|
||||||
hidden: hidden,
|
view: view,
|
||||||
view: view,
|
order_by_li: order_by_li,
|
||||||
order_by_li: order_by_li,
|
limit: limit,
|
||||||
limit: limit,
|
offset: offset,
|
||||||
offset: offset,
|
log_lvl: log_lvl
|
||||||
log_lvl: log_lvl
|
});
|
||||||
});
|
|
||||||
|
|
||||||
if (ae_promises.load__event_badge_obj_li) {
|
if (ae_promises.load__event_badge_obj_li) {
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
const processed_obj_li = await process_ae_obj__event_badge_props({
|
const processed_obj_li =
|
||||||
obj_li: ae_promises.load__event_badge_obj_li,
|
await process_ae_obj__event_badge_props({
|
||||||
event_id,
|
obj_li: ae_promises.load__event_badge_obj_li,
|
||||||
log_lvl
|
event_id,
|
||||||
});
|
log_lvl
|
||||||
|
});
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
db_instance: db_events,
|
db_instance: db_events,
|
||||||
table_name: 'badge',
|
table_name: 'badge',
|
||||||
@@ -169,9 +191,11 @@ export async function load_ae_obj_li__event_badge({
|
|||||||
} else {
|
} else {
|
||||||
console.log('No results returned from API.');
|
console.log('No results returned from API.');
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
if (log_lvl) console.log('Attempting to load from local cache...');
|
if (log_lvl)
|
||||||
|
console.log('Attempting to load from local cache...');
|
||||||
ae_promises.load__event_badge_obj_li = await db_events.badge
|
ae_promises.load__event_badge_obj_li = await db_events.badge
|
||||||
.where('event_id').equals(event_id)
|
.where('event_id')
|
||||||
|
.equals(event_id)
|
||||||
.toArray();
|
.toArray();
|
||||||
} else {
|
} else {
|
||||||
ae_promises.load__event_badge_obj_li = [];
|
ae_promises.load__event_badge_obj_li = [];
|
||||||
@@ -180,9 +204,13 @@ export async function load_ae_obj_li__event_badge({
|
|||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log('API request failed.', error);
|
console.log('API request failed.', error);
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
if (log_lvl) console.log('Attempting to load from local cache after error...');
|
if (log_lvl)
|
||||||
|
console.log(
|
||||||
|
'Attempting to load from local cache after error...'
|
||||||
|
);
|
||||||
ae_promises.load__event_badge_obj_li = await db_events.badge
|
ae_promises.load__event_badge_obj_li = await db_events.badge
|
||||||
.where('event_id').equals(event_id)
|
.where('event_id')
|
||||||
|
.equals(event_id)
|
||||||
.toArray();
|
.toArray();
|
||||||
} else {
|
} else {
|
||||||
ae_promises.load__event_badge_obj_li = [];
|
ae_promises.load__event_badge_obj_li = [];
|
||||||
@@ -193,12 +221,13 @@ export async function load_ae_obj_li__event_badge({
|
|||||||
for (const badge_obj of ae_promises.load__event_badge_obj_li) {
|
for (const badge_obj of ae_promises.load__event_badge_obj_li) {
|
||||||
const current_template_id = badge_obj.event_badge_template_id;
|
const current_template_id = badge_obj.event_badge_template_id;
|
||||||
if (current_template_id) {
|
if (current_template_id) {
|
||||||
badge_obj.event_badge_template = await load_ae_obj_id__event_badge_template({
|
badge_obj.event_badge_template =
|
||||||
api_cfg: api_cfg,
|
await load_ae_obj_id__event_badge_template({
|
||||||
event_badge_template_id: current_template_id,
|
api_cfg: api_cfg,
|
||||||
try_cache: try_cache,
|
event_badge_template_id: current_template_id,
|
||||||
log_lvl: log_lvl
|
try_cache: try_cache,
|
||||||
});
|
log_lvl: log_lvl
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -223,7 +252,9 @@ export async function create_ae_obj__event_badge({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_EventBadge | null> {
|
}): Promise<ae_EventBadge | null> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** create_ae_obj__event_badge() *** event_id=${event_id}`);
|
console.log(
|
||||||
|
`*** create_ae_obj__event_badge() *** event_id=${event_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await api.create_nested_obj({
|
const result = await api.create_nested_obj({
|
||||||
@@ -275,7 +306,9 @@ export async function delete_ae_obj_id__event_badge({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}) {
|
}) {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** delete_ae_obj_id__event_badge() *** event_badge_id=${event_badge_id}`);
|
console.log(
|
||||||
|
`*** delete_ae_obj_id__event_badge() *** event_badge_id=${event_badge_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await api.delete_nested_ae_obj({
|
const result = await api.delete_nested_ae_obj({
|
||||||
@@ -315,7 +348,9 @@ export async function update_ae_obj__event_badge({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_EventBadge | null> {
|
}): Promise<ae_EventBadge | null> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** update_ae_obj__event_badge() *** event_badge_id=${event_badge_id}`);
|
console.log(
|
||||||
|
`*** update_ae_obj__event_badge() *** event_badge_id=${event_badge_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await api.update_nested_obj({
|
const result = await api.update_nested_obj({
|
||||||
@@ -391,7 +426,9 @@ export async function search__event_badge({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_EventBadge[] | false> {
|
}): Promise<ae_EventBadge[] | false> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** search__event_badge() *** event_id=${event_id} ft=${fulltext_search_qry_str}`);
|
console.log(
|
||||||
|
`*** search__event_badge() *** event_id=${event_id} ft=${fulltext_search_qry_str}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const search_query: any = {
|
const search_query: any = {
|
||||||
@@ -406,15 +443,23 @@ export async function search__event_badge({
|
|||||||
// Multi-word support: Split query by spaces and search for all words (AND logic)
|
// Multi-word support: Split query by spaces and search for all words (AND logic)
|
||||||
if (fulltext_search_qry_str && fulltext_search_qry_str.trim().length > 0) {
|
if (fulltext_search_qry_str && fulltext_search_qry_str.trim().length > 0) {
|
||||||
const qry = fulltext_search_qry_str.trim();
|
const qry = fulltext_search_qry_str.trim();
|
||||||
const words = qry.split(/\s+/).filter(w => w.length > 0);
|
const words = qry.split(/\s+/).filter((w) => w.length > 0);
|
||||||
|
|
||||||
if (words.length === 1) {
|
if (words.length === 1) {
|
||||||
// Single word: use simple LIKE
|
// Single word: use simple LIKE
|
||||||
search_query.and.push({ field: 'default_qry_str', op: 'like', value: `%${words[0]}%` });
|
search_query.and.push({
|
||||||
|
field: 'default_qry_str',
|
||||||
|
op: 'like',
|
||||||
|
value: `%${words[0]}%`
|
||||||
|
});
|
||||||
} else if (words.length > 1) {
|
} else if (words.length > 1) {
|
||||||
// Multiple words: each word must match (AND logic)
|
// Multiple words: each word must match (AND logic)
|
||||||
for (const word of words) {
|
for (const word of words) {
|
||||||
search_query.and.push({ field: 'default_qry_str', op: 'like', value: `%${word}%` });
|
search_query.and.push({
|
||||||
|
field: 'default_qry_str',
|
||||||
|
op: 'like',
|
||||||
|
value: `%${word}%`
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -424,7 +469,11 @@ export async function search__event_badge({
|
|||||||
|
|
||||||
if (affiliations_qry_str && affiliations_qry_str.trim().length > 0) {
|
if (affiliations_qry_str && affiliations_qry_str.trim().length > 0) {
|
||||||
const qry = affiliations_qry_str.trim();
|
const qry = affiliations_qry_str.trim();
|
||||||
search_query.and.push({ field: 'affiliations', op: 'like', value: `%${qry}%` });
|
search_query.and.push({
|
||||||
|
field: 'affiliations',
|
||||||
|
op: 'like',
|
||||||
|
value: `%${qry}%`
|
||||||
|
});
|
||||||
params['lk_qry'] = params['lk_qry'] || {};
|
params['lk_qry'] = params['lk_qry'] || {};
|
||||||
params['lk_qry']['affiliations'] = qry;
|
params['lk_qry']['affiliations'] = qry;
|
||||||
}
|
}
|
||||||
@@ -435,11 +484,19 @@ export async function search__event_badge({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (external_event_id) {
|
if (external_event_id) {
|
||||||
search_query.and.push({ field: 'external_event_id', op: 'eq', value: external_event_id });
|
search_query.and.push({
|
||||||
|
field: 'external_event_id',
|
||||||
|
op: 'eq',
|
||||||
|
value: external_event_id
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type_code) {
|
if (type_code) {
|
||||||
search_query.and.push({ field: 'badge_type_code', op: 'eq', value: type_code });
|
search_query.and.push({
|
||||||
|
field: 'badge_type_code',
|
||||||
|
op: 'eq',
|
||||||
|
value: type_code
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (printed_status === 'printed') {
|
if (printed_status === 'printed') {
|
||||||
@@ -448,11 +505,15 @@ export async function search__event_badge({
|
|||||||
search_query.and.push({ field: 'print_count', op: 'eq', value: 0 });
|
search_query.and.push({ field: 'print_count', op: 'eq', value: 0 });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enabled === 'enabled') search_query.and.push({ field: 'enable', op: 'eq', value: true });
|
if (enabled === 'enabled')
|
||||||
else if (enabled === 'not_enabled') search_query.and.push({ field: 'enable', op: 'eq', value: false });
|
search_query.and.push({ field: 'enable', op: 'eq', value: true });
|
||||||
|
else if (enabled === 'not_enabled')
|
||||||
|
search_query.and.push({ field: 'enable', op: 'eq', value: false });
|
||||||
|
|
||||||
if (hidden === 'hidden') search_query.and.push({ field: 'hide', op: 'eq', value: true });
|
if (hidden === 'hidden')
|
||||||
else if (hidden === 'not_hidden') search_query.and.push({ field: 'hide', op: 'eq', value: false });
|
search_query.and.push({ field: 'hide', op: 'eq', value: true });
|
||||||
|
else if (hidden === 'not_hidden')
|
||||||
|
search_query.and.push({ field: 'hide', op: 'eq', value: false });
|
||||||
|
|
||||||
ae_promises.search__event_badge_obj_li = await api
|
ae_promises.search__event_badge_obj_li = await api
|
||||||
.search_ae_obj({
|
.search_ae_obj({
|
||||||
@@ -473,17 +534,21 @@ export async function search__event_badge({
|
|||||||
let result_li: ae_EventBadge[] = [];
|
let result_li: ae_EventBadge[] = [];
|
||||||
if (Array.isArray(badge_obj_li_get_result)) {
|
if (Array.isArray(badge_obj_li_get_result)) {
|
||||||
result_li = badge_obj_li_get_result;
|
result_li = badge_obj_li_get_result;
|
||||||
} else if (badge_obj_li_get_result?.data && Array.isArray(badge_obj_li_get_result.data)) {
|
} else if (
|
||||||
|
badge_obj_li_get_result?.data &&
|
||||||
|
Array.isArray(badge_obj_li_get_result.data)
|
||||||
|
) {
|
||||||
result_li = badge_obj_li_get_result.data;
|
result_li = badge_obj_li_get_result.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result_li.length > 0) {
|
if (result_li.length > 0) {
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
const processed_obj_li = await process_ae_obj__event_badge_props({
|
const processed_obj_li =
|
||||||
obj_li: result_li,
|
await process_ae_obj__event_badge_props({
|
||||||
event_id,
|
obj_li: result_li,
|
||||||
log_lvl
|
event_id,
|
||||||
});
|
log_lvl
|
||||||
|
});
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
db_instance: db_events,
|
db_instance: db_events,
|
||||||
table_name: 'badge',
|
table_name: 'badge',
|
||||||
@@ -631,14 +696,21 @@ async function _process_generic_props<T extends Record<string, any>>({
|
|||||||
const group = processed_obj.group ?? '0';
|
const group = processed_obj.group ?? '0';
|
||||||
const priority = processed_obj.priority ? 1 : 0;
|
const priority = processed_obj.priority ? 1 : 0;
|
||||||
const sort = processed_obj.sort ?? '0';
|
const sort = processed_obj.sort ?? '0';
|
||||||
const updated = processed_obj.updated_on ?? processed_obj.created_on ?? new Date(0).toISOString();
|
const updated =
|
||||||
|
processed_obj.updated_on ??
|
||||||
|
processed_obj.created_on ??
|
||||||
|
new Date(0).toISOString();
|
||||||
const name = processed_obj.name ?? '';
|
const name = processed_obj.name ?? '';
|
||||||
|
|
||||||
(processed_obj as any).tmp_sort_1 = `${group}_${priority}_${sort}_${updated}`;
|
(processed_obj as any).tmp_sort_1 =
|
||||||
(processed_obj as any).tmp_sort_2 = `${group}_${priority}_${sort}_${name}_${updated}`;
|
`${group}_${priority}_${sort}_${updated}`;
|
||||||
|
(processed_obj as any).tmp_sort_2 =
|
||||||
|
`${group}_${priority}_${sort}_${name}_${updated}`;
|
||||||
|
|
||||||
if (specific_processor) {
|
if (specific_processor) {
|
||||||
processed_obj = await Promise.resolve(specific_processor(processed_obj));
|
processed_obj = await Promise.resolve(
|
||||||
|
specific_processor(processed_obj)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
processed_obj_li.push(processed_obj as T);
|
processed_obj_li.push(processed_obj as T);
|
||||||
@@ -663,7 +735,9 @@ export async function process_ae_obj__event_badge_props({
|
|||||||
log_lvl,
|
log_lvl,
|
||||||
specific_processor: (obj) => {
|
specific_processor: (obj) => {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** process_ae_obj__event_badge_props() *** event_id=${event_id}`);
|
console.log(
|
||||||
|
`*** process_ae_obj__event_badge_props() *** event_id=${event_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (event_id) {
|
if (event_id) {
|
||||||
if (!obj.event_id) obj.event_id = event_id;
|
if (!obj.event_id) obj.event_id = event_id;
|
||||||
|
|||||||
@@ -87,11 +87,15 @@ async function _process_generic_props<T extends Record<string, any>>({
|
|||||||
const updated = processed_obj.updated_on ?? processed_obj.created_on;
|
const updated = processed_obj.updated_on ?? processed_obj.created_on;
|
||||||
const name = processed_obj.name ?? '';
|
const name = processed_obj.name ?? '';
|
||||||
|
|
||||||
(processed_obj as any).tmp_sort_1 = `${group}_${priority}_${sort}_${updated}`;
|
(processed_obj as any).tmp_sort_1 =
|
||||||
(processed_obj as any).tmp_sort_2 = `${group}_${priority}_${sort}_${name}_${updated}`;
|
`${group}_${priority}_${sort}_${updated}`;
|
||||||
|
(processed_obj as any).tmp_sort_2 =
|
||||||
|
`${group}_${priority}_${sort}_${name}_${updated}`;
|
||||||
|
|
||||||
if (specific_processor) {
|
if (specific_processor) {
|
||||||
processed_obj = await Promise.resolve(specific_processor(processed_obj));
|
processed_obj = await Promise.resolve(
|
||||||
|
specific_processor(processed_obj)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
processed_obj_li.push(processed_obj as T);
|
processed_obj_li.push(processed_obj as T);
|
||||||
@@ -129,7 +133,9 @@ export async function load_ae_obj_id__event_badge_template({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}) {
|
}) {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** load_ae_obj_id__event_badge_template() *** [V3] id=${event_badge_template_id}`);
|
console.log(
|
||||||
|
`*** load_ae_obj_id__event_badge_template() *** [V3] id=${event_badge_template_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -156,11 +162,13 @@ export async function load_ae_obj_id__event_badge_template({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (try_cache) {
|
} else if (try_cache) {
|
||||||
ae_promises.load__event_badge_template_obj = await db_events.badge_template.get(event_badge_template_id);
|
ae_promises.load__event_badge_template_obj =
|
||||||
|
await db_events.badge_template.get(event_badge_template_id);
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
ae_promises.load__event_badge_template_obj = await db_events.badge_template.get(event_badge_template_id);
|
ae_promises.load__event_badge_template_obj =
|
||||||
|
await db_events.badge_template.get(event_badge_template_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,19 +205,21 @@ export async function load_ae_obj_li__event_badge_template({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}) {
|
}) {
|
||||||
try {
|
try {
|
||||||
ae_promises.load__event_badge_template_obj_li = await api.get_ae_obj_li({
|
ae_promises.load__event_badge_template_obj_li = await api.get_ae_obj_li(
|
||||||
api_cfg,
|
{
|
||||||
obj_type: 'event_badge_template',
|
api_cfg,
|
||||||
for_obj_type: 'event',
|
obj_type: 'event_badge_template',
|
||||||
for_obj_id: event_id,
|
for_obj_type: 'event',
|
||||||
enabled,
|
for_obj_id: event_id,
|
||||||
hidden,
|
enabled,
|
||||||
view,
|
hidden,
|
||||||
limit,
|
view,
|
||||||
offset,
|
limit,
|
||||||
order_by_li,
|
offset,
|
||||||
log_lvl
|
order_by_li,
|
||||||
});
|
log_lvl
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
if (ae_promises.load__event_badge_template_obj_li) {
|
if (ae_promises.load__event_badge_template_obj_li) {
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
@@ -226,15 +236,19 @@ export async function load_ae_obj_li__event_badge_template({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (try_cache) {
|
} else if (try_cache) {
|
||||||
ae_promises.load__event_badge_template_obj_li = await db_events.badge_template
|
ae_promises.load__event_badge_template_obj_li =
|
||||||
.where('event_id').equals(event_id)
|
await db_events.badge_template
|
||||||
.toArray();
|
.where('event_id')
|
||||||
|
.equals(event_id)
|
||||||
|
.toArray();
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
ae_promises.load__event_badge_template_obj_li = await db_events.badge_template
|
ae_promises.load__event_badge_template_obj_li =
|
||||||
.where('event_id').equals(event_id)
|
await db_events.badge_template
|
||||||
.toArray();
|
.where('event_id')
|
||||||
|
.equals(event_id)
|
||||||
|
.toArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,115 +257,115 @@ export async function load_ae_obj_li__event_badge_template({
|
|||||||
|
|
||||||
// Updated 2026-01-20 to V3
|
// Updated 2026-01-20 to V3
|
||||||
export async function create_ae_obj__event_badge_template({
|
export async function create_ae_obj__event_badge_template({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
event_id,
|
event_id,
|
||||||
data_kv,
|
data_kv,
|
||||||
try_cache = true,
|
try_cache = true,
|
||||||
log_lvl = 0
|
log_lvl = 0
|
||||||
}: {
|
}: {
|
||||||
api_cfg: any;
|
api_cfg: any;
|
||||||
event_id: string;
|
event_id: string;
|
||||||
data_kv: key_val;
|
data_kv: key_val;
|
||||||
try_cache?: boolean;
|
try_cache?: boolean;
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}) {
|
}) {
|
||||||
const result = await api.create_nested_obj({
|
const result = await api.create_nested_obj({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
for_obj_type: 'event',
|
for_obj_type: 'event',
|
||||||
for_obj_id: event_id,
|
for_obj_id: event_id,
|
||||||
obj_type: 'event_badge_template',
|
obj_type: 'event_badge_template',
|
||||||
fields: { ...data_kv },
|
fields: { ...data_kv },
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
|
|
||||||
if (result && try_cache) {
|
if (result && try_cache) {
|
||||||
const processed_obj_li = await process_ae_badge_template_props({
|
const processed_obj_li = await process_ae_badge_template_props({
|
||||||
obj_li: [result],
|
obj_li: [result],
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
db_instance: db_events,
|
db_instance: db_events,
|
||||||
table_name: 'badge_template',
|
table_name: 'badge_template',
|
||||||
obj_li: processed_obj_li,
|
obj_li: processed_obj_li,
|
||||||
properties_to_save,
|
properties_to_save,
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updated 2026-01-20 to V3
|
// Updated 2026-01-20 to V3
|
||||||
export async function delete_ae_obj_id__event_badge_template({
|
export async function delete_ae_obj_id__event_badge_template({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
event_id,
|
event_id,
|
||||||
event_badge_template_id,
|
event_badge_template_id,
|
||||||
method = 'delete',
|
method = 'delete',
|
||||||
try_cache = true,
|
try_cache = true,
|
||||||
log_lvl = 0
|
log_lvl = 0
|
||||||
}: {
|
}: {
|
||||||
api_cfg: any;
|
api_cfg: any;
|
||||||
event_id: string;
|
event_id: string;
|
||||||
event_badge_template_id: string;
|
event_badge_template_id: string;
|
||||||
method?: 'delete' | 'soft_delete' | 'disable' | 'hide';
|
method?: 'delete' | 'soft_delete' | 'disable' | 'hide';
|
||||||
try_cache?: boolean;
|
try_cache?: boolean;
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}) {
|
}) {
|
||||||
const result = await api.delete_nested_ae_obj({
|
const result = await api.delete_nested_ae_obj({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
for_obj_type: 'event',
|
for_obj_type: 'event',
|
||||||
for_obj_id: event_id,
|
for_obj_id: event_id,
|
||||||
obj_type: 'event_badge_template',
|
obj_type: 'event_badge_template',
|
||||||
obj_id: event_badge_template_id,
|
obj_id: event_badge_template_id,
|
||||||
method,
|
method,
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
|
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
await db_events.badge_template.delete(event_badge_template_id);
|
await db_events.badge_template.delete(event_badge_template_id);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updated 2026-01-20 to V3
|
// Updated 2026-01-20 to V3
|
||||||
export async function update_ae_obj__event_badge_template({
|
export async function update_ae_obj__event_badge_template({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
event_id,
|
event_id,
|
||||||
event_badge_template_id,
|
event_badge_template_id,
|
||||||
data_kv,
|
data_kv,
|
||||||
try_cache = true,
|
try_cache = true,
|
||||||
log_lvl = 0
|
log_lvl = 0
|
||||||
}: {
|
}: {
|
||||||
api_cfg: any;
|
api_cfg: any;
|
||||||
event_id: string;
|
event_id: string;
|
||||||
event_badge_template_id: string;
|
event_badge_template_id: string;
|
||||||
data_kv: key_val;
|
data_kv: key_val;
|
||||||
try_cache?: boolean;
|
try_cache?: boolean;
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}) {
|
}) {
|
||||||
const result = await api.update_nested_obj({
|
const result = await api.update_nested_obj({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
for_obj_type: 'event',
|
for_obj_type: 'event',
|
||||||
for_obj_id: event_id,
|
for_obj_id: event_id,
|
||||||
obj_type: 'event_badge_template',
|
obj_type: 'event_badge_template',
|
||||||
obj_id: event_badge_template_id,
|
obj_id: event_badge_template_id,
|
||||||
fields: data_kv,
|
fields: data_kv,
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
|
|
||||||
if (result && try_cache) {
|
if (result && try_cache) {
|
||||||
const processed_obj_li = await process_ae_badge_template_props({
|
const processed_obj_li = await process_ae_badge_template_props({
|
||||||
obj_li: [result],
|
obj_li: [result],
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
db_instance: db_events,
|
db_instance: db_events,
|
||||||
table_name: 'badge_template',
|
table_name: 'badge_template',
|
||||||
obj_li: processed_obj_li,
|
obj_li: processed_obj_li,
|
||||||
properties_to_save,
|
properties_to_save,
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updated 2026-01-20 to V3
|
// Updated 2026-01-20 to V3
|
||||||
@@ -388,11 +402,15 @@ export async function search__event_badge_template({
|
|||||||
and: [{ field: 'event_id', op: 'eq', value: event_id }]
|
and: [{ field: 'event_id', op: 'eq', value: event_id }]
|
||||||
};
|
};
|
||||||
|
|
||||||
if (enabled === 'enabled') search_query.and.push({ field: 'enable', op: 'eq', value: true });
|
if (enabled === 'enabled')
|
||||||
else if (enabled === 'not_enabled') search_query.and.push({ field: 'enable', op: 'eq', value: false });
|
search_query.and.push({ field: 'enable', op: 'eq', value: true });
|
||||||
|
else if (enabled === 'not_enabled')
|
||||||
|
search_query.and.push({ field: 'enable', op: 'eq', value: false });
|
||||||
|
|
||||||
if (hidden === 'hidden') search_query.and.push({ field: 'hide', op: 'eq', value: true });
|
if (hidden === 'hidden')
|
||||||
else if (hidden === 'not_hidden') search_query.and.push({ field: 'hide', op: 'eq', value: false });
|
search_query.and.push({ field: 'hide', op: 'eq', value: true });
|
||||||
|
else if (hidden === 'not_hidden')
|
||||||
|
search_query.and.push({ field: 'hide', op: 'eq', value: false });
|
||||||
|
|
||||||
const result_li = await api.search_ae_obj({
|
const result_li = await api.search_ae_obj({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
|
|||||||
@@ -28,7 +28,9 @@ export async function load_ae_obj_id__event_device({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_EventDevice | null> {
|
}): Promise<ae_EventDevice | null> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** load_ae_obj_id__event_device() *** [V3] id=${event_device_id}`);
|
console.log(
|
||||||
|
`*** load_ae_obj_id__event_device() *** [V3] id=${event_device_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -57,26 +59,30 @@ export async function load_ae_obj_id__event_device({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (try_cache) {
|
} else if (try_cache) {
|
||||||
ae_promises.load__event_device_obj = await db_events.device.get(event_device_id);
|
ae_promises.load__event_device_obj =
|
||||||
|
await db_events.device.get(event_device_id);
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log('V3 Request failed.', error);
|
console.log('V3 Request failed.', error);
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
ae_promises.load__event_device_obj = await db_events.device.get(event_device_id);
|
ae_promises.load__event_device_obj =
|
||||||
|
await db_events.device.get(event_device_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ae_promises.load__event_device_obj) return null;
|
if (!ae_promises.load__event_device_obj) return null;
|
||||||
|
|
||||||
if (inc_location_id) {
|
if (inc_location_id) {
|
||||||
const current_location_id = ae_promises.load__event_device_obj.event_location_id;
|
const current_location_id =
|
||||||
|
ae_promises.load__event_device_obj.event_location_id;
|
||||||
if (current_location_id) {
|
if (current_location_id) {
|
||||||
ae_promises.load__event_device_obj.event_location_obj = await load_ae_obj_id__event_location({
|
ae_promises.load__event_device_obj.event_location_obj =
|
||||||
api_cfg,
|
await load_ae_obj_id__event_location({
|
||||||
event_location_id: current_location_id,
|
api_cfg,
|
||||||
try_cache,
|
event_location_id: current_location_id,
|
||||||
log_lvl
|
try_cache,
|
||||||
});
|
log_lvl
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,7 +121,9 @@ export async function load_ae_obj_li__event_device({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_EventDevice[]> {
|
}): Promise<ae_EventDevice[]> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** load_ae_obj_li__event_device() *** [V3] for=${for_obj_type}:${for_obj_id}`);
|
console.log(
|
||||||
|
`*** load_ae_obj_li__event_device() *** [V3] for=${for_obj_type}:${for_obj_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -150,14 +158,16 @@ export async function load_ae_obj_li__event_device({
|
|||||||
}
|
}
|
||||||
} else if (try_cache) {
|
} else if (try_cache) {
|
||||||
ae_promises.load__event_device_obj_li = await db_events.device
|
ae_promises.load__event_device_obj_li = await db_events.device
|
||||||
.where('event_id').equals(for_obj_id)
|
.where('event_id')
|
||||||
|
.equals(for_obj_id)
|
||||||
.toArray();
|
.toArray();
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log('V3 List Request failed.', error);
|
console.log('V3 List Request failed.', error);
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
ae_promises.load__event_device_obj_li = await db_events.device
|
ae_promises.load__event_device_obj_li = await db_events.device
|
||||||
.where('event_id').equals(for_obj_id)
|
.where('event_id')
|
||||||
|
.equals(for_obj_id)
|
||||||
.toArray();
|
.toArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -165,12 +175,13 @@ export async function load_ae_obj_li__event_device({
|
|||||||
if (inc_location_id && ae_promises.load__event_device_obj_li) {
|
if (inc_location_id && ae_promises.load__event_device_obj_li) {
|
||||||
for (const device of ae_promises.load__event_device_obj_li) {
|
for (const device of ae_promises.load__event_device_obj_li) {
|
||||||
if (device.event_location_id) {
|
if (device.event_location_id) {
|
||||||
device.event_location_obj = await load_ae_obj_id__event_location({
|
device.event_location_obj =
|
||||||
api_cfg,
|
await load_ae_obj_id__event_location({
|
||||||
event_location_id: device.event_location_id,
|
api_cfg,
|
||||||
try_cache,
|
event_location_id: device.event_location_id,
|
||||||
log_lvl
|
try_cache,
|
||||||
});
|
log_lvl
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -180,155 +191,161 @@ export async function load_ae_obj_li__event_device({
|
|||||||
|
|
||||||
// Updated 2026-01-20 to V3
|
// Updated 2026-01-20 to V3
|
||||||
export async function create_ae_obj__event_device({
|
export async function create_ae_obj__event_device({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
event_id,
|
event_id,
|
||||||
data_kv,
|
data_kv,
|
||||||
try_cache = true,
|
try_cache = true,
|
||||||
log_lvl = 0
|
log_lvl = 0
|
||||||
}: {
|
}: {
|
||||||
api_cfg: any;
|
api_cfg: any;
|
||||||
event_id?: string;
|
event_id?: string;
|
||||||
data_kv: key_val;
|
data_kv: key_val;
|
||||||
try_cache?: boolean;
|
try_cache?: boolean;
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_EventDevice | null> {
|
}): Promise<ae_EventDevice | null> {
|
||||||
if (!event_id) event_id = get(slct).event_id;
|
if (!event_id) event_id = get(slct).event_id;
|
||||||
if (!event_id) {
|
if (!event_id) {
|
||||||
console.error('create_ae_obj__event_device: event_id is required');
|
console.error('create_ae_obj__event_device: event_id is required');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** create_ae_obj__event_device() *** [V3] event_id=${event_id}`);
|
console.log(
|
||||||
}
|
`*** create_ae_obj__event_device() *** [V3] event_id=${event_id}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const result = await api.create_nested_obj({
|
const result = await api.create_nested_obj({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
for_obj_type: 'event',
|
for_obj_type: 'event',
|
||||||
for_obj_id: event_id,
|
for_obj_id: event_id,
|
||||||
obj_type: 'event_device',
|
obj_type: 'event_device',
|
||||||
fields: { ...data_kv },
|
fields: { ...data_kv },
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
const processed = await process_ae_obj__event_device_props({
|
const processed = await process_ae_obj__event_device_props({
|
||||||
obj_li: [result],
|
obj_li: [result],
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
const processed_obj = processed[0];
|
const processed_obj = processed[0];
|
||||||
|
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
db_instance: db_events,
|
db_instance: db_events,
|
||||||
table_name: 'device',
|
table_name: 'device',
|
||||||
obj_li: [processed_obj],
|
obj_li: [processed_obj],
|
||||||
properties_to_save,
|
properties_to_save,
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return processed_obj;
|
return processed_obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updated 2026-01-20 to V3
|
// Updated 2026-01-20 to V3
|
||||||
export async function delete_ae_obj_id__event_device({
|
export async function delete_ae_obj_id__event_device({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
event_id,
|
event_id,
|
||||||
event_device_id,
|
event_device_id,
|
||||||
method = 'delete',
|
method = 'delete',
|
||||||
try_cache = true,
|
try_cache = true,
|
||||||
log_lvl = 0
|
log_lvl = 0
|
||||||
}: {
|
}: {
|
||||||
api_cfg: any;
|
api_cfg: any;
|
||||||
event_id?: string;
|
event_id?: string;
|
||||||
event_device_id: string;
|
event_device_id: string;
|
||||||
method?: 'delete' | 'soft_delete' | 'disable' | 'hide';
|
method?: 'delete' | 'soft_delete' | 'disable' | 'hide';
|
||||||
try_cache?: boolean;
|
try_cache?: boolean;
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}) {
|
}) {
|
||||||
if (!event_id) event_id = get(slct).event_id;
|
if (!event_id) event_id = get(slct).event_id;
|
||||||
if (!event_id) {
|
if (!event_id) {
|
||||||
console.error('delete_ae_obj_id__event_device: event_id is required');
|
console.error('delete_ae_obj_id__event_device: event_id is required');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** delete_ae_obj_id__event_device() *** [V3] id=${event_device_id}`);
|
console.log(
|
||||||
}
|
`*** delete_ae_obj_id__event_device() *** [V3] id=${event_device_id}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const result = await api.delete_nested_ae_obj({
|
const result = await api.delete_nested_ae_obj({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
for_obj_type: 'event',
|
for_obj_type: 'event',
|
||||||
for_obj_id: event_id,
|
for_obj_id: event_id,
|
||||||
obj_type: 'event_device',
|
obj_type: 'event_device',
|
||||||
obj_id: event_device_id,
|
obj_id: event_device_id,
|
||||||
method,
|
method,
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
|
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
await db_events.device.delete(event_device_id);
|
await db_events.device.delete(event_device_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updated 2026-01-20 to V3
|
// Updated 2026-01-20 to V3
|
||||||
export async function update_ae_obj__event_device({
|
export async function update_ae_obj__event_device({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
event_id,
|
event_id,
|
||||||
event_device_id,
|
event_device_id,
|
||||||
data_kv,
|
data_kv,
|
||||||
try_cache = true,
|
try_cache = true,
|
||||||
log_lvl = 0
|
log_lvl = 0
|
||||||
}: {
|
}: {
|
||||||
api_cfg: any;
|
api_cfg: any;
|
||||||
event_id?: string;
|
event_id?: string;
|
||||||
event_device_id: string;
|
event_device_id: string;
|
||||||
data_kv: key_val;
|
data_kv: key_val;
|
||||||
try_cache?: boolean;
|
try_cache?: boolean;
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_EventDevice | null> {
|
}): Promise<ae_EventDevice | null> {
|
||||||
if (!event_id) event_id = get(slct).event_id;
|
if (!event_id) event_id = get(slct).event_id;
|
||||||
if (!event_id) {
|
if (!event_id) {
|
||||||
console.error('update_ae_obj__event_device: event_id is required');
|
console.error('update_ae_obj__event_device: event_id is required');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** update_ae_obj__event_device() *** [V3] id=${event_device_id}`);
|
console.log(
|
||||||
}
|
`*** update_ae_obj__event_device() *** [V3] id=${event_device_id}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const result = await api.update_nested_obj({
|
const result = await api.update_nested_obj({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
for_obj_type: 'event',
|
for_obj_type: 'event',
|
||||||
for_obj_id: event_id,
|
for_obj_id: event_id,
|
||||||
obj_type: 'event_device',
|
obj_type: 'event_device',
|
||||||
obj_id: event_device_id,
|
obj_id: event_device_id,
|
||||||
fields: data_kv,
|
fields: data_kv,
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
const processed = await process_ae_obj__event_device_props({
|
const processed = await process_ae_obj__event_device_props({
|
||||||
obj_li: [result],
|
obj_li: [result],
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
const processed_obj = processed[0];
|
const processed_obj = processed[0];
|
||||||
|
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
db_instance: db_events,
|
db_instance: db_events,
|
||||||
table_name: 'device',
|
table_name: 'device',
|
||||||
obj_li: [processed_obj],
|
obj_li: [processed_obj],
|
||||||
properties_to_save,
|
properties_to_save,
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return processed_obj;
|
return processed_obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updated 2026-01-20 to V3
|
// Updated 2026-01-20 to V3
|
||||||
@@ -361,7 +378,9 @@ export async function search__event_device({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_EventDevice[]> {
|
}): Promise<ae_EventDevice[]> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** search__event_device() *** [V3] event_id=${event_id} qry=${qry_str}`);
|
console.log(
|
||||||
|
`*** search__event_device() *** [V3] event_id=${event_id} qry=${qry_str}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const search_query: any = {
|
const search_query: any = {
|
||||||
@@ -370,11 +389,15 @@ export async function search__event_device({
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Logical filters
|
// Logical filters
|
||||||
if (enabled === 'enabled') search_query.and.push({ field: 'enable', op: 'eq', value: true });
|
if (enabled === 'enabled')
|
||||||
else if (enabled === 'not_enabled') search_query.and.push({ field: 'enable', op: 'eq', value: false });
|
search_query.and.push({ field: 'enable', op: 'eq', value: true });
|
||||||
|
else if (enabled === 'not_enabled')
|
||||||
|
search_query.and.push({ field: 'enable', op: 'eq', value: false });
|
||||||
|
|
||||||
if (hidden === 'hidden') search_query.and.push({ field: 'hide', op: 'eq', value: true });
|
if (hidden === 'hidden')
|
||||||
else if (hidden === 'not_hidden') search_query.and.push({ field: 'hide', op: 'eq', value: false });
|
search_query.and.push({ field: 'hide', op: 'eq', value: true });
|
||||||
|
else if (hidden === 'not_hidden')
|
||||||
|
search_query.and.push({ field: 'hide', op: 'eq', value: false });
|
||||||
|
|
||||||
const result_li = await api.search_ae_obj({
|
const result_li = await api.search_ae_obj({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
@@ -499,11 +522,15 @@ async function _process_generic_props<T extends Record<string, any>>({
|
|||||||
const updated = processed_obj.updated_on ?? processed_obj.created_on;
|
const updated = processed_obj.updated_on ?? processed_obj.created_on;
|
||||||
const name = processed_obj.name ?? '';
|
const name = processed_obj.name ?? '';
|
||||||
|
|
||||||
(processed_obj as any).tmp_sort_1 = `${group}_${priority}_${sort}_${updated}`;
|
(processed_obj as any).tmp_sort_1 =
|
||||||
(processed_obj as any).tmp_sort_2 = `${group}_${priority}_${sort}_${name}_${updated}`;
|
`${group}_${priority}_${sort}_${updated}`;
|
||||||
|
(processed_obj as any).tmp_sort_2 =
|
||||||
|
`${group}_${priority}_${sort}_${name}_${updated}`;
|
||||||
|
|
||||||
if (specific_processor) {
|
if (specific_processor) {
|
||||||
processed_obj = await Promise.resolve(specific_processor(processed_obj));
|
processed_obj = await Promise.resolve(
|
||||||
|
specific_processor(processed_obj)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
processed_obj_li.push(processed_obj as T);
|
processed_obj_li.push(processed_obj as T);
|
||||||
|
|||||||
@@ -191,7 +191,9 @@ async function _refresh_file_li_background({
|
|||||||
if (typeof navigator !== 'undefined' && !navigator.onLine) return [];
|
if (typeof navigator !== 'undefined' && !navigator.onLine) return [];
|
||||||
try {
|
try {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`📡 [DEBUG] _refresh_file_li_background: Fetching files for ${for_obj_type}:${for_obj_id}`);
|
console.log(
|
||||||
|
`📡 [DEBUG] _refresh_file_li_background: Fetching files for ${for_obj_type}:${for_obj_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const result_li = await api.get_ae_obj_li({
|
const result_li = await api.get_ae_obj_li({
|
||||||
@@ -211,7 +213,10 @@ async function _refresh_file_li_background({
|
|||||||
|
|
||||||
if (result_li) {
|
if (result_li) {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`📦 [DEBUG] Raw API results count:`, result_li.length);
|
console.log(
|
||||||
|
`📦 [DEBUG] Raw API results count:`,
|
||||||
|
result_li.length
|
||||||
|
);
|
||||||
if (result_li.length > 0) {
|
if (result_li.length > 0) {
|
||||||
console.log(`🔍 [DEBUG] Sample Raw IDs:`, {
|
console.log(`🔍 [DEBUG] Sample Raw IDs:`, {
|
||||||
id: result_li[0].id,
|
id: result_li[0].id,
|
||||||
@@ -253,7 +258,10 @@ async function _refresh_file_li_background({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
if (log_lvl) console.log(`💾 [DEBUG] Saving ${processed.length} records to ae_events_db.file`);
|
if (log_lvl)
|
||||||
|
console.log(
|
||||||
|
`💾 [DEBUG] Saving ${processed.length} records to ae_events_db.file`
|
||||||
|
);
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
db_instance: db_events,
|
db_instance: db_events,
|
||||||
table_name: 'file',
|
table_name: 'file',
|
||||||
@@ -265,10 +273,15 @@ async function _refresh_file_li_background({
|
|||||||
return processed;
|
return processed;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (log_lvl) console.error(`❌ [DEBUG] Error in _refresh_file_li_background:`, e);
|
if (log_lvl)
|
||||||
|
console.error(
|
||||||
|
`❌ [DEBUG] Error in _refresh_file_li_background:`,
|
||||||
|
e
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
}export async function create_event_file_obj_from_hosted_file_async({
|
}
|
||||||
|
export async function create_event_file_obj_from_hosted_file_async({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
hosted_file_id,
|
hosted_file_id,
|
||||||
params = {},
|
params = {},
|
||||||
@@ -459,7 +472,7 @@ export async function search__event_file({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return processed; // Return processed data with mapped fields
|
return processed; // Return processed data with mapped fields
|
||||||
}
|
}
|
||||||
|
|
||||||
return [];
|
return [];
|
||||||
@@ -545,7 +558,11 @@ async function _process_generic_props<T extends Record<string, any>>({
|
|||||||
if (key.endsWith('_random')) {
|
if (key.endsWith('_random')) {
|
||||||
const newKey = key.slice(0, -7);
|
const newKey = key.slice(0, -7);
|
||||||
// ONLY overwrite if the random variant has a valid value
|
// ONLY overwrite if the random variant has a valid value
|
||||||
if (processed_obj[key] !== null && processed_obj[key] !== undefined && processed_obj[key] !== '') {
|
if (
|
||||||
|
processed_obj[key] !== null &&
|
||||||
|
processed_obj[key] !== undefined &&
|
||||||
|
processed_obj[key] !== ''
|
||||||
|
) {
|
||||||
(processed_obj as any)[newKey] = processed_obj[key];
|
(processed_obj as any)[newKey] = processed_obj[key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,9 @@ export async function load_ae_obj_id__event_location({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_EventLocation | null> {
|
}): Promise<ae_EventLocation | null> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** load_ae_obj_id__event_location() *** [V3] id=${event_location_id} (SWR)`);
|
console.log(
|
||||||
|
`*** load_ae_obj_id__event_location() *** [V3] id=${event_location_id} (SWR)`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. FAST PATH: Cache hit
|
// 1. FAST PATH: Cache hit
|
||||||
@@ -46,12 +48,26 @@ export async function load_ae_obj_id__event_location({
|
|||||||
const cached = await db_events.location.get(event_location_id);
|
const cached = await db_events.location.get(event_location_id);
|
||||||
if (cached) {
|
if (cached) {
|
||||||
_refresh_location_id_background({
|
_refresh_location_id_background({
|
||||||
api_cfg, event_location_id, view, try_cache,
|
api_cfg,
|
||||||
inc_file_li, inc_session_li, inc_presentation_li, inc_presenter_li, inc_device_li, inc_all_file_li,
|
event_location_id,
|
||||||
|
view,
|
||||||
|
try_cache,
|
||||||
|
inc_file_li,
|
||||||
|
inc_session_li,
|
||||||
|
inc_presentation_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
inc_device_li,
|
||||||
|
inc_all_file_li,
|
||||||
log_lvl: 0
|
log_lvl: 0
|
||||||
});
|
});
|
||||||
return await _handle_nested_loads(cached, {
|
return await _handle_nested_loads(cached, {
|
||||||
api_cfg, inc_file_li, inc_session_li, inc_presentation_li, inc_presenter_li, inc_device_li, inc_all_file_li,
|
api_cfg,
|
||||||
|
inc_file_li,
|
||||||
|
inc_session_li,
|
||||||
|
inc_presentation_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
inc_device_li,
|
||||||
|
inc_all_file_li,
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -60,24 +76,65 @@ export async function load_ae_obj_id__event_location({
|
|||||||
|
|
||||||
// 2. SLOW PATH: Wait for API
|
// 2. SLOW PATH: Wait for API
|
||||||
return await _refresh_location_id_background({
|
return await _refresh_location_id_background({
|
||||||
api_cfg, event_location_id, view, try_cache,
|
api_cfg,
|
||||||
inc_file_li, inc_session_li, inc_presentation_li, inc_presenter_li, inc_device_li, inc_all_file_li,
|
event_location_id,
|
||||||
|
view,
|
||||||
|
try_cache,
|
||||||
|
inc_file_li,
|
||||||
|
inc_session_li,
|
||||||
|
inc_presentation_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
inc_device_li,
|
||||||
|
inc_all_file_li,
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function _refresh_location_id_background({ api_cfg, event_location_id, view, try_cache, inc_file_li, inc_session_li, inc_presentation_li, inc_presenter_li, inc_device_li, inc_all_file_li, log_lvl }: any) {
|
async function _refresh_location_id_background({
|
||||||
|
api_cfg,
|
||||||
|
event_location_id,
|
||||||
|
view,
|
||||||
|
try_cache,
|
||||||
|
inc_file_li,
|
||||||
|
inc_session_li,
|
||||||
|
inc_presentation_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
inc_device_li,
|
||||||
|
inc_all_file_li,
|
||||||
|
log_lvl
|
||||||
|
}: any) {
|
||||||
if (typeof navigator !== 'undefined' && !navigator.onLine) return null;
|
if (typeof navigator !== 'undefined' && !navigator.onLine) return null;
|
||||||
try {
|
try {
|
||||||
const result = await api.get_ae_obj({ api_cfg, obj_type: 'event_location', obj_id: event_location_id, view, log_lvl });
|
const result = await api.get_ae_obj({
|
||||||
|
api_cfg,
|
||||||
|
obj_type: 'event_location',
|
||||||
|
obj_id: event_location_id,
|
||||||
|
view,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
if (result) {
|
if (result) {
|
||||||
const processed = await process_ae_obj__event_location_props({ obj_li: [result], log_lvl });
|
const processed = await process_ae_obj__event_location_props({
|
||||||
|
obj_li: [result],
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
const processed_obj = processed[0];
|
const processed_obj = processed[0];
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'location', obj_li: [processed_obj], properties_to_save, log_lvl });
|
await db_save_ae_obj_li__ae_obj({
|
||||||
|
db_instance: db_events,
|
||||||
|
table_name: 'location',
|
||||||
|
obj_li: [processed_obj],
|
||||||
|
properties_to_save,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return await _handle_nested_loads(processed_obj, {
|
return await _handle_nested_loads(processed_obj, {
|
||||||
api_cfg, inc_file_li, inc_session_li, inc_presentation_li, inc_presenter_li, inc_device_li, inc_all_file_li,
|
api_cfg,
|
||||||
|
inc_file_li,
|
||||||
|
inc_session_li,
|
||||||
|
inc_presentation_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
inc_device_li,
|
||||||
|
inc_all_file_li,
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -129,23 +186,47 @@ export async function load_ae_obj_li__event_location({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_EventLocation[]> {
|
}): Promise<ae_EventLocation[]> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** load_ae_obj_li__event_location() *** [V3] for=${for_obj_type}:${for_obj_id} (SWR)`);
|
console.log(
|
||||||
|
`*** load_ae_obj_li__event_location() *** [V3] for=${for_obj_type}:${for_obj_id} (SWR)`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. FAST PATH: Check cache
|
// 1. FAST PATH: Check cache
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
try {
|
try {
|
||||||
const cached_li = await db_events.location.where('event_id').equals(for_obj_id).toArray();
|
const cached_li = await db_events.location
|
||||||
|
.where('event_id')
|
||||||
|
.equals(for_obj_id)
|
||||||
|
.toArray();
|
||||||
if (cached_li && cached_li.length > 0) {
|
if (cached_li && cached_li.length > 0) {
|
||||||
_refresh_location_li_background({
|
_refresh_location_li_background({
|
||||||
api_cfg, for_obj_type, for_obj_id,
|
api_cfg,
|
||||||
inc_file_li, inc_session_li, inc_presentation_li, inc_presenter_li, inc_device_li, inc_all_file_li,
|
for_obj_type,
|
||||||
enabled, hidden, view, limit, offset, order_by_li, try_cache,
|
for_obj_id,
|
||||||
|
inc_file_li,
|
||||||
|
inc_session_li,
|
||||||
|
inc_presentation_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
inc_device_li,
|
||||||
|
inc_all_file_li,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
view,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
order_by_li,
|
||||||
|
try_cache,
|
||||||
log_lvl: 0
|
log_lvl: 0
|
||||||
});
|
});
|
||||||
for (const loc of cached_li) {
|
for (const loc of cached_li) {
|
||||||
_handle_nested_loads(loc, {
|
_handle_nested_loads(loc, {
|
||||||
api_cfg, inc_file_li, inc_session_li, inc_presentation_li, inc_presenter_li, inc_device_li, inc_all_file_li,
|
api_cfg,
|
||||||
|
inc_file_li,
|
||||||
|
inc_session_li,
|
||||||
|
inc_presentation_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
inc_device_li,
|
||||||
|
inc_all_file_li,
|
||||||
log_lvl: 0
|
log_lvl: 0
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -156,31 +237,89 @@ export async function load_ae_obj_li__event_location({
|
|||||||
|
|
||||||
// 2. SLOW PATH: API
|
// 2. SLOW PATH: API
|
||||||
return await _refresh_location_li_background({
|
return await _refresh_location_li_background({
|
||||||
api_cfg, for_obj_type, for_obj_id,
|
api_cfg,
|
||||||
inc_file_li, inc_session_li, inc_presentation_li, inc_presenter_li, inc_device_li, inc_all_file_li,
|
for_obj_type,
|
||||||
enabled, hidden, view, limit, offset, order_by_li, try_cache,
|
for_obj_id,
|
||||||
|
inc_file_li,
|
||||||
|
inc_session_li,
|
||||||
|
inc_presentation_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
inc_device_li,
|
||||||
|
inc_all_file_li,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
view,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
order_by_li,
|
||||||
|
try_cache,
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function _refresh_location_li_background({ api_cfg, for_obj_type, for_obj_id, inc_file_li, inc_session_li, inc_presentation_li, inc_presenter_li, inc_device_li, inc_all_file_li, enabled, hidden, view, limit, offset, order_by_li, try_cache, log_lvl }: any) {
|
async function _refresh_location_li_background({
|
||||||
|
api_cfg,
|
||||||
|
for_obj_type,
|
||||||
|
for_obj_id,
|
||||||
|
inc_file_li,
|
||||||
|
inc_session_li,
|
||||||
|
inc_presentation_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
inc_device_li,
|
||||||
|
inc_all_file_li,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
view,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
order_by_li,
|
||||||
|
try_cache,
|
||||||
|
log_lvl
|
||||||
|
}: any) {
|
||||||
if (typeof navigator !== 'undefined' && !navigator.onLine) return [];
|
if (typeof navigator !== 'undefined' && !navigator.onLine) return [];
|
||||||
try {
|
try {
|
||||||
const result_li = await api.get_ae_obj_li({ api_cfg, obj_type: 'event_location', for_obj_type, for_obj_id, enabled, hidden, view, limit, offset, order_by_li, log_lvl });
|
const result_li = await api.get_ae_obj_li({
|
||||||
|
api_cfg,
|
||||||
|
obj_type: 'event_location',
|
||||||
|
for_obj_type,
|
||||||
|
for_obj_id,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
view,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
order_by_li,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
if (result_li) {
|
if (result_li) {
|
||||||
const processed = await process_ae_obj__event_location_props({ obj_li: result_li, log_lvl });
|
const processed = await process_ae_obj__event_location_props({
|
||||||
|
obj_li: result_li,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
|
|
||||||
// String-Only ID Vision: Ensure linking ID is set for indexing
|
// String-Only ID Vision: Ensure linking ID is set for indexing
|
||||||
if (for_obj_type === 'event') {
|
if (for_obj_type === 'event') {
|
||||||
processed.forEach(loc => loc.event_id = for_obj_id);
|
processed.forEach((loc) => (loc.event_id = for_obj_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'location', obj_li: processed, properties_to_save, log_lvl });
|
await db_save_ae_obj_li__ae_obj({
|
||||||
|
db_instance: db_events,
|
||||||
|
table_name: 'location',
|
||||||
|
obj_li: processed,
|
||||||
|
properties_to_save,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
}
|
}
|
||||||
for (const loc of processed) {
|
for (const loc of processed) {
|
||||||
_handle_nested_loads(loc, {
|
_handle_nested_loads(loc, {
|
||||||
api_cfg, inc_file_li, inc_session_li, inc_presentation_li, inc_presenter_li, inc_device_li, inc_all_file_li,
|
api_cfg,
|
||||||
|
inc_file_li,
|
||||||
|
inc_session_li,
|
||||||
|
inc_presentation_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
inc_device_li,
|
||||||
|
inc_all_file_li,
|
||||||
log_lvl: 0
|
log_lvl: 0
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -193,34 +332,66 @@ async function _refresh_location_li_background({ api_cfg, for_obj_type, for_obj_
|
|||||||
/**
|
/**
|
||||||
* Handle nested data loads for a single location object.
|
* Handle nested data loads for a single location object.
|
||||||
*/
|
*/
|
||||||
async function _handle_nested_loads(location_obj: any, { api_cfg, inc_file_li, inc_session_li, inc_presentation_li, inc_presenter_li, inc_device_li, inc_all_file_li, log_lvl }: any) {
|
async function _handle_nested_loads(
|
||||||
const current_location_id = location_obj.id || location_obj.event_location_id;
|
location_obj: any,
|
||||||
|
{
|
||||||
|
api_cfg,
|
||||||
|
inc_file_li,
|
||||||
|
inc_session_li,
|
||||||
|
inc_presentation_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
inc_device_li,
|
||||||
|
inc_all_file_li,
|
||||||
|
log_lvl
|
||||||
|
}: any
|
||||||
|
) {
|
||||||
|
const current_location_id =
|
||||||
|
location_obj.id || location_obj.event_location_id;
|
||||||
if (!current_location_id) return location_obj;
|
if (!current_location_id) return location_obj;
|
||||||
|
|
||||||
const tasks = [];
|
const tasks = [];
|
||||||
if (inc_file_li) {
|
if (inc_file_li) {
|
||||||
tasks.push(load_ae_obj_li__event_file({
|
tasks.push(
|
||||||
api_cfg, for_obj_type: 'event_location', for_obj_id: current_location_id,
|
load_ae_obj_li__event_file({
|
||||||
enabled: 'all', limit: 25, log_lvl
|
api_cfg,
|
||||||
}).then(res => location_obj.event_file_li = res));
|
for_obj_type: 'event_location',
|
||||||
|
for_obj_id: current_location_id,
|
||||||
|
enabled: 'all',
|
||||||
|
limit: 25,
|
||||||
|
log_lvl
|
||||||
|
}).then((res) => (location_obj.event_file_li = res))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inc_session_li) {
|
if (inc_session_li) {
|
||||||
tasks.push(load_ae_obj_li__event_session({
|
tasks.push(
|
||||||
api_cfg, for_obj_type: 'event_location', for_obj_id: current_location_id,
|
load_ae_obj_li__event_session({
|
||||||
inc_file_li: inc_all_file_li,
|
api_cfg,
|
||||||
inc_all_file_li: inc_all_file_li,
|
for_obj_type: 'event_location',
|
||||||
inc_presentation_li: inc_presentation_li,
|
for_obj_id: current_location_id,
|
||||||
inc_presenter_li: inc_presenter_li,
|
inc_file_li: inc_all_file_li,
|
||||||
enabled: 'enabled', hidden: 'not_hidden', limit: 150, log_lvl
|
inc_all_file_li: inc_all_file_li,
|
||||||
}).then(res => location_obj.event_session_obj_li = res));
|
inc_presentation_li: inc_presentation_li,
|
||||||
|
inc_presenter_li: inc_presenter_li,
|
||||||
|
enabled: 'enabled',
|
||||||
|
hidden: 'not_hidden',
|
||||||
|
limit: 150,
|
||||||
|
log_lvl
|
||||||
|
}).then((res) => (location_obj.event_session_obj_li = res))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inc_device_li) {
|
if (inc_device_li) {
|
||||||
tasks.push(load_ae_obj_li__event_device({
|
tasks.push(
|
||||||
api_cfg, for_obj_type: 'event_location', for_obj_id: current_location_id,
|
load_ae_obj_li__event_device({
|
||||||
enabled: 'all', limit: 50, log_lvl
|
api_cfg,
|
||||||
}).then(res => location_obj.event_device_li = res));
|
for_obj_type: 'event_location',
|
||||||
|
for_obj_id: current_location_id,
|
||||||
|
enabled: 'all',
|
||||||
|
limit: 50,
|
||||||
|
log_lvl
|
||||||
|
}).then((res) => (location_obj.event_device_li = res))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tasks.length > 0) await Promise.all(tasks);
|
if (tasks.length > 0) await Promise.all(tasks);
|
||||||
@@ -229,132 +400,183 @@ async function _handle_nested_loads(location_obj: any, { api_cfg, inc_file_li, i
|
|||||||
|
|
||||||
// Updated 2026-01-20 to V3
|
// Updated 2026-01-20 to V3
|
||||||
export async function create_ae_obj__event_location({
|
export async function create_ae_obj__event_location({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
event_id,
|
event_id,
|
||||||
data_kv,
|
data_kv,
|
||||||
try_cache = true,
|
try_cache = true,
|
||||||
log_lvl = 0
|
log_lvl = 0
|
||||||
}: {
|
}: {
|
||||||
api_cfg: any;
|
api_cfg: any;
|
||||||
event_id: string;
|
event_id: string;
|
||||||
data_kv: key_val;
|
data_kv: key_val;
|
||||||
try_cache?: boolean;
|
try_cache?: boolean;
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_EventLocation | null> {
|
}): Promise<ae_EventLocation | null> {
|
||||||
const result = await api.create_nested_obj({
|
const result = await api.create_nested_obj({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
for_obj_type: 'event',
|
for_obj_type: 'event',
|
||||||
for_obj_id: event_id,
|
for_obj_id: event_id,
|
||||||
obj_type: 'event_location',
|
obj_type: 'event_location',
|
||||||
fields: { ...data_kv },
|
fields: { ...data_kv },
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
const processed = await process_ae_obj__event_location_props({ obj_li: [result], log_lvl });
|
const processed = await process_ae_obj__event_location_props({
|
||||||
const processed_obj = processed[0];
|
obj_li: [result],
|
||||||
if (try_cache) {
|
log_lvl
|
||||||
await db_save_ae_obj_li__ae_obj({
|
});
|
||||||
db_instance: db_events,
|
const processed_obj = processed[0];
|
||||||
table_name: 'location',
|
if (try_cache) {
|
||||||
obj_li: [processed_obj],
|
await db_save_ae_obj_li__ae_obj({
|
||||||
properties_to_save,
|
db_instance: db_events,
|
||||||
log_lvl
|
table_name: 'location',
|
||||||
});
|
obj_li: [processed_obj],
|
||||||
}
|
properties_to_save,
|
||||||
return processed_obj;
|
log_lvl
|
||||||
}
|
});
|
||||||
return null;
|
}
|
||||||
|
return processed_obj;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updated 2026-01-20 to V3
|
// Updated 2026-01-20 to V3
|
||||||
export async function delete_ae_obj_id__event_location({
|
export async function delete_ae_obj_id__event_location({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
event_id,
|
event_id,
|
||||||
event_location_id,
|
event_location_id,
|
||||||
method = 'delete',
|
method = 'delete',
|
||||||
try_cache = true,
|
try_cache = true,
|
||||||
log_lvl = 0
|
log_lvl = 0
|
||||||
}: {
|
}: {
|
||||||
api_cfg: any;
|
api_cfg: any;
|
||||||
event_id: string;
|
event_id: string;
|
||||||
event_location_id: string;
|
event_location_id: string;
|
||||||
method?: 'delete' | 'soft_delete' | 'disable' | 'hide';
|
method?: 'delete' | 'soft_delete' | 'disable' | 'hide';
|
||||||
try_cache?: boolean;
|
try_cache?: boolean;
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}) {
|
}) {
|
||||||
const result = await api.delete_nested_ae_obj({
|
const result = await api.delete_nested_ae_obj({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
for_obj_type: 'event',
|
for_obj_type: 'event',
|
||||||
for_obj_id: event_id,
|
for_obj_id: event_id,
|
||||||
obj_type: 'event_location',
|
obj_type: 'event_location',
|
||||||
obj_id: event_location_id,
|
obj_id: event_location_id,
|
||||||
method,
|
method,
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
if (try_cache) await db_events.location.delete(event_location_id);
|
if (try_cache) await db_events.location.delete(event_location_id);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updated 2026-01-20 to V3
|
// Updated 2026-01-20 to V3
|
||||||
export async function update_ae_obj__event_location({
|
export async function update_ae_obj__event_location({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
event_id,
|
event_id,
|
||||||
event_location_id,
|
event_location_id,
|
||||||
data_kv,
|
data_kv,
|
||||||
try_cache = true,
|
try_cache = true,
|
||||||
log_lvl = 0
|
log_lvl = 0
|
||||||
}: {
|
}: {
|
||||||
api_cfg: any;
|
api_cfg: any;
|
||||||
event_id: string;
|
event_id: string;
|
||||||
event_location_id: string;
|
event_location_id: string;
|
||||||
data_kv: key_val;
|
data_kv: key_val;
|
||||||
try_cache?: boolean;
|
try_cache?: boolean;
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_EventLocation | null> {
|
}): Promise<ae_EventLocation | null> {
|
||||||
const result = await api.update_nested_obj({
|
const result = await api.update_nested_obj({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
for_obj_type: 'event',
|
for_obj_type: 'event',
|
||||||
for_obj_id: event_id,
|
for_obj_id: event_id,
|
||||||
obj_type: 'event_location',
|
obj_type: 'event_location',
|
||||||
obj_id: event_location_id,
|
obj_id: event_location_id,
|
||||||
fields: data_kv,
|
fields: data_kv,
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
if (result) {
|
if (result) {
|
||||||
const processed = await process_ae_obj__event_location_props({ obj_li: [result], log_lvl });
|
const processed = await process_ae_obj__event_location_props({
|
||||||
const processed_obj = processed[0];
|
obj_li: [result],
|
||||||
if (try_cache) {
|
log_lvl
|
||||||
await db_save_ae_obj_li__ae_obj({
|
});
|
||||||
db_instance: db_events,
|
const processed_obj = processed[0];
|
||||||
table_name: 'location',
|
if (try_cache) {
|
||||||
obj_li: [processed_obj],
|
await db_save_ae_obj_li__ae_obj({
|
||||||
properties_to_save,
|
db_instance: db_events,
|
||||||
log_lvl
|
table_name: 'location',
|
||||||
});
|
obj_li: [processed_obj],
|
||||||
}
|
properties_to_save,
|
||||||
return processed_obj;
|
log_lvl
|
||||||
}
|
});
|
||||||
return null;
|
}
|
||||||
|
return processed_obj;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updated 2026-01-20 to V3
|
// Updated 2026-01-20 to V3
|
||||||
export async function search__event_location({
|
export async function search__event_location({
|
||||||
api_cfg, event_id, qry_str = '', enabled = 'enabled', hidden = 'not_hidden', view = 'default', limit = 25, offset = 0, order_by_li = [{ sort: 'ASC' }, { name: 'ASC' }], try_cache = true, log_lvl = 0
|
api_cfg,
|
||||||
|
event_id,
|
||||||
|
qry_str = '',
|
||||||
|
enabled = 'enabled',
|
||||||
|
hidden = 'not_hidden',
|
||||||
|
view = 'default',
|
||||||
|
limit = 25,
|
||||||
|
offset = 0,
|
||||||
|
order_by_li = [{ sort: 'ASC' }, { name: 'ASC' }],
|
||||||
|
try_cache = true,
|
||||||
|
log_lvl = 0
|
||||||
}: {
|
}: {
|
||||||
api_cfg: any; event_id: string; qry_str?: string; enabled?: 'enabled' | 'all' | 'not_enabled'; hidden?: 'hidden' | 'all' | 'not_hidden'; view?: string; limit?: number; offset?: number; order_by_li?: any; try_cache?: boolean; log_lvl?: number;
|
api_cfg: any;
|
||||||
|
event_id: string;
|
||||||
|
qry_str?: string;
|
||||||
|
enabled?: 'enabled' | 'all' | 'not_enabled';
|
||||||
|
hidden?: 'hidden' | 'all' | 'not_hidden';
|
||||||
|
view?: string;
|
||||||
|
limit?: number;
|
||||||
|
offset?: number;
|
||||||
|
order_by_li?: any;
|
||||||
|
try_cache?: boolean;
|
||||||
|
log_lvl?: number;
|
||||||
}): Promise<ae_EventLocation[]> {
|
}): Promise<ae_EventLocation[]> {
|
||||||
const search_query: any = { q: qry_str, and: [{ field: 'event_id', op: 'eq', value: event_id }] };
|
const search_query: any = {
|
||||||
if (enabled === 'enabled') search_query.and.push({ field: 'enable', op: 'eq', value: true });
|
q: qry_str,
|
||||||
else if (enabled === 'not_enabled') search_query.and.push({ field: 'enable', op: 'eq', value: false });
|
and: [{ field: 'event_id', op: 'eq', value: event_id }]
|
||||||
if (hidden === 'hidden') search_query.and.push({ field: 'hide', op: 'eq', value: true });
|
};
|
||||||
else if (hidden === 'not_hidden') search_query.and.push({ field: 'hide', op: 'eq', value: false });
|
if (enabled === 'enabled')
|
||||||
|
search_query.and.push({ field: 'enable', op: 'eq', value: true });
|
||||||
|
else if (enabled === 'not_enabled')
|
||||||
|
search_query.and.push({ field: 'enable', op: 'eq', value: false });
|
||||||
|
if (hidden === 'hidden')
|
||||||
|
search_query.and.push({ field: 'hide', op: 'eq', value: true });
|
||||||
|
else if (hidden === 'not_hidden')
|
||||||
|
search_query.and.push({ field: 'hide', op: 'eq', value: false });
|
||||||
|
|
||||||
const result_li = await api.search_ae_obj({ api_cfg, obj_type: 'event_location', search_query, order_by_li, view, limit, offset, log_lvl });
|
const result_li = await api.search_ae_obj({
|
||||||
|
api_cfg,
|
||||||
|
obj_type: 'event_location',
|
||||||
|
search_query,
|
||||||
|
order_by_li,
|
||||||
|
view,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
if (result_li) {
|
if (result_li) {
|
||||||
const processed = await process_ae_obj__event_location_props({ obj_li: result_li, log_lvl });
|
const processed = await process_ae_obj__event_location_props({
|
||||||
|
obj_li: result_li,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'location', obj_li: processed, properties_to_save, log_lvl });
|
await db_save_ae_obj_li__ae_obj({
|
||||||
|
db_instance: db_events,
|
||||||
|
table_name: 'location',
|
||||||
|
obj_li: processed,
|
||||||
|
properties_to_save,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return processed;
|
return processed;
|
||||||
}
|
}
|
||||||
@@ -362,10 +584,40 @@ export async function search__event_location({
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const properties_to_save = [
|
export const properties_to_save = [
|
||||||
'id', 'event_location_id', 'event_location_id_random', 'event_id', 'event_id_random', 'external_id', 'code', 'name', 'description', 'passcode', 'enable', 'hide', 'priority', 'sort', 'group', 'notes', 'created_on', 'updated_on', 'tmp_sort_1', 'tmp_sort_2', 'event_name'
|
'id',
|
||||||
|
'event_location_id',
|
||||||
|
'event_location_id_random',
|
||||||
|
'event_id',
|
||||||
|
'event_id_random',
|
||||||
|
'external_id',
|
||||||
|
'code',
|
||||||
|
'name',
|
||||||
|
'description',
|
||||||
|
'passcode',
|
||||||
|
'enable',
|
||||||
|
'hide',
|
||||||
|
'priority',
|
||||||
|
'sort',
|
||||||
|
'group',
|
||||||
|
'notes',
|
||||||
|
'created_on',
|
||||||
|
'updated_on',
|
||||||
|
'tmp_sort_1',
|
||||||
|
'tmp_sort_2',
|
||||||
|
'event_name'
|
||||||
];
|
];
|
||||||
|
|
||||||
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[]> {
|
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 [];
|
if (!obj_li || obj_li.length === 0) return [];
|
||||||
const processed_obj_li: T[] = [];
|
const processed_obj_li: T[] = [];
|
||||||
for (const original_obj of obj_li) {
|
for (const original_obj of obj_li) {
|
||||||
@@ -378,24 +630,42 @@ async function _process_generic_props<T extends Record<string, any>>({ obj_li, o
|
|||||||
}
|
}
|
||||||
const randomIdKey = `${obj_type}_id_random`;
|
const randomIdKey = `${obj_type}_id_random`;
|
||||||
const baseIdKey = `${obj_type}_id`;
|
const baseIdKey = `${obj_type}_id`;
|
||||||
if (processed_obj[randomIdKey]) (processed_obj as any).id = processed_obj[randomIdKey];
|
if (processed_obj[randomIdKey])
|
||||||
else if (processed_obj[baseIdKey]) (processed_obj as any).id = processed_obj[baseIdKey];
|
(processed_obj as any).id = processed_obj[randomIdKey];
|
||||||
|
else if (processed_obj[baseIdKey])
|
||||||
|
(processed_obj as any).id = processed_obj[baseIdKey];
|
||||||
const group = processed_obj.group ?? '0';
|
const group = processed_obj.group ?? '0';
|
||||||
const priority = processed_obj.priority ? 1 : 0;
|
const priority = processed_obj.priority ? 1 : 0;
|
||||||
const sort = processed_obj.sort ?? '0';
|
const sort = processed_obj.sort ?? '0';
|
||||||
const updated = processed_obj.updated_on ?? processed_obj.created_on;
|
const updated = processed_obj.updated_on ?? processed_obj.created_on;
|
||||||
const name = processed_obj.name ?? '';
|
const name = processed_obj.name ?? '';
|
||||||
(processed_obj as any).tmp_sort_1 = `${group}_${priority}_${sort}_${updated}`;
|
(processed_obj as any).tmp_sort_1 =
|
||||||
(processed_obj as any).tmp_sort_2 = `${group}_${priority}_${sort}_${name}_${updated}`;
|
`${group}_${priority}_${sort}_${updated}`;
|
||||||
if (specific_processor) processed_obj = await Promise.resolve(specific_processor(processed_obj));
|
(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);
|
processed_obj_li.push(processed_obj as T);
|
||||||
}
|
}
|
||||||
return processed_obj_li;
|
return processed_obj_li;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function process_ae_obj__event_location_props({ obj_li, log_lvl = 0 }: { obj_li: any[]; log_lvl?: number; }) {
|
export async function process_ae_obj__event_location_props({
|
||||||
return _process_generic_props({ obj_li, obj_type: 'event_location', log_lvl, specific_processor: (obj) => {
|
obj_li,
|
||||||
if (obj.event_id_random) obj.event_id = obj.event_id_random;
|
log_lvl = 0
|
||||||
return obj;
|
}: {
|
||||||
}});
|
obj_li: any[];
|
||||||
|
log_lvl?: number;
|
||||||
|
}) {
|
||||||
|
return _process_generic_props({
|
||||||
|
obj_li,
|
||||||
|
obj_type: 'event_location',
|
||||||
|
log_lvl,
|
||||||
|
specific_processor: (obj) => {
|
||||||
|
if (obj.event_id_random) obj.event_id = obj.event_id_random;
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
@@ -37,41 +37,116 @@ export async function load_ae_obj_id__event_presentation({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_EventPresentation | null> {
|
}): Promise<ae_EventPresentation | null> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** load_ae_obj_id__event_presentation() *** id=${event_presentation_id} (SWR)`);
|
console.log(
|
||||||
|
`*** load_ae_obj_id__event_presentation() *** id=${event_presentation_id} (SWR)`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. FAST PATH: Cache hit
|
// 1. FAST PATH: Cache hit
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
try {
|
try {
|
||||||
const cached = await db_events.presentation.get(event_presentation_id);
|
const cached = await db_events.presentation.get(
|
||||||
|
event_presentation_id
|
||||||
|
);
|
||||||
if (cached) {
|
if (cached) {
|
||||||
// Background refresh (non-blocking)
|
// Background refresh (non-blocking)
|
||||||
_refresh_presentation_id_background({ api_cfg, event_presentation_id, view, try_cache, inc_file_li, inc_presenter_li, enabled, hidden, limit, offset, log_lvl: 0 });
|
_refresh_presentation_id_background({
|
||||||
|
api_cfg,
|
||||||
|
event_presentation_id,
|
||||||
|
view,
|
||||||
|
try_cache,
|
||||||
|
inc_file_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
log_lvl: 0
|
||||||
|
});
|
||||||
// Await nested loads from cache to return a complete object
|
// Await nested loads from cache to return a complete object
|
||||||
return await _handle_nested_loads(cached, { api_cfg, inc_file_li, inc_presenter_li, enabled, hidden, limit, offset, try_cache, log_lvl: 0 });
|
return await _handle_nested_loads(cached, {
|
||||||
|
api_cfg,
|
||||||
|
inc_file_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
try_cache,
|
||||||
|
log_lvl: 0
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. SLOW PATH: Wait for API
|
// 2. SLOW PATH: Wait for API
|
||||||
return await _refresh_presentation_id_background({ api_cfg, event_presentation_id, view, try_cache, inc_file_li, inc_presenter_li, enabled, hidden, limit, offset, log_lvl });
|
return await _refresh_presentation_id_background({
|
||||||
|
api_cfg,
|
||||||
|
event_presentation_id,
|
||||||
|
view,
|
||||||
|
try_cache,
|
||||||
|
inc_file_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal background refresh for a single presentation
|
* Internal background refresh for a single presentation
|
||||||
*/
|
*/
|
||||||
async function _refresh_presentation_id_background({ api_cfg, event_presentation_id, view, try_cache, inc_file_li, inc_presenter_li, enabled, hidden, limit, offset, log_lvl }: any) {
|
async function _refresh_presentation_id_background({
|
||||||
|
api_cfg,
|
||||||
|
event_presentation_id,
|
||||||
|
view,
|
||||||
|
try_cache,
|
||||||
|
inc_file_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
log_lvl
|
||||||
|
}: any) {
|
||||||
if (typeof navigator !== 'undefined' && !navigator.onLine) return null;
|
if (typeof navigator !== 'undefined' && !navigator.onLine) return null;
|
||||||
try {
|
try {
|
||||||
const result = await api.get_ae_obj({ api_cfg, obj_type: 'event_presentation', obj_id: event_presentation_id, view, log_lvl });
|
const result = await api.get_ae_obj({
|
||||||
|
api_cfg,
|
||||||
|
obj_type: 'event_presentation',
|
||||||
|
obj_id: event_presentation_id,
|
||||||
|
view,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
if (result) {
|
if (result) {
|
||||||
const processed = await process_ae_obj__event_presentation_props({ obj_li: [result], log_lvl });
|
const processed = await process_ae_obj__event_presentation_props({
|
||||||
|
obj_li: [result],
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
const processed_obj = processed[0];
|
const processed_obj = processed[0];
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'presentation', obj_li: [processed_obj], properties_to_save, log_lvl });
|
await db_save_ae_obj_li__ae_obj({
|
||||||
|
db_instance: db_events,
|
||||||
|
table_name: 'presentation',
|
||||||
|
obj_li: [processed_obj],
|
||||||
|
properties_to_save,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
}
|
}
|
||||||
// During refresh, we disable child SWR to prevent a request storm
|
// During refresh, we disable child SWR to prevent a request storm
|
||||||
return await _handle_nested_loads(processed_obj, { api_cfg, inc_file_li, inc_presenter_li, enabled, hidden, limit, offset, try_cache: false, log_lvl });
|
return await _handle_nested_loads(processed_obj, {
|
||||||
|
api_cfg,
|
||||||
|
inc_file_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
try_cache: false,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
return null;
|
return null;
|
||||||
@@ -80,23 +155,54 @@ async function _refresh_presentation_id_background({ api_cfg, event_presentation
|
|||||||
/**
|
/**
|
||||||
* Helper to handle nested collection loads for a presentation
|
* Helper to handle nested collection loads for a presentation
|
||||||
*/
|
*/
|
||||||
async function _handle_nested_loads(presentation_obj: any, { api_cfg, inc_file_li, inc_presenter_li, enabled, hidden, limit, offset, try_cache, log_lvl }: any) {
|
async function _handle_nested_loads(
|
||||||
const current_presentation_id = presentation_obj.id || presentation_obj.event_presentation_id;
|
presentation_obj: any,
|
||||||
|
{
|
||||||
|
api_cfg,
|
||||||
|
inc_file_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
try_cache,
|
||||||
|
log_lvl
|
||||||
|
}: any
|
||||||
|
) {
|
||||||
|
const current_presentation_id =
|
||||||
|
presentation_obj.id || presentation_obj.event_presentation_id;
|
||||||
if (!current_presentation_id) return presentation_obj;
|
if (!current_presentation_id) return presentation_obj;
|
||||||
|
|
||||||
const tasks = [];
|
const tasks = [];
|
||||||
if (inc_file_li) {
|
if (inc_file_li) {
|
||||||
tasks.push(load_ae_obj_li__event_file({
|
tasks.push(
|
||||||
api_cfg, for_obj_type: 'event_presentation', for_obj_id: current_presentation_id,
|
load_ae_obj_li__event_file({
|
||||||
enabled, limit: 25, try_cache, log_lvl
|
api_cfg,
|
||||||
}).then(res => presentation_obj.event_file_li = res));
|
for_obj_type: 'event_presentation',
|
||||||
|
for_obj_id: current_presentation_id,
|
||||||
|
enabled,
|
||||||
|
limit: 25,
|
||||||
|
try_cache,
|
||||||
|
log_lvl
|
||||||
|
}).then((res) => (presentation_obj.event_file_li = res))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inc_presenter_li) {
|
if (inc_presenter_li) {
|
||||||
tasks.push(load_ae_obj_li__event_presenter({
|
tasks.push(
|
||||||
api_cfg, for_obj_type: 'event_presentation', for_obj_id: current_presentation_id,
|
load_ae_obj_li__event_presenter({
|
||||||
inc_file_li, enabled, hidden, limit, offset, try_cache, log_lvl
|
api_cfg,
|
||||||
}).then(res => presentation_obj.event_presenter_li = res));
|
for_obj_type: 'event_presentation',
|
||||||
|
for_obj_id: current_presentation_id,
|
||||||
|
inc_file_li,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
try_cache,
|
||||||
|
log_lvl
|
||||||
|
}).then((res) => (presentation_obj.event_presenter_li = res))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tasks.length > 0) await Promise.all(tasks);
|
if (tasks.length > 0) await Promise.all(tasks);
|
||||||
@@ -140,17 +246,36 @@ export async function load_ae_obj_li__event_presentation({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_EventPresentation[]> {
|
}): Promise<ae_EventPresentation[]> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** load_ae_obj_li__event_presentation() *** for=${for_obj_type}:${for_obj_id} (SWR)`);
|
console.log(
|
||||||
|
`*** load_ae_obj_li__event_presentation() *** for=${for_obj_type}:${for_obj_id} (SWR)`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. FAST PATH: Cache hit
|
// 1. FAST PATH: Cache hit
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
try {
|
try {
|
||||||
// String-Only ID Vision: query event_session_id using the string ID
|
// String-Only ID Vision: query event_session_id using the string ID
|
||||||
const cached_li = await db_events.presentation.where('event_session_id').equals(for_obj_id).toArray();
|
const cached_li = await db_events.presentation
|
||||||
|
.where('event_session_id')
|
||||||
|
.equals(for_obj_id)
|
||||||
|
.toArray();
|
||||||
if (cached_li && cached_li.length > 0) {
|
if (cached_li && cached_li.length > 0) {
|
||||||
// Background refresh (non-blocking)
|
// Background refresh (non-blocking)
|
||||||
_refresh_presentation_li_background({ api_cfg, for_obj_type, for_obj_id, inc_file_li, inc_presenter_li, enabled, hidden, view, limit, offset, order_by_li, try_cache, log_lvl: 0 });
|
_refresh_presentation_li_background({
|
||||||
|
api_cfg,
|
||||||
|
for_obj_type,
|
||||||
|
for_obj_id,
|
||||||
|
inc_file_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
view,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
order_by_li,
|
||||||
|
try_cache,
|
||||||
|
log_lvl: 0
|
||||||
|
});
|
||||||
|
|
||||||
// Warm cache for nested loads in the background (FIRE AND FORGET)
|
// Warm cache for nested loads in the background (FIRE AND FORGET)
|
||||||
// DEPRECATED Optimization: Don't fire child loads for every item in a list here.
|
// DEPRECATED Optimization: Don't fire child loads for every item in a list here.
|
||||||
@@ -167,23 +292,72 @@ export async function load_ae_obj_li__event_presentation({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 2. SLOW PATH: Wait for API
|
// 2. SLOW PATH: Wait for API
|
||||||
return await _refresh_presentation_li_background({ api_cfg, for_obj_type, for_obj_id, inc_file_li, inc_presenter_li, enabled, hidden, view, limit, offset, order_by_li, try_cache, log_lvl });
|
return await _refresh_presentation_li_background({
|
||||||
|
api_cfg,
|
||||||
|
for_obj_type,
|
||||||
|
for_obj_id,
|
||||||
|
inc_file_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
view,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
order_by_li,
|
||||||
|
try_cache,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function _refresh_presentation_li_background({ api_cfg, for_obj_type, for_obj_id, inc_file_li, inc_presenter_li, enabled, hidden, view, limit, offset, order_by_li, try_cache, log_lvl }: any) {
|
async function _refresh_presentation_li_background({
|
||||||
|
api_cfg,
|
||||||
|
for_obj_type,
|
||||||
|
for_obj_id,
|
||||||
|
inc_file_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
view,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
order_by_li,
|
||||||
|
try_cache,
|
||||||
|
log_lvl
|
||||||
|
}: any) {
|
||||||
if (typeof navigator !== 'undefined' && !navigator.onLine) return [];
|
if (typeof navigator !== 'undefined' && !navigator.onLine) return [];
|
||||||
try {
|
try {
|
||||||
const result_li = await api.get_ae_obj_li({ api_cfg, obj_type: 'event_presentation', for_obj_type, for_obj_id, enabled, hidden, view, limit, offset, order_by_li, log_lvl });
|
const result_li = await api.get_ae_obj_li({
|
||||||
|
api_cfg,
|
||||||
|
obj_type: 'event_presentation',
|
||||||
|
for_obj_type,
|
||||||
|
for_obj_id,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
view,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
order_by_li,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
if (result_li) {
|
if (result_li) {
|
||||||
const processed = await process_ae_obj__event_presentation_props({ obj_li: result_li, log_lvl });
|
const processed = await process_ae_obj__event_presentation_props({
|
||||||
|
obj_li: result_li,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
|
|
||||||
// Ensure the linking ID is set correctly for indexing
|
// Ensure the linking ID is set correctly for indexing
|
||||||
if (for_obj_type === 'event_session') {
|
if (for_obj_type === 'event_session') {
|
||||||
processed.forEach(p => p.event_session_id = for_obj_id);
|
processed.forEach((p) => (p.event_session_id = for_obj_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'presentation', obj_li: processed, properties_to_save, log_lvl });
|
await db_save_ae_obj_li__ae_obj({
|
||||||
|
db_instance: db_events,
|
||||||
|
table_name: 'presentation',
|
||||||
|
obj_li: processed,
|
||||||
|
properties_to_save,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
// CRITICAL FIX (2026-02-26): Yield to microtask queue so Dexie liveQuery observers
|
// CRITICAL FIX (2026-02-26): Yield to microtask queue so Dexie liveQuery observers
|
||||||
// fire before we return. Without this, component-mounted liveQueries may subscribe
|
// fire before we return. Without this, component-mounted liveQueries may subscribe
|
||||||
// to IDB *before* the write completes, causing empty results on cold-start.
|
// to IDB *before* the write completes, causing empty results on cold-start.
|
||||||
@@ -194,9 +368,21 @@ async function _refresh_presentation_li_background({ api_cfg, for_obj_type, for_
|
|||||||
// before presenter data was loaded, causing "refresh twice" bug on cold-start.
|
// before presenter data was loaded, causing "refresh twice" bug on cold-start.
|
||||||
// Now we await all nested loads AND preserve try_cache so presenters are written to IDB.
|
// Now we await all nested loads AND preserve try_cache so presenters are written to IDB.
|
||||||
if (inc_file_li || inc_presenter_li) {
|
if (inc_file_li || inc_presenter_li) {
|
||||||
await Promise.all(processed.map(p =>
|
await Promise.all(
|
||||||
_handle_nested_loads(p, { api_cfg, inc_file_li, inc_presenter_li, enabled, hidden, limit, offset, try_cache, log_lvl: 0 })
|
processed.map((p) =>
|
||||||
));
|
_handle_nested_loads(p, {
|
||||||
|
api_cfg,
|
||||||
|
inc_file_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
try_cache,
|
||||||
|
log_lvl: 0
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return processed;
|
return processed;
|
||||||
}
|
}
|
||||||
@@ -206,42 +392,45 @@ async function _refresh_presentation_li_background({ api_cfg, for_obj_type, for_
|
|||||||
|
|
||||||
// Updated 2026-01-20 to V3
|
// Updated 2026-01-20 to V3
|
||||||
export async function create_ae_obj__event_presentation({
|
export async function create_ae_obj__event_presentation({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
event_session_id,
|
event_session_id,
|
||||||
data_kv,
|
data_kv,
|
||||||
try_cache = true,
|
try_cache = true,
|
||||||
log_lvl = 0
|
log_lvl = 0
|
||||||
}: {
|
}: {
|
||||||
api_cfg: any;
|
api_cfg: any;
|
||||||
event_session_id: string;
|
event_session_id: string;
|
||||||
data_kv: key_val;
|
data_kv: key_val;
|
||||||
try_cache?: boolean;
|
try_cache?: boolean;
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_EventPresentation | null> {
|
}): Promise<ae_EventPresentation | null> {
|
||||||
const result = await api.create_nested_obj({
|
const result = await api.create_nested_obj({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
for_obj_type: 'event_session',
|
for_obj_type: 'event_session',
|
||||||
for_obj_id: event_session_id,
|
for_obj_id: event_session_id,
|
||||||
obj_type: 'event_presentation',
|
obj_type: 'event_presentation',
|
||||||
fields: { ...data_kv },
|
fields: { ...data_kv },
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
const processed = await process_ae_obj__event_presentation_props({ obj_li: [result], log_lvl });
|
const processed = await process_ae_obj__event_presentation_props({
|
||||||
const processed_obj = processed[0];
|
obj_li: [result],
|
||||||
if (try_cache) {
|
log_lvl
|
||||||
await db_save_ae_obj_li__ae_obj({
|
});
|
||||||
db_instance: db_events,
|
const processed_obj = processed[0];
|
||||||
table_name: 'presentation',
|
if (try_cache) {
|
||||||
obj_li: [processed_obj],
|
await db_save_ae_obj_li__ae_obj({
|
||||||
properties_to_save,
|
db_instance: db_events,
|
||||||
log_lvl
|
table_name: 'presentation',
|
||||||
});
|
obj_li: [processed_obj],
|
||||||
}
|
properties_to_save,
|
||||||
return processed_obj;
|
log_lvl
|
||||||
}
|
});
|
||||||
return null;
|
}
|
||||||
|
return processed_obj;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updated 2026-01-20 to V3
|
// Updated 2026-01-20 to V3
|
||||||
@@ -259,7 +448,11 @@ export async function delete_ae_obj_id__event_presentation({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}) {
|
}) {
|
||||||
const result = await api.delete_ae_obj({
|
const result = await api.delete_ae_obj({
|
||||||
api_cfg, obj_type: 'event_presentation', obj_id: event_presentation_id, method, log_lvl
|
api_cfg,
|
||||||
|
obj_type: 'event_presentation',
|
||||||
|
obj_id: event_presentation_id,
|
||||||
|
method,
|
||||||
|
log_lvl
|
||||||
});
|
});
|
||||||
if (try_cache) await db_events.presentation.delete(event_presentation_id);
|
if (try_cache) await db_events.presentation.delete(event_presentation_id);
|
||||||
return result;
|
return result;
|
||||||
@@ -280,13 +473,26 @@ export async function update_ae_obj__event_presentation({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_EventPresentation | null> {
|
}): Promise<ae_EventPresentation | null> {
|
||||||
const result = await api.update_ae_obj({
|
const result = await api.update_ae_obj({
|
||||||
api_cfg, obj_type: 'event_presentation', obj_id: event_presentation_id, fields: data_kv, log_lvl
|
api_cfg,
|
||||||
|
obj_type: 'event_presentation',
|
||||||
|
obj_id: event_presentation_id,
|
||||||
|
fields: data_kv,
|
||||||
|
log_lvl
|
||||||
});
|
});
|
||||||
if (result) {
|
if (result) {
|
||||||
const processed = await process_ae_obj__event_presentation_props({ obj_li: [result], log_lvl });
|
const processed = await process_ae_obj__event_presentation_props({
|
||||||
|
obj_li: [result],
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
const processed_obj = processed[0];
|
const processed_obj = processed[0];
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'presentation', obj_li: [processed_obj], properties_to_save, log_lvl });
|
await db_save_ae_obj_li__ae_obj({
|
||||||
|
db_instance: db_events,
|
||||||
|
table_name: 'presentation',
|
||||||
|
obj_li: [processed_obj],
|
||||||
|
properties_to_save,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return processed_obj;
|
return processed_obj;
|
||||||
}
|
}
|
||||||
@@ -295,24 +501,74 @@ export async function update_ae_obj__event_presentation({
|
|||||||
|
|
||||||
// Updated 2026-01-21 to Restore Full Aether Search Logic
|
// Updated 2026-01-21 to Restore Full Aether Search Logic
|
||||||
export async function search__event_presentation({
|
export async function search__event_presentation({
|
||||||
api_cfg, event_id, fulltext_search_qry_str = '', like_search_qry_str = '', enabled = 'enabled', hidden = 'not_hidden', view = 'default', limit = 50, offset = 0, order_by_li = [{ sort: 'ASC' }, { start_datetime: 'ASC' }, { name: 'ASC' }], try_cache = true, log_lvl = 0
|
api_cfg,
|
||||||
|
event_id,
|
||||||
|
fulltext_search_qry_str = '',
|
||||||
|
like_search_qry_str = '',
|
||||||
|
enabled = 'enabled',
|
||||||
|
hidden = 'not_hidden',
|
||||||
|
view = 'default',
|
||||||
|
limit = 50,
|
||||||
|
offset = 0,
|
||||||
|
order_by_li = [{ sort: 'ASC' }, { start_datetime: 'ASC' }, { name: 'ASC' }],
|
||||||
|
try_cache = true,
|
||||||
|
log_lvl = 0
|
||||||
}: {
|
}: {
|
||||||
api_cfg: any; event_id: string; fulltext_search_qry_str?: string; like_search_qry_str?: string; enabled?: 'enabled' | 'all' | 'not_enabled'; hidden?: 'hidden' | 'all' | 'not_hidden'; view?: string; limit?: number; offset?: number; order_by_li?: any; try_cache?: boolean; log_lvl?: number;
|
api_cfg: any;
|
||||||
|
event_id: string;
|
||||||
|
fulltext_search_qry_str?: string;
|
||||||
|
like_search_qry_str?: string;
|
||||||
|
enabled?: 'enabled' | 'all' | 'not_enabled';
|
||||||
|
hidden?: 'hidden' | 'all' | 'not_hidden';
|
||||||
|
view?: string;
|
||||||
|
limit?: number;
|
||||||
|
offset?: number;
|
||||||
|
order_by_li?: any;
|
||||||
|
try_cache?: boolean;
|
||||||
|
log_lvl?: number;
|
||||||
}): Promise<ae_EventPresentation[]> {
|
}): Promise<ae_EventPresentation[]> {
|
||||||
const search_query: any = { q: '', and: [{ field: 'event_id', op: 'eq', value: event_id }] };
|
const search_query: any = {
|
||||||
|
q: '',
|
||||||
|
and: [{ field: 'event_id', op: 'eq', value: event_id }]
|
||||||
|
};
|
||||||
const params: key_val = {};
|
const params: key_val = {};
|
||||||
if (fulltext_search_qry_str && fulltext_search_qry_str.length > 2) params['ft_qry'] = { 'default_qry_str': fulltext_search_qry_str };
|
if (fulltext_search_qry_str && fulltext_search_qry_str.length > 2)
|
||||||
if (like_search_qry_str) params['lk_qry'] = { 'default_qry_str': like_search_qry_str };
|
params['ft_qry'] = { default_qry_str: fulltext_search_qry_str };
|
||||||
if (enabled === 'enabled') search_query.and.push({ field: 'enable', op: 'eq', value: 1 });
|
if (like_search_qry_str)
|
||||||
else if (enabled === 'not_enabled') search_query.and.push({ field: 'enable', op: 'eq', value: 0 });
|
params['lk_qry'] = { default_qry_str: like_search_qry_str };
|
||||||
if (hidden === 'hidden') search_query.and.push({ field: 'hide', op: 'eq', value: 1 });
|
if (enabled === 'enabled')
|
||||||
else if (hidden === 'not_hidden') search_query.and.push({ field: 'hide', op: 'eq', value: 0 });
|
search_query.and.push({ field: 'enable', op: 'eq', value: 1 });
|
||||||
|
else if (enabled === 'not_enabled')
|
||||||
|
search_query.and.push({ field: 'enable', op: 'eq', value: 0 });
|
||||||
|
if (hidden === 'hidden')
|
||||||
|
search_query.and.push({ field: 'hide', op: 'eq', value: 1 });
|
||||||
|
else if (hidden === 'not_hidden')
|
||||||
|
search_query.and.push({ field: 'hide', op: 'eq', value: 0 });
|
||||||
|
|
||||||
const result_li = await api.search_ae_obj({ api_cfg, obj_type: 'event_presentation', search_query, order_by_li, params, view, limit, offset, log_lvl });
|
const result_li = await api.search_ae_obj({
|
||||||
|
api_cfg,
|
||||||
|
obj_type: 'event_presentation',
|
||||||
|
search_query,
|
||||||
|
order_by_li,
|
||||||
|
params,
|
||||||
|
view,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
if (result_li) {
|
if (result_li) {
|
||||||
const processed = await process_ae_obj__event_presentation_props({ obj_li: result_li, log_lvl });
|
const processed = await process_ae_obj__event_presentation_props({
|
||||||
|
obj_li: result_li,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'presentation', obj_li: processed, properties_to_save, log_lvl });
|
await db_save_ae_obj_li__ae_obj({
|
||||||
|
db_instance: db_events,
|
||||||
|
table_name: 'presentation',
|
||||||
|
obj_li: processed,
|
||||||
|
properties_to_save,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return processed;
|
return processed;
|
||||||
}
|
}
|
||||||
@@ -322,10 +578,53 @@ export async function search__event_presentation({
|
|||||||
export const qry__event_presentation = search__event_presentation;
|
export const qry__event_presentation = search__event_presentation;
|
||||||
|
|
||||||
export const properties_to_save = [
|
export const properties_to_save = [
|
||||||
'id', 'event_presentation_id', 'event_presentation_id_random', 'external_id', 'code', 'for_type', 'for_id', 'for_id_random', 'type_code', 'event_id', 'event_session_id', 'event_abstract_id', 'event_id_random', 'event_session_id_random', 'event_abstract_id_random', 'abstract_code', 'name', 'description', 'start_datetime', 'end_datetime', 'passcode', 'hide_event_launcher', 'enable', 'hide', 'priority', 'sort', 'group', 'notes', 'created_on', 'updated_on', 'tmp_sort_1', 'tmp_sort_2', 'event_session_code', 'event_session_name'
|
'id',
|
||||||
|
'event_presentation_id',
|
||||||
|
'event_presentation_id_random',
|
||||||
|
'external_id',
|
||||||
|
'code',
|
||||||
|
'for_type',
|
||||||
|
'for_id',
|
||||||
|
'for_id_random',
|
||||||
|
'type_code',
|
||||||
|
'event_id',
|
||||||
|
'event_session_id',
|
||||||
|
'event_abstract_id',
|
||||||
|
'event_id_random',
|
||||||
|
'event_session_id_random',
|
||||||
|
'event_abstract_id_random',
|
||||||
|
'abstract_code',
|
||||||
|
'name',
|
||||||
|
'description',
|
||||||
|
'start_datetime',
|
||||||
|
'end_datetime',
|
||||||
|
'passcode',
|
||||||
|
'hide_event_launcher',
|
||||||
|
'enable',
|
||||||
|
'hide',
|
||||||
|
'priority',
|
||||||
|
'sort',
|
||||||
|
'group',
|
||||||
|
'notes',
|
||||||
|
'created_on',
|
||||||
|
'updated_on',
|
||||||
|
'tmp_sort_1',
|
||||||
|
'tmp_sort_2',
|
||||||
|
'event_session_code',
|
||||||
|
'event_session_name'
|
||||||
];
|
];
|
||||||
|
|
||||||
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[]> {
|
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 [];
|
if (!obj_li || obj_li.length === 0) return [];
|
||||||
const processed_obj_li: T[] = [];
|
const processed_obj_li: T[] = [];
|
||||||
for (const original_obj of obj_li) {
|
for (const original_obj of obj_li) {
|
||||||
@@ -338,26 +637,48 @@ async function _process_generic_props<T extends Record<string, any>>({ obj_li, o
|
|||||||
}
|
}
|
||||||
const randomIdKey = `${obj_type}_id_random`;
|
const randomIdKey = `${obj_type}_id_random`;
|
||||||
const baseIdKey = `${obj_type}_id`;
|
const baseIdKey = `${obj_type}_id`;
|
||||||
if (processed_obj[randomIdKey]) (processed_obj as any).id = processed_obj[randomIdKey];
|
if (processed_obj[randomIdKey])
|
||||||
else if (processed_obj[baseIdKey]) (processed_obj as any).id = processed_obj[baseIdKey];
|
(processed_obj as any).id = processed_obj[randomIdKey];
|
||||||
|
else if (processed_obj[baseIdKey])
|
||||||
|
(processed_obj as any).id = processed_obj[baseIdKey];
|
||||||
const group = processed_obj.group ?? '0';
|
const group = processed_obj.group ?? '0';
|
||||||
const priority = processed_obj.priority ? 1 : 0;
|
const priority = processed_obj.priority ? 1 : 0;
|
||||||
const sort = processed_obj.sort ?? '0';
|
const sort = processed_obj.sort ?? '0';
|
||||||
const updated = processed_obj.updated_on ?? processed_obj.created_on ?? new Date(0).toISOString();
|
const updated =
|
||||||
|
processed_obj.updated_on ??
|
||||||
|
processed_obj.created_on ??
|
||||||
|
new Date(0).toISOString();
|
||||||
const name = processed_obj.name ?? '';
|
const name = processed_obj.name ?? '';
|
||||||
(processed_obj as any).tmp_sort_1 = `${group}_${priority}_${sort}_${updated}`;
|
(processed_obj as any).tmp_sort_1 =
|
||||||
(processed_obj as any).tmp_sort_2 = `${group}_${priority}_${sort}_${name}_${updated}`;
|
`${group}_${priority}_${sort}_${updated}`;
|
||||||
if (specific_processor) processed_obj = await Promise.resolve(specific_processor(processed_obj));
|
(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);
|
processed_obj_li.push(processed_obj as T);
|
||||||
}
|
}
|
||||||
return processed_obj_li;
|
return processed_obj_li;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function process_ae_obj__event_presentation_props({ obj_li, log_lvl = 0 }: { obj_li: any[]; log_lvl?: number; }) {
|
export async function process_ae_obj__event_presentation_props({
|
||||||
return _process_generic_props({ obj_li, obj_type: 'event_presentation', log_lvl, specific_processor: (obj) => {
|
obj_li,
|
||||||
// Ensure linking IDs are the string versions for indexing
|
log_lvl = 0
|
||||||
if (obj.event_session_id_random) obj.event_session_id = obj.event_session_id_random;
|
}: {
|
||||||
if (obj.event_id_random) obj.event_id = obj.event_id_random;
|
obj_li: any[];
|
||||||
return obj;
|
log_lvl?: number;
|
||||||
}});
|
}) {
|
||||||
|
return _process_generic_props({
|
||||||
|
obj_li,
|
||||||
|
obj_type: 'event_presentation',
|
||||||
|
log_lvl,
|
||||||
|
specific_processor: (obj) => {
|
||||||
|
// Ensure linking IDs are the string versions for indexing
|
||||||
|
if (obj.event_session_id_random)
|
||||||
|
obj.event_session_id = obj.event_session_id_random;
|
||||||
|
if (obj.event_id_random) obj.event_id = obj.event_id_random;
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
@@ -29,7 +29,9 @@ export async function load_ae_obj_id__event_presenter({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_EventPresenter | null> {
|
}): Promise<ae_EventPresenter | null> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** load_ae_obj_id__event_presenter() *** [V3] id=${event_presenter_id} (SWR)`);
|
console.log(
|
||||||
|
`*** load_ae_obj_id__event_presenter() *** [V3] id=${event_presenter_id} (SWR)`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. FAST PATH: Cache hit
|
// 1. FAST PATH: Cache hit
|
||||||
@@ -38,30 +40,71 @@ export async function load_ae_obj_id__event_presenter({
|
|||||||
const cached = await db_events.presenter.get(event_presenter_id);
|
const cached = await db_events.presenter.get(event_presenter_id);
|
||||||
if (cached) {
|
if (cached) {
|
||||||
// Background refresh (non-blocking)
|
// Background refresh (non-blocking)
|
||||||
_refresh_presenter_id_background({ api_cfg, event_presenter_id, view, try_cache, inc_file_li, log_lvl: 0 });
|
_refresh_presenter_id_background({
|
||||||
|
api_cfg,
|
||||||
|
event_presenter_id,
|
||||||
|
view,
|
||||||
|
try_cache,
|
||||||
|
inc_file_li,
|
||||||
|
log_lvl: 0
|
||||||
|
});
|
||||||
return cached;
|
return cached;
|
||||||
}
|
}
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. SLOW PATH: Wait for API
|
// 2. SLOW PATH: Wait for API
|
||||||
return await _refresh_presenter_id_background({ api_cfg, event_presenter_id, view, try_cache, inc_file_li, log_lvl });
|
return await _refresh_presenter_id_background({
|
||||||
|
api_cfg,
|
||||||
|
event_presenter_id,
|
||||||
|
view,
|
||||||
|
try_cache,
|
||||||
|
inc_file_li,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function _refresh_presenter_id_background({ api_cfg, event_presenter_id, view, try_cache, inc_file_li, log_lvl }: any) {
|
async function _refresh_presenter_id_background({
|
||||||
|
api_cfg,
|
||||||
|
event_presenter_id,
|
||||||
|
view,
|
||||||
|
try_cache,
|
||||||
|
inc_file_li,
|
||||||
|
log_lvl
|
||||||
|
}: any) {
|
||||||
if (typeof navigator !== 'undefined' && !navigator.onLine) return null;
|
if (typeof navigator !== 'undefined' && !navigator.onLine) return null;
|
||||||
try {
|
try {
|
||||||
const result = await api.get_ae_obj({ api_cfg, obj_type: 'event_presenter', obj_id: event_presenter_id, view, log_lvl });
|
const result = await api.get_ae_obj({
|
||||||
|
api_cfg,
|
||||||
|
obj_type: 'event_presenter',
|
||||||
|
obj_id: event_presenter_id,
|
||||||
|
view,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
if (result) {
|
if (result) {
|
||||||
const processed = await process_ae_obj__event_presenter_props({ obj_li: [result], log_lvl });
|
const processed = await process_ae_obj__event_presenter_props({
|
||||||
|
obj_li: [result],
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
const processed_obj = processed[0];
|
const processed_obj = processed[0];
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'presenter', obj_li: [processed_obj], properties_to_save, log_lvl });
|
await db_save_ae_obj_li__ae_obj({
|
||||||
|
db_instance: db_events,
|
||||||
|
table_name: 'presenter',
|
||||||
|
obj_li: [processed_obj],
|
||||||
|
properties_to_save,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (inc_file_li) {
|
if (inc_file_li) {
|
||||||
processed_obj.event_file_li = await load_ae_obj_li__event_file({
|
processed_obj.event_file_li = await load_ae_obj_li__event_file({
|
||||||
api_cfg, for_obj_type: 'event_presenter', for_obj_id: event_presenter_id,
|
api_cfg,
|
||||||
enabled: 'all', limit: 25, try_cache: false, log_lvl
|
for_obj_type: 'event_presenter',
|
||||||
|
for_obj_id: event_presenter_id,
|
||||||
|
enabled: 'all',
|
||||||
|
limit: 25,
|
||||||
|
try_cache: false,
|
||||||
|
log_lvl
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return processed_obj;
|
return processed_obj;
|
||||||
@@ -104,7 +147,9 @@ export async function load_ae_obj_li__event_presenter({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_EventPresenter[]> {
|
}): Promise<ae_EventPresenter[]> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** load_ae_obj_li__event_presenter() *** [V3] for=${for_obj_type}:${for_obj_id} (SWR)`);
|
console.log(
|
||||||
|
`*** load_ae_obj_li__event_presenter() *** [V3] for=${for_obj_type}:${for_obj_id} (SWR)`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. FAST PATH: Check cache using specific indices
|
// 1. FAST PATH: Check cache using specific indices
|
||||||
@@ -112,31 +157,94 @@ export async function load_ae_obj_li__event_presenter({
|
|||||||
try {
|
try {
|
||||||
let cached_li: any[] = [];
|
let cached_li: any[] = [];
|
||||||
if (for_obj_type === 'event_presentation') {
|
if (for_obj_type === 'event_presentation') {
|
||||||
cached_li = await db_events.presenter.where('event_presentation_id').equals(for_obj_id).toArray();
|
cached_li = await db_events.presenter
|
||||||
|
.where('event_presentation_id')
|
||||||
|
.equals(for_obj_id)
|
||||||
|
.toArray();
|
||||||
} else if (for_obj_type === 'event_session') {
|
} else if (for_obj_type === 'event_session') {
|
||||||
cached_li = await db_events.presenter.where('event_session_id').equals(for_obj_id).toArray();
|
cached_li = await db_events.presenter
|
||||||
|
.where('event_session_id')
|
||||||
|
.equals(for_obj_id)
|
||||||
|
.toArray();
|
||||||
} else if (for_obj_type === 'event') {
|
} else if (for_obj_type === 'event') {
|
||||||
cached_li = await db_events.presenter.where('event_id').equals(for_obj_id).toArray();
|
cached_li = await db_events.presenter
|
||||||
|
.where('event_id')
|
||||||
|
.equals(for_obj_id)
|
||||||
|
.toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cached_li && cached_li.length > 0) {
|
if (cached_li && cached_li.length > 0) {
|
||||||
// Background refresh (non-blocking)
|
// Background refresh (non-blocking)
|
||||||
_refresh_presenter_li_background({ api_cfg, for_obj_type, for_obj_id, inc_file_li, enabled, hidden, view, limit, offset, order_by_li, try_cache, log_lvl: 0 });
|
_refresh_presenter_li_background({
|
||||||
|
api_cfg,
|
||||||
|
for_obj_type,
|
||||||
|
for_obj_id,
|
||||||
|
inc_file_li,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
view,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
order_by_li,
|
||||||
|
try_cache,
|
||||||
|
log_lvl: 0
|
||||||
|
});
|
||||||
return cached_li;
|
return cached_li;
|
||||||
}
|
}
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. SLOW PATH: Wait for API
|
// 2. SLOW PATH: Wait for API
|
||||||
return await _refresh_presenter_li_background({ api_cfg, for_obj_type, for_obj_id, inc_file_li, enabled, hidden, view, limit, offset, order_by_li, try_cache, log_lvl });
|
return await _refresh_presenter_li_background({
|
||||||
|
api_cfg,
|
||||||
|
for_obj_type,
|
||||||
|
for_obj_id,
|
||||||
|
inc_file_li,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
view,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
order_by_li,
|
||||||
|
try_cache,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function _refresh_presenter_li_background({ api_cfg, for_obj_type, for_obj_id, inc_file_li, enabled, hidden, view, limit, offset, order_by_li, try_cache, log_lvl }: any) {
|
async function _refresh_presenter_li_background({
|
||||||
|
api_cfg,
|
||||||
|
for_obj_type,
|
||||||
|
for_obj_id,
|
||||||
|
inc_file_li,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
view,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
order_by_li,
|
||||||
|
try_cache,
|
||||||
|
log_lvl
|
||||||
|
}: any) {
|
||||||
if (typeof navigator !== 'undefined' && !navigator.onLine) return [];
|
if (typeof navigator !== 'undefined' && !navigator.onLine) return [];
|
||||||
try {
|
try {
|
||||||
const result_li = await api.get_ae_obj_li({ api_cfg, obj_type: 'event_presenter', for_obj_type, for_obj_id, enabled, hidden, view, limit, offset, order_by_li, log_lvl });
|
const result_li = await api.get_ae_obj_li({
|
||||||
|
api_cfg,
|
||||||
|
obj_type: 'event_presenter',
|
||||||
|
for_obj_type,
|
||||||
|
for_obj_id,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
view,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
order_by_li,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
if (result_li) {
|
if (result_li) {
|
||||||
const processed = await process_ae_obj__event_presenter_props({ obj_li: result_li, log_lvl });
|
const processed = await process_ae_obj__event_presenter_props({
|
||||||
|
obj_li: result_li,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
|
|
||||||
// String-Only ID Vision: Ensure linking ID is set for indexing
|
// String-Only ID Vision: Ensure linking ID is set for indexing
|
||||||
processed.forEach((p) => {
|
processed.forEach((p) => {
|
||||||
@@ -155,7 +263,13 @@ async function _refresh_presenter_li_background({ api_cfg, for_obj_type, for_obj
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'presenter', obj_li: processed, properties_to_save, log_lvl });
|
await db_save_ae_obj_li__ae_obj({
|
||||||
|
db_instance: db_events,
|
||||||
|
table_name: 'presenter',
|
||||||
|
obj_li: processed,
|
||||||
|
properties_to_save,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
// CRITICAL FIX (2026-02-26): Yield to microtask queue so Dexie liveQuery observers
|
// CRITICAL FIX (2026-02-26): Yield to microtask queue so Dexie liveQuery observers
|
||||||
// fire before we return. Without this, component-mounted liveQueries may subscribe
|
// fire before we return. Without this, component-mounted liveQueries may subscribe
|
||||||
// to IDB *before* the write completes, causing empty results on cold-start.
|
// to IDB *before* the write completes, causing empty results on cold-start.
|
||||||
@@ -164,10 +278,15 @@ async function _refresh_presenter_li_background({ api_cfg, for_obj_type, for_obj
|
|||||||
|
|
||||||
// Background nested loads for refreshed items (FIRE AND FORGET)
|
// Background nested loads for refreshed items (FIRE AND FORGET)
|
||||||
if (inc_file_li) {
|
if (inc_file_li) {
|
||||||
processed.forEach(p => {
|
processed.forEach((p) => {
|
||||||
load_ae_obj_li__event_file({
|
load_ae_obj_li__event_file({
|
||||||
api_cfg, for_obj_type: 'event_presenter', for_obj_id: p.id,
|
api_cfg,
|
||||||
enabled: 'all', limit: 25, try_cache: false, log_lvl: 0
|
for_obj_type: 'event_presenter',
|
||||||
|
for_obj_id: p.id,
|
||||||
|
enabled: 'all',
|
||||||
|
limit: 25,
|
||||||
|
try_cache: false,
|
||||||
|
log_lvl: 0
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -180,128 +299,143 @@ async function _refresh_presenter_li_background({ api_cfg, for_obj_type, for_obj
|
|||||||
|
|
||||||
// Updated 2026-01-20 to V3
|
// Updated 2026-01-20 to V3
|
||||||
export async function create_ae_obj__event_presenter({
|
export async function create_ae_obj__event_presenter({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
event_presentation_id,
|
event_presentation_id,
|
||||||
data_kv,
|
data_kv,
|
||||||
try_cache = true,
|
try_cache = true,
|
||||||
log_lvl = 0
|
log_lvl = 0
|
||||||
}: {
|
}: {
|
||||||
api_cfg: any;
|
api_cfg: any;
|
||||||
event_presentation_id?: string;
|
event_presentation_id?: string;
|
||||||
data_kv: key_val;
|
data_kv: key_val;
|
||||||
try_cache?: boolean;
|
try_cache?: boolean;
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_EventPresenter | null> {
|
}): Promise<ae_EventPresenter | null> {
|
||||||
if (!event_presentation_id) event_presentation_id = get(events_slct).event_presentation_id;
|
if (!event_presentation_id)
|
||||||
|
event_presentation_id = get(events_slct).event_presentation_id;
|
||||||
if (!event_presentation_id) {
|
if (!event_presentation_id) {
|
||||||
console.error('create_ae_obj__event_presenter: event_presentation_id is required');
|
console.error(
|
||||||
|
'create_ae_obj__event_presenter: event_presentation_id is required'
|
||||||
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const result = await api.create_nested_obj({
|
const result = await api.create_nested_obj({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
for_obj_type: 'event_presentation',
|
for_obj_type: 'event_presentation',
|
||||||
for_obj_id: event_presentation_id,
|
for_obj_id: event_presentation_id,
|
||||||
obj_type: 'event_presenter',
|
obj_type: 'event_presenter',
|
||||||
fields: { ...data_kv },
|
fields: { ...data_kv },
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
const processed = await process_ae_obj__event_presenter_props({ obj_li: [result], log_lvl });
|
const processed = await process_ae_obj__event_presenter_props({
|
||||||
const processed_obj = processed[0];
|
obj_li: [result],
|
||||||
if (try_cache) {
|
log_lvl
|
||||||
await db_save_ae_obj_li__ae_obj({
|
});
|
||||||
db_instance: db_events,
|
const processed_obj = processed[0];
|
||||||
table_name: 'presenter',
|
if (try_cache) {
|
||||||
obj_li: [processed_obj],
|
await db_save_ae_obj_li__ae_obj({
|
||||||
properties_to_save,
|
db_instance: db_events,
|
||||||
log_lvl
|
table_name: 'presenter',
|
||||||
});
|
obj_li: [processed_obj],
|
||||||
}
|
properties_to_save,
|
||||||
return processed_obj;
|
log_lvl
|
||||||
}
|
});
|
||||||
return null;
|
}
|
||||||
|
return processed_obj;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updated 2026-01-20 to V3
|
// Updated 2026-01-20 to V3
|
||||||
export async function delete_ae_obj_id__event_presenter({
|
export async function delete_ae_obj_id__event_presenter({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
event_presentation_id,
|
event_presentation_id,
|
||||||
event_presenter_id,
|
event_presenter_id,
|
||||||
method = 'delete',
|
method = 'delete',
|
||||||
try_cache = true,
|
try_cache = true,
|
||||||
log_lvl = 0
|
log_lvl = 0
|
||||||
}: {
|
}: {
|
||||||
api_cfg: any;
|
api_cfg: any;
|
||||||
event_presentation_id?: string;
|
event_presentation_id?: string;
|
||||||
event_presenter_id: string;
|
event_presenter_id: string;
|
||||||
method?: 'delete' | 'soft_delete' | 'disable' | 'hide';
|
method?: 'delete' | 'soft_delete' | 'disable' | 'hide';
|
||||||
try_cache?: boolean;
|
try_cache?: boolean;
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}) {
|
}) {
|
||||||
if (!event_presentation_id) event_presentation_id = get(events_slct).event_presentation_id;
|
if (!event_presentation_id)
|
||||||
|
event_presentation_id = get(events_slct).event_presentation_id;
|
||||||
if (!event_presentation_id) {
|
if (!event_presentation_id) {
|
||||||
console.error('delete_ae_obj_id__event_presenter: event_presentation_id is required');
|
console.error(
|
||||||
|
'delete_ae_obj_id__event_presenter: event_presentation_id is required'
|
||||||
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const result = await api.delete_nested_ae_obj({
|
const result = await api.delete_nested_ae_obj({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
for_obj_type: 'event_presentation',
|
for_obj_type: 'event_presentation',
|
||||||
for_obj_id: event_presentation_id,
|
for_obj_id: event_presentation_id,
|
||||||
obj_type: 'event_presenter',
|
obj_type: 'event_presenter',
|
||||||
obj_id: event_presenter_id,
|
obj_id: event_presenter_id,
|
||||||
method,
|
method,
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
if (try_cache) await db_events.presenter.delete(event_presenter_id);
|
if (try_cache) await db_events.presenter.delete(event_presenter_id);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updated 2026-01-20 to V3
|
// Updated 2026-01-20 to V3
|
||||||
export async function update_ae_obj__event_presenter({
|
export async function update_ae_obj__event_presenter({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
event_presentation_id,
|
event_presentation_id,
|
||||||
event_presenter_id,
|
event_presenter_id,
|
||||||
data_kv,
|
data_kv,
|
||||||
try_cache = true,
|
try_cache = true,
|
||||||
log_lvl = 0
|
log_lvl = 0
|
||||||
}: {
|
}: {
|
||||||
api_cfg: any;
|
api_cfg: any;
|
||||||
event_presentation_id?: string;
|
event_presentation_id?: string;
|
||||||
event_presenter_id: string;
|
event_presenter_id: string;
|
||||||
data_kv: key_val;
|
data_kv: key_val;
|
||||||
try_cache?: boolean;
|
try_cache?: boolean;
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_EventPresenter | null> {
|
}): Promise<ae_EventPresenter | null> {
|
||||||
if (!event_presentation_id) event_presentation_id = get(events_slct).event_presentation_id;
|
if (!event_presentation_id)
|
||||||
|
event_presentation_id = get(events_slct).event_presentation_id;
|
||||||
if (!event_presentation_id) {
|
if (!event_presentation_id) {
|
||||||
console.error('update_ae_obj__event_presenter: event_presentation_id is required');
|
console.error(
|
||||||
|
'update_ae_obj__event_presenter: event_presentation_id is required'
|
||||||
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const result = await api.update_nested_obj({
|
const result = await api.update_nested_obj({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
for_obj_type: 'event_presentation',
|
for_obj_type: 'event_presentation',
|
||||||
for_obj_id: event_presentation_id,
|
for_obj_id: event_presentation_id,
|
||||||
obj_type: 'event_presenter',
|
obj_type: 'event_presenter',
|
||||||
obj_id: event_presenter_id,
|
obj_id: event_presenter_id,
|
||||||
fields: data_kv,
|
fields: data_kv,
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
if (result) {
|
if (result) {
|
||||||
const processed = await process_ae_obj__event_presenter_props({ obj_li: [result], log_lvl });
|
const processed = await process_ae_obj__event_presenter_props({
|
||||||
const processed_obj = processed[0];
|
obj_li: [result],
|
||||||
if (try_cache) {
|
log_lvl
|
||||||
await db_save_ae_obj_li__ae_obj({
|
});
|
||||||
db_instance: db_events,
|
const processed_obj = processed[0];
|
||||||
table_name: 'presenter',
|
if (try_cache) {
|
||||||
obj_li: [processed_obj],
|
await db_save_ae_obj_li__ae_obj({
|
||||||
properties_to_save,
|
db_instance: db_events,
|
||||||
log_lvl
|
table_name: 'presenter',
|
||||||
});
|
obj_li: [processed_obj],
|
||||||
}
|
properties_to_save,
|
||||||
return processed_obj;
|
log_lvl
|
||||||
}
|
});
|
||||||
return null;
|
}
|
||||||
|
return processed_obj;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updated 2026-01-21 to Restore Full Aether Search Logic
|
// Updated 2026-01-21 to Restore Full Aether Search Logic
|
||||||
@@ -320,7 +454,11 @@ export async function search__event_presenter({
|
|||||||
view = 'default',
|
view = 'default',
|
||||||
limit = 25,
|
limit = 25,
|
||||||
offset = 0,
|
offset = 0,
|
||||||
order_by_li = [{ sort: 'ASC' }, { given_name: 'ASC' }, { family_name: 'ASC' }],
|
order_by_li = [
|
||||||
|
{ sort: 'ASC' },
|
||||||
|
{ given_name: 'ASC' },
|
||||||
|
{ family_name: 'ASC' }
|
||||||
|
],
|
||||||
try_cache = true,
|
try_cache = true,
|
||||||
log_lvl = 0
|
log_lvl = 0
|
||||||
}: {
|
}: {
|
||||||
@@ -342,29 +480,71 @@ export async function search__event_presenter({
|
|||||||
try_cache?: boolean;
|
try_cache?: boolean;
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_EventPresenter[]> {
|
}): Promise<ae_EventPresenter[]> {
|
||||||
const search_query: any = { q: '', and: [{ field: 'event_id', op: 'eq', value: event_id }] };
|
const search_query: any = {
|
||||||
|
q: '',
|
||||||
|
and: [{ field: 'event_id', op: 'eq', value: event_id }]
|
||||||
|
};
|
||||||
const params: key_val = {};
|
const params: key_val = {};
|
||||||
if (fulltext_search_qry_str && fulltext_search_qry_str.length > 2)
|
if (fulltext_search_qry_str && fulltext_search_qry_str.length > 2)
|
||||||
params['ft_qry'] = { default_qry_str: fulltext_search_qry_str };
|
params['ft_qry'] = { default_qry_str: fulltext_search_qry_str };
|
||||||
if (ft_presenter_search_qry_str && ft_presenter_search_qry_str.length > 2)
|
if (ft_presenter_search_qry_str && ft_presenter_search_qry_str.length > 2)
|
||||||
params['ft_qry'] = { ...params['ft_qry'], event_presenter_li_qry_str: ft_presenter_search_qry_str };
|
params['ft_qry'] = {
|
||||||
if (like_search_qry_str) params['lk_qry'] = { default_qry_str: like_search_qry_str };
|
...params['ft_qry'],
|
||||||
|
event_presenter_li_qry_str: ft_presenter_search_qry_str
|
||||||
|
};
|
||||||
|
if (like_search_qry_str)
|
||||||
|
params['lk_qry'] = { default_qry_str: like_search_qry_str };
|
||||||
if (like_presentation_search_qry_str)
|
if (like_presentation_search_qry_str)
|
||||||
params['lk_qry'] = { ...params['lk_qry'], event_presentation_li_qry_str: like_presentation_search_qry_str };
|
params['lk_qry'] = {
|
||||||
|
...params['lk_qry'],
|
||||||
|
event_presentation_li_qry_str: like_presentation_search_qry_str
|
||||||
|
};
|
||||||
if (like_presenter_search_qry_str)
|
if (like_presenter_search_qry_str)
|
||||||
params['lk_qry'] = { ...params['lk_qry'], event_presenter_li_qry_str: like_presenter_search_qry_str };
|
params['lk_qry'] = {
|
||||||
if (agree !== null) search_query.and.push({ field: 'agree', op: 'eq', value: agree ? 1 : 0 });
|
...params['lk_qry'],
|
||||||
if (biography === true) search_query.and.push({ field: 'biography', op: 'ne', value: '' });
|
event_presenter_li_qry_str: like_presenter_search_qry_str
|
||||||
if (enabled === 'enabled') search_query.and.push({ field: 'enable', op: 'eq', value: 1 });
|
};
|
||||||
else if (enabled === 'not_enabled') search_query.and.push({ field: 'enable', op: 'eq', value: 0 });
|
if (agree !== null)
|
||||||
if (hidden === 'hidden') search_query.and.push({ field: 'hide', op: 'eq', value: 1 });
|
search_query.and.push({
|
||||||
else if (hidden === 'not_hidden') search_query.and.push({ field: 'hide', op: 'eq', value: 0 });
|
field: 'agree',
|
||||||
|
op: 'eq',
|
||||||
|
value: agree ? 1 : 0
|
||||||
|
});
|
||||||
|
if (biography === true)
|
||||||
|
search_query.and.push({ field: 'biography', op: 'ne', value: '' });
|
||||||
|
if (enabled === 'enabled')
|
||||||
|
search_query.and.push({ field: 'enable', op: 'eq', value: 1 });
|
||||||
|
else if (enabled === 'not_enabled')
|
||||||
|
search_query.and.push({ field: 'enable', op: 'eq', value: 0 });
|
||||||
|
if (hidden === 'hidden')
|
||||||
|
search_query.and.push({ field: 'hide', op: 'eq', value: 1 });
|
||||||
|
else if (hidden === 'not_hidden')
|
||||||
|
search_query.and.push({ field: 'hide', op: 'eq', value: 0 });
|
||||||
|
|
||||||
const result_li = await api.search_ae_obj({ api_cfg, obj_type: 'event_presenter', search_query, order_by_li, params, view, limit, offset, log_lvl });
|
const result_li = await api.search_ae_obj({
|
||||||
|
api_cfg,
|
||||||
|
obj_type: 'event_presenter',
|
||||||
|
search_query,
|
||||||
|
order_by_li,
|
||||||
|
params,
|
||||||
|
view,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
if (result_li) {
|
if (result_li) {
|
||||||
const processed = await process_ae_obj__event_presenter_props({ obj_li: result_li, log_lvl });
|
const processed = await process_ae_obj__event_presenter_props({
|
||||||
|
obj_li: result_li,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'presenter', obj_li: processed, properties_to_save, log_lvl });
|
await db_save_ae_obj_li__ae_obj({
|
||||||
|
db_instance: db_events,
|
||||||
|
table_name: 'presenter',
|
||||||
|
obj_li: processed,
|
||||||
|
properties_to_save,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return processed;
|
return processed;
|
||||||
}
|
}
|
||||||
@@ -400,8 +580,16 @@ export async function email_sign_in__event_presenter({
|
|||||||
session_name?: string | null;
|
session_name?: string | null;
|
||||||
presentation_name?: string | null;
|
presentation_name?: string | null;
|
||||||
}) {
|
}) {
|
||||||
if (!to_email || !person_id || !person_passcode || !event_id || !event_presenter_id) {
|
if (
|
||||||
console.error('Missing required parameters for email_sign_in__event_presenter');
|
!to_email ||
|
||||||
|
!person_id ||
|
||||||
|
!person_passcode ||
|
||||||
|
!event_id ||
|
||||||
|
!event_presenter_id
|
||||||
|
) {
|
||||||
|
console.error(
|
||||||
|
'Missing required parameters for email_sign_in__event_presenter'
|
||||||
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const subject = `Pres Mgmt Hub Sign In Link for Presenter: ${to_name ?? 'Presenter'}`;
|
const subject = `Pres Mgmt Hub Sign In Link for Presenter: ${to_name ?? 'Presenter'}`;
|
||||||
@@ -420,10 +608,75 @@ export async function email_sign_in__event_presenter({
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const properties_to_save = [
|
export const properties_to_save = [
|
||||||
'id', 'event_presenter_id', 'event_presenter_id_random', 'external_id', 'code', 'event_id', 'event_session_id', 'event_presentation_id', 'event_person_id', 'person_id', 'person_profile_id', 'person_id_random', 'person_profile_id_random', 'pronouns', 'informal_name', 'title_names', 'given_name', 'middle_name', 'family_name', 'designations', 'professional_title', 'full_name', 'affiliations', 'email', 'biography', 'agree', 'comments', 'passcode', 'hide_event_launcher', 'data_json', 'enable', 'hide', 'priority', 'sort', 'group', 'notes', 'created_on', 'updated_on', 'tmp_sort_1', 'tmp_sort_2', 'file_count', 'event_session_code', 'event_session_name', 'event_session_start_datetime', 'event_presentation_code', 'event_presentation_name', 'event_presentation_start_datetime', 'person_external_id', 'person_external_sys_id', 'person_given_name', 'person_family_name', 'person_full_name', 'person_professional_title', 'person_affiliations', 'person_primary_email', 'person_passcode'
|
'id',
|
||||||
|
'event_presenter_id',
|
||||||
|
'event_presenter_id_random',
|
||||||
|
'external_id',
|
||||||
|
'code',
|
||||||
|
'event_id',
|
||||||
|
'event_session_id',
|
||||||
|
'event_presentation_id',
|
||||||
|
'event_person_id',
|
||||||
|
'person_id',
|
||||||
|
'person_profile_id',
|
||||||
|
'person_id_random',
|
||||||
|
'person_profile_id_random',
|
||||||
|
'pronouns',
|
||||||
|
'informal_name',
|
||||||
|
'title_names',
|
||||||
|
'given_name',
|
||||||
|
'middle_name',
|
||||||
|
'family_name',
|
||||||
|
'designations',
|
||||||
|
'professional_title',
|
||||||
|
'full_name',
|
||||||
|
'affiliations',
|
||||||
|
'email',
|
||||||
|
'biography',
|
||||||
|
'agree',
|
||||||
|
'comments',
|
||||||
|
'passcode',
|
||||||
|
'hide_event_launcher',
|
||||||
|
'data_json',
|
||||||
|
'enable',
|
||||||
|
'hide',
|
||||||
|
'priority',
|
||||||
|
'sort',
|
||||||
|
'group',
|
||||||
|
'notes',
|
||||||
|
'created_on',
|
||||||
|
'updated_on',
|
||||||
|
'tmp_sort_1',
|
||||||
|
'tmp_sort_2',
|
||||||
|
'file_count',
|
||||||
|
'event_session_code',
|
||||||
|
'event_session_name',
|
||||||
|
'event_session_start_datetime',
|
||||||
|
'event_presentation_code',
|
||||||
|
'event_presentation_name',
|
||||||
|
'event_presentation_start_datetime',
|
||||||
|
'person_external_id',
|
||||||
|
'person_external_sys_id',
|
||||||
|
'person_given_name',
|
||||||
|
'person_family_name',
|
||||||
|
'person_full_name',
|
||||||
|
'person_professional_title',
|
||||||
|
'person_affiliations',
|
||||||
|
'person_primary_email',
|
||||||
|
'person_passcode'
|
||||||
];
|
];
|
||||||
|
|
||||||
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[]> {
|
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 [];
|
if (!obj_li || obj_li.length === 0) return [];
|
||||||
const processed_obj_li: T[] = [];
|
const processed_obj_li: T[] = [];
|
||||||
for (const original_obj of obj_li) {
|
for (const original_obj of obj_li) {
|
||||||
@@ -439,28 +692,50 @@ async function _process_generic_props<T extends Record<string, any>>({ obj_li, o
|
|||||||
if (processed_obj[randomIdKey]) {
|
if (processed_obj[randomIdKey]) {
|
||||||
(processed_obj as any).id = processed_obj[randomIdKey];
|
(processed_obj as any).id = processed_obj[randomIdKey];
|
||||||
(processed_obj as any)[baseIdKey] = processed_obj[randomIdKey];
|
(processed_obj as any)[baseIdKey] = processed_obj[randomIdKey];
|
||||||
}
|
} else if (processed_obj[baseIdKey])
|
||||||
else if (processed_obj[baseIdKey]) (processed_obj as any).id = processed_obj[baseIdKey];
|
(processed_obj as any).id = processed_obj[baseIdKey];
|
||||||
const group = processed_obj.group ?? '0';
|
const group = processed_obj.group ?? '0';
|
||||||
const priority = processed_obj.priority ? 1 : 0;
|
const priority = processed_obj.priority ? 1 : 0;
|
||||||
const sort = processed_obj.sort ?? '0';
|
const sort = processed_obj.sort ?? '0';
|
||||||
const updated = processed_obj.updated_on ?? processed_obj.created_on ?? new Date(0).toISOString();
|
const updated =
|
||||||
|
processed_obj.updated_on ??
|
||||||
|
processed_obj.created_on ??
|
||||||
|
new Date(0).toISOString();
|
||||||
const name = processed_obj.name ?? '';
|
const name = processed_obj.name ?? '';
|
||||||
(processed_obj as any).tmp_sort_1 = `${group}_${priority}_${sort}_${updated}`;
|
(processed_obj as any).tmp_sort_1 =
|
||||||
(processed_obj as any).tmp_sort_2 = `${group}_${priority}_${sort}_${name}_${updated}`;
|
`${group}_${priority}_${sort}_${updated}`;
|
||||||
if (specific_processor) processed_obj = await Promise.resolve(specific_processor(processed_obj));
|
(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);
|
processed_obj_li.push(processed_obj as T);
|
||||||
}
|
}
|
||||||
return processed_obj_li;
|
return processed_obj_li;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function process_ae_obj__event_presenter_props({ obj_li, log_lvl = 0 }: { obj_li: any[]; log_lvl?: number; }) {
|
export async function process_ae_obj__event_presenter_props({
|
||||||
return _process_generic_props({ obj_li, obj_type: 'event_presenter', log_lvl, specific_processor: (obj) => {
|
obj_li,
|
||||||
// String-Only ID Vision: Ensure linking IDs are the string versions for indexing
|
log_lvl = 0
|
||||||
if (obj.event_presenter_id_random) obj.event_presenter_id = obj.event_presenter_id_random;
|
}: {
|
||||||
if (obj.event_presentation_id_random) obj.event_presentation_id = obj.event_presentation_id_random;
|
obj_li: any[];
|
||||||
if (obj.event_session_id_random) obj.event_session_id = obj.event_session_id_random;
|
log_lvl?: number;
|
||||||
if (obj.event_id_random) obj.event_id = obj.event_id_random;
|
}) {
|
||||||
return obj;
|
return _process_generic_props({
|
||||||
}});
|
obj_li,
|
||||||
|
obj_type: 'event_presenter',
|
||||||
|
log_lvl,
|
||||||
|
specific_processor: (obj) => {
|
||||||
|
// String-Only ID Vision: Ensure linking IDs are the string versions for indexing
|
||||||
|
if (obj.event_presenter_id_random)
|
||||||
|
obj.event_presenter_id = obj.event_presenter_id_random;
|
||||||
|
if (obj.event_presentation_id_random)
|
||||||
|
obj.event_presentation_id = obj.event_presentation_id_random;
|
||||||
|
if (obj.event_session_id_random)
|
||||||
|
obj.event_session_id = obj.event_session_id_random;
|
||||||
|
if (obj.event_id_random) obj.event_id = obj.event_id_random;
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,9 @@ export async function load_ae_obj_id__event_session({
|
|||||||
}): Promise<ae_EventSession | null> {
|
}): Promise<ae_EventSession | null> {
|
||||||
const start_time = performance.now();
|
const start_time = performance.now();
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`🔎 [Trace] load_ae_obj_id__event_session: START (id=${event_session_id}, try_cache=${try_cache})`);
|
console.log(
|
||||||
|
`🔎 [Trace] load_ae_obj_id__event_session: START (id=${event_session_id}, try_cache=${try_cache})`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hierarchy Enforcement: Pulling presenters requires pulling presentations first
|
// Hierarchy Enforcement: Pulling presenters requires pulling presentations first
|
||||||
@@ -56,65 +58,167 @@ export async function load_ae_obj_id__event_session({
|
|||||||
const cached = await db_events.session.get(event_session_id);
|
const cached = await db_events.session.get(event_session_id);
|
||||||
if (cached) {
|
if (cached) {
|
||||||
const elapsed = (performance.now() - start_time).toFixed(2);
|
const elapsed = (performance.now() - start_time).toFixed(2);
|
||||||
if (log_lvl) console.log(`✅ [Trace] load_ae_obj_id: CACHE HIT at ${elapsed}ms. Returning stale shell for id=${event_session_id}`);
|
if (log_lvl)
|
||||||
|
console.log(
|
||||||
|
`✅ [Trace] load_ae_obj_id: CACHE HIT at ${elapsed}ms. Returning stale shell for id=${event_session_id}`
|
||||||
|
);
|
||||||
|
|
||||||
// Background tasks: refresh parent and warm child caches (non-blocking)
|
// Background tasks: refresh parent and warm child caches (non-blocking)
|
||||||
_refresh_session_id_background({
|
_refresh_session_id_background({
|
||||||
api_cfg, event_session_id, view, try_cache,
|
api_cfg,
|
||||||
inc_file_li, inc_all_file_li, inc_presentation_li, inc_presenter_li,
|
event_session_id,
|
||||||
enabled, hidden, limit, offset, log_lvl: log_lvl > 1 ? log_lvl : 0
|
view,
|
||||||
|
try_cache,
|
||||||
|
inc_file_li,
|
||||||
|
inc_all_file_li,
|
||||||
|
inc_presentation_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
log_lvl: log_lvl > 1 ? log_lvl : 0
|
||||||
});
|
});
|
||||||
|
|
||||||
// In SWR mode, we fire child loads in background to warm IDB for the view's LiveQueries
|
// In SWR mode, we fire child loads in background to warm IDB for the view's LiveQueries
|
||||||
_handle_nested_loads(cached, { api_cfg, inc_file_li, inc_all_file_li, inc_presentation_li, inc_presenter_li, enabled, hidden, limit, offset, try_cache, log_lvl: 0 });
|
_handle_nested_loads(cached, {
|
||||||
|
api_cfg,
|
||||||
|
inc_file_li,
|
||||||
|
inc_all_file_li,
|
||||||
|
inc_presentation_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
try_cache,
|
||||||
|
log_lvl: 0
|
||||||
|
});
|
||||||
|
|
||||||
return cached; // Return immediately without awaiting nested loads
|
return cached; // Return immediately without awaiting nested loads
|
||||||
} else if (log_lvl) {
|
} else if (log_lvl) {
|
||||||
console.log(`⏳ [Trace] load_ae_obj_id: CACHE MISS at ${(performance.now() - start_time).toFixed(2)}ms for id=${event_session_id}`);
|
console.log(
|
||||||
|
`⏳ [Trace] load_ae_obj_id: CACHE MISS at ${(performance.now() - start_time).toFixed(2)}ms for id=${event_session_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (log_lvl) console.error(`❌ [Trace] load_ae_obj_id: Cache access error:`, e);
|
if (log_lvl)
|
||||||
|
console.error(
|
||||||
|
`❌ [Trace] load_ae_obj_id: Cache access error:`,
|
||||||
|
e
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. SLOW PATH: Wait for API
|
// 2. SLOW PATH: Wait for API
|
||||||
if (log_lvl) console.log(`🚀 [Trace] load_ae_obj_id: Proceeding to API path for id=${event_session_id}`);
|
if (log_lvl)
|
||||||
return await _refresh_session_id_background({ api_cfg, event_session_id, view, try_cache, inc_file_li, inc_all_file_li, inc_presentation_li, inc_presenter_li, enabled, hidden, limit, offset, log_lvl });
|
console.log(
|
||||||
|
`🚀 [Trace] load_ae_obj_id: Proceeding to API path for id=${event_session_id}`
|
||||||
|
);
|
||||||
|
return await _refresh_session_id_background({
|
||||||
|
api_cfg,
|
||||||
|
event_session_id,
|
||||||
|
view,
|
||||||
|
try_cache,
|
||||||
|
inc_file_li,
|
||||||
|
inc_all_file_li,
|
||||||
|
inc_presentation_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal background refresh for a single session
|
* Internal background refresh for a single session
|
||||||
*/
|
*/
|
||||||
async function _refresh_session_id_background({ api_cfg, event_session_id, view, try_cache, inc_file_li, inc_all_file_li, inc_presentation_li, inc_presenter_li, enabled, hidden, limit, offset, log_lvl }: any) {
|
async function _refresh_session_id_background({
|
||||||
|
api_cfg,
|
||||||
|
event_session_id,
|
||||||
|
view,
|
||||||
|
try_cache,
|
||||||
|
inc_file_li,
|
||||||
|
inc_all_file_li,
|
||||||
|
inc_presentation_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
log_lvl
|
||||||
|
}: any) {
|
||||||
const start_time = performance.now();
|
const start_time = performance.now();
|
||||||
if (typeof navigator !== 'undefined' && !navigator.onLine) return null;
|
if (typeof navigator !== 'undefined' && !navigator.onLine) return null;
|
||||||
try {
|
try {
|
||||||
if (log_lvl) console.log(`📡 [Trace] _refresh_session_id: API Fetching id=${event_session_id}`);
|
if (log_lvl)
|
||||||
const result = await api.get_ae_obj({ api_cfg, obj_type: 'event_session', obj_id: event_session_id, view, log_lvl });
|
console.log(
|
||||||
|
`📡 [Trace] _refresh_session_id: API Fetching id=${event_session_id}`
|
||||||
|
);
|
||||||
|
const result = await api.get_ae_obj({
|
||||||
|
api_cfg,
|
||||||
|
obj_type: 'event_session',
|
||||||
|
obj_id: event_session_id,
|
||||||
|
view,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
const processed = await process_ae_obj__event_session_props({ obj_li: [result], log_lvl });
|
const processed = await process_ae_obj__event_session_props({
|
||||||
|
obj_li: [result],
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
const processed_obj = processed[0];
|
const processed_obj = processed[0];
|
||||||
const elapsed = (performance.now() - start_time).toFixed(2);
|
const elapsed = (performance.now() - start_time).toFixed(2);
|
||||||
|
|
||||||
if (log_lvl) console.log(`📦 [Trace] _refresh_session_id: Received from API at ${elapsed}ms (id=${processed_obj.id})`);
|
if (log_lvl)
|
||||||
|
console.log(
|
||||||
|
`📦 [Trace] _refresh_session_id: Received from API at ${elapsed}ms (id=${processed_obj.id})`
|
||||||
|
);
|
||||||
|
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'session', obj_li: [processed_obj], properties_to_save, log_lvl });
|
await db_save_ae_obj_li__ae_obj({
|
||||||
|
db_instance: db_events,
|
||||||
|
table_name: 'session',
|
||||||
|
obj_li: [processed_obj],
|
||||||
|
properties_to_save,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
// CRITICAL FIX (2026-02-26): Yield to microtask queue so Dexie liveQuery observers
|
// CRITICAL FIX (2026-02-26): Yield to microtask queue so Dexie liveQuery observers
|
||||||
// fire before we return. Without this, component-mounted liveQueries may subscribe
|
// fire before we return. Without this, component-mounted liveQueries may subscribe
|
||||||
// to IDB *before* the write completes, causing empty results on cold-start.
|
// to IDB *before* the write completes, causing empty results on cold-start.
|
||||||
await Promise.resolve();
|
await Promise.resolve();
|
||||||
if (log_lvl) console.log(`💾 [Trace] _refresh_session_id: Saved to IDB cache.`);
|
if (log_lvl)
|
||||||
|
console.log(
|
||||||
|
`💾 [Trace] _refresh_session_id: Saved to IDB cache.`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
// CRITICAL FIX (2026-02-26): Preserve parent's try_cache value when loading nested data.
|
// CRITICAL FIX (2026-02-26): Preserve parent's try_cache value when loading nested data.
|
||||||
// Previously set to `false`, which meant presentations/presenters were fetched from API
|
// Previously set to `false`, which meant presentations/presenters were fetched from API
|
||||||
// but NEVER written to IndexedDB, causing "refresh twice" bug on cold-start.
|
// but NEVER written to IndexedDB, causing "refresh twice" bug on cold-start.
|
||||||
// Now nested loads inherit parent's caching behavior for deterministic first-render.
|
// Now nested loads inherit parent's caching behavior for deterministic first-render.
|
||||||
return await _handle_nested_loads(processed_obj, { api_cfg, inc_file_li, inc_all_file_li, inc_presentation_li, inc_presenter_li, enabled, hidden, limit, offset, try_cache, log_lvl });
|
return await _handle_nested_loads(processed_obj, {
|
||||||
|
api_cfg,
|
||||||
|
inc_file_li,
|
||||||
|
inc_all_file_li,
|
||||||
|
inc_presentation_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
try_cache,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (log_lvl) console.error(`❌ [Trace] _refresh_session_id: API error for id=${event_session_id}:`, e);
|
if (log_lvl)
|
||||||
|
console.error(
|
||||||
|
`❌ [Trace] _refresh_session_id: API error for id=${event_session_id}:`,
|
||||||
|
e
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -122,29 +226,65 @@ async function _refresh_session_id_background({ api_cfg, event_session_id, view,
|
|||||||
/**
|
/**
|
||||||
* Helper to handle nested collection loads for a session
|
* Helper to handle nested collection loads for a session
|
||||||
*/
|
*/
|
||||||
async function _handle_nested_loads(session_obj: any, { api_cfg, inc_file_li, inc_all_file_li, inc_presentation_li, inc_presenter_li, enabled, hidden, limit, offset, try_cache, log_lvl }: any) {
|
async function _handle_nested_loads(
|
||||||
|
session_obj: any,
|
||||||
|
{
|
||||||
|
api_cfg,
|
||||||
|
inc_file_li,
|
||||||
|
inc_all_file_li,
|
||||||
|
inc_presentation_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
try_cache,
|
||||||
|
log_lvl
|
||||||
|
}: any
|
||||||
|
) {
|
||||||
const start_time = performance.now();
|
const start_time = performance.now();
|
||||||
const current_session_id = session_obj.id || session_obj.event_session_id;
|
const current_session_id = session_obj.id || session_obj.event_session_id;
|
||||||
if (!current_session_id) return session_obj;
|
if (!current_session_id) return session_obj;
|
||||||
|
|
||||||
const tasks = [];
|
const tasks = [];
|
||||||
if (inc_file_li) {
|
if (inc_file_li) {
|
||||||
tasks.push(load_ae_obj_li__event_file({
|
tasks.push(
|
||||||
api_cfg, for_obj_type: 'event_session', for_obj_id: current_session_id,
|
load_ae_obj_li__event_file({
|
||||||
enabled, limit: 15, try_cache, log_lvl
|
api_cfg,
|
||||||
}).then(res => session_obj.event_file_li = res));
|
for_obj_type: 'event_session',
|
||||||
|
for_obj_id: current_session_id,
|
||||||
|
enabled,
|
||||||
|
limit: 15,
|
||||||
|
try_cache,
|
||||||
|
log_lvl
|
||||||
|
}).then((res) => (session_obj.event_file_li = res))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inc_presentation_li) {
|
if (inc_presentation_li) {
|
||||||
tasks.push(load_ae_obj_li__event_presentation({
|
tasks.push(
|
||||||
api_cfg, for_obj_type: 'event_session', for_obj_id: current_session_id,
|
load_ae_obj_li__event_presentation({
|
||||||
inc_file_li: inc_all_file_li, inc_presenter_li, enabled, hidden, limit, offset, try_cache, log_lvl
|
api_cfg,
|
||||||
}).then(res => session_obj.event_presentation_li = res));
|
for_obj_type: 'event_session',
|
||||||
|
for_obj_id: current_session_id,
|
||||||
|
inc_file_li: inc_all_file_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
try_cache,
|
||||||
|
log_lvl
|
||||||
|
}).then((res) => (session_obj.event_presentation_li = res))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tasks.length > 0) {
|
if (tasks.length > 0) {
|
||||||
await Promise.all(tasks);
|
await Promise.all(tasks);
|
||||||
if (log_lvl) console.log(`🔗 [Trace] _handle_nested_loads: Finished child collections in ${(performance.now() - start_time).toFixed(2)}ms`);
|
if (log_lvl)
|
||||||
|
console.log(
|
||||||
|
`🔗 [Trace] _handle_nested_loads: Finished child collections in ${(performance.now() - start_time).toFixed(2)}ms`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return session_obj;
|
return session_obj;
|
||||||
}
|
}
|
||||||
@@ -191,7 +331,9 @@ export async function load_ae_obj_li__event_session({
|
|||||||
}): Promise<ae_EventSession[]> {
|
}): Promise<ae_EventSession[]> {
|
||||||
const start_time = performance.now();
|
const start_time = performance.now();
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`🔎 [Trace] load_ae_obj_li__event_session: START (for=${for_obj_type}:${for_obj_id}, try_cache=${try_cache})`);
|
console.log(
|
||||||
|
`🔎 [Trace] load_ae_obj_li__event_session: START (for=${for_obj_type}:${for_obj_id}, try_cache=${try_cache})`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hierarchy Enforcement: Pulling presenters requires pulling presentations first
|
// Hierarchy Enforcement: Pulling presenters requires pulling presentations first
|
||||||
@@ -201,226 +343,409 @@ export async function load_ae_obj_li__event_session({
|
|||||||
try {
|
try {
|
||||||
// Robust lookup logic
|
// Robust lookup logic
|
||||||
let query;
|
let query;
|
||||||
if (for_obj_type === 'event_location') query = db_events.session.where('event_location_id').equals(for_obj_id);
|
if (for_obj_type === 'event_location')
|
||||||
else if (for_obj_type === 'event') query = db_events.session.where('event_id').equals(for_obj_id);
|
query = db_events.session
|
||||||
|
.where('event_location_id')
|
||||||
|
.equals(for_obj_id);
|
||||||
|
else if (for_obj_type === 'event')
|
||||||
|
query = db_events.session.where('event_id').equals(for_obj_id);
|
||||||
else query = db_events.session.where('for_id').equals(for_obj_id);
|
else query = db_events.session.where('for_id').equals(for_obj_id);
|
||||||
|
|
||||||
const cached_li = await query.toArray();
|
const cached_li = await query.toArray();
|
||||||
|
|
||||||
if (cached_li && cached_li.length > 0) {
|
if (cached_li && cached_li.length > 0) {
|
||||||
const elapsed = (performance.now() - start_time).toFixed(2);
|
const elapsed = (performance.now() - start_time).toFixed(2);
|
||||||
if (log_lvl) console.log(`✅ [Trace] load_ae_obj_li: CACHE HIT at ${elapsed}ms (${cached_li.length} items).`);
|
if (log_lvl)
|
||||||
|
console.log(
|
||||||
|
`✅ [Trace] load_ae_obj_li: CACHE HIT at ${elapsed}ms (${cached_li.length} items).`
|
||||||
|
);
|
||||||
|
|
||||||
// Background refresh (non-blocking)
|
// Background refresh (non-blocking)
|
||||||
_refresh_session_li_background({
|
_refresh_session_li_background({
|
||||||
api_cfg, for_obj_type, for_obj_id, view,
|
api_cfg,
|
||||||
|
for_obj_type,
|
||||||
|
for_obj_id,
|
||||||
|
view,
|
||||||
// Optimization: Disable nested loads for list members to prevent request storms
|
// Optimization: Disable nested loads for list members to prevent request storms
|
||||||
inc_file_li: false, inc_all_file_li: false, inc_presentation_li: false, inc_presenter_li: false,
|
inc_file_li: false,
|
||||||
enabled, hidden, limit, offset, order_by_li, try_cache,
|
inc_all_file_li: false,
|
||||||
|
inc_presentation_li: false,
|
||||||
|
inc_presenter_li: false,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
order_by_li,
|
||||||
|
try_cache,
|
||||||
log_lvl: log_lvl > 1 ? log_lvl : 0
|
log_lvl: log_lvl > 1 ? log_lvl : 0
|
||||||
});
|
});
|
||||||
|
|
||||||
return cached_li;
|
return cached_li;
|
||||||
} else if (log_lvl) {
|
} else if (log_lvl) {
|
||||||
console.log(`⏳ [Trace] load_ae_obj_li: CACHE MISS at ${(performance.now() - start_time).toFixed(2)}ms for type=${for_obj_type} id=${for_obj_id}`);
|
console.log(
|
||||||
|
`⏳ [Trace] load_ae_obj_li: CACHE MISS at ${(performance.now() - start_time).toFixed(2)}ms for type=${for_obj_type} id=${for_obj_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (log_lvl) console.error(`❌ [Trace] load_ae_obj_li: Cache access error:`, e);
|
if (log_lvl)
|
||||||
|
console.error(
|
||||||
|
`❌ [Trace] load_ae_obj_li: Cache access error:`,
|
||||||
|
e
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return await _refresh_session_li_background({ api_cfg, for_obj_type, for_obj_id, view, inc_file_li, inc_all_file_li, inc_presentation_li, inc_presenter_li, enabled, hidden, limit, offset, order_by_li, try_cache, log_lvl });
|
return await _refresh_session_li_background({
|
||||||
|
api_cfg,
|
||||||
|
for_obj_type,
|
||||||
|
for_obj_id,
|
||||||
|
view,
|
||||||
|
inc_file_li,
|
||||||
|
inc_all_file_li,
|
||||||
|
inc_presentation_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
order_by_li,
|
||||||
|
try_cache,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function _refresh_session_li_background({ api_cfg, for_obj_type, for_obj_id, view, inc_file_li, inc_all_file_li, inc_presentation_li, inc_presenter_li, enabled, hidden, limit, offset, order_by_li, try_cache, log_lvl }: any) {
|
async function _refresh_session_li_background({
|
||||||
|
api_cfg,
|
||||||
|
for_obj_type,
|
||||||
|
for_obj_id,
|
||||||
|
view,
|
||||||
|
inc_file_li,
|
||||||
|
inc_all_file_li,
|
||||||
|
inc_presentation_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
order_by_li,
|
||||||
|
try_cache,
|
||||||
|
log_lvl
|
||||||
|
}: any) {
|
||||||
const start_time = performance.now();
|
const start_time = performance.now();
|
||||||
if (typeof navigator !== 'undefined' && !navigator.onLine) return [];
|
if (typeof navigator !== 'undefined' && !navigator.onLine) return [];
|
||||||
try {
|
try {
|
||||||
if (log_lvl) console.log(`📡 [Trace] _refresh_session_li: API Fetching for=${for_obj_type}:${for_obj_id} (view=${view})`);
|
if (log_lvl)
|
||||||
const result_li = await api.get_ae_obj_li({ api_cfg, obj_type: 'event_session', for_obj_type, for_obj_id, view, enabled, hidden, limit, offset, order_by_li, log_lvl });
|
console.log(
|
||||||
|
`📡 [Trace] _refresh_session_li: API Fetching for=${for_obj_type}:${for_obj_id} (view=${view})`
|
||||||
|
);
|
||||||
|
const result_li = await api.get_ae_obj_li({
|
||||||
|
api_cfg,
|
||||||
|
obj_type: 'event_session',
|
||||||
|
for_obj_type,
|
||||||
|
for_obj_id,
|
||||||
|
view,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
order_by_li,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
|
|
||||||
if (result_li) {
|
if (result_li) {
|
||||||
const processed = await process_ae_obj__event_session_props({ obj_li: result_li, log_lvl });
|
const processed = await process_ae_obj__event_session_props({
|
||||||
|
obj_li: result_li,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
const elapsed = (performance.now() - start_time).toFixed(2);
|
const elapsed = (performance.now() - start_time).toFixed(2);
|
||||||
if (log_lvl) console.log(`📦 [Trace] _refresh_session_li: Received ${processed.length} items from API at ${elapsed}ms.`);
|
if (log_lvl)
|
||||||
|
console.log(
|
||||||
|
`📦 [Trace] _refresh_session_li: Received ${processed.length} items from API at ${elapsed}ms.`
|
||||||
|
);
|
||||||
|
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'session', obj_li: processed, properties_to_save, log_lvl });
|
await db_save_ae_obj_li__ae_obj({
|
||||||
if (log_lvl) console.log(`💾 [Trace] _refresh_session_li: Saved to IDB cache.`);
|
db_instance: db_events,
|
||||||
|
table_name: 'session',
|
||||||
|
obj_li: processed,
|
||||||
|
properties_to_save,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
|
if (log_lvl)
|
||||||
|
console.log(
|
||||||
|
`💾 [Trace] _refresh_session_li: Saved to IDB cache.`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fire nested loads for each session only if explicitly requested (usually only for single objects)
|
// Fire nested loads for each session only if explicitly requested (usually only for single objects)
|
||||||
if (inc_file_li || inc_presentation_li) {
|
if (inc_file_li || inc_presentation_li) {
|
||||||
processed.forEach(s => {
|
processed.forEach((s) => {
|
||||||
_handle_nested_loads(s, { api_cfg, inc_file_li, inc_all_file_li, inc_presentation_li, inc_presenter_li, enabled, hidden, limit, offset, try_cache, log_lvl: 0 });
|
_handle_nested_loads(s, {
|
||||||
|
api_cfg,
|
||||||
|
inc_file_li,
|
||||||
|
inc_all_file_li,
|
||||||
|
inc_presentation_li,
|
||||||
|
inc_presenter_li,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
try_cache,
|
||||||
|
log_lvl: 0
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return processed;
|
return processed;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (log_lvl) console.error(`❌ [Trace] _refresh_session_li: API error:`, e);
|
if (log_lvl)
|
||||||
|
console.error(`❌ [Trace] _refresh_session_li: API error:`, e);
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function create_ae_obj__event_session({
|
export async function create_ae_obj__event_session({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
event_id,
|
event_id,
|
||||||
data_kv,
|
data_kv,
|
||||||
try_cache = true,
|
try_cache = true,
|
||||||
log_lvl = 0
|
log_lvl = 0
|
||||||
}: {
|
}: {
|
||||||
api_cfg: any;
|
api_cfg: any;
|
||||||
event_id?: string;
|
event_id?: string;
|
||||||
data_kv: key_val;
|
data_kv: key_val;
|
||||||
try_cache?: boolean;
|
try_cache?: boolean;
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_EventSession | null> {
|
}): Promise<ae_EventSession | null> {
|
||||||
if (!event_id) event_id = get(slct).event_id;
|
if (!event_id) event_id = get(slct).event_id;
|
||||||
if (!event_id) {
|
if (!event_id) {
|
||||||
console.error('create_ae_obj__event_session: event_id is required');
|
console.error('create_ae_obj__event_session: event_id is required');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const result = await api.create_nested_obj({
|
const result = await api.create_nested_obj({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
for_obj_type: 'event',
|
for_obj_type: 'event',
|
||||||
for_obj_id: event_id,
|
for_obj_id: event_id,
|
||||||
obj_type: 'event_session',
|
obj_type: 'event_session',
|
||||||
fields: { ...data_kv },
|
fields: { ...data_kv },
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
if (result) {
|
if (result) {
|
||||||
const processed = await process_ae_obj__event_session_props({ obj_li: [result], log_lvl });
|
const processed = await process_ae_obj__event_session_props({
|
||||||
const processed_obj = processed[0];
|
obj_li: [result],
|
||||||
if (try_cache) {
|
log_lvl
|
||||||
await db_save_ae_obj_li__ae_obj({
|
});
|
||||||
db_instance: db_events,
|
const processed_obj = processed[0];
|
||||||
table_name: 'session',
|
if (try_cache) {
|
||||||
obj_li: [processed_obj],
|
await db_save_ae_obj_li__ae_obj({
|
||||||
properties_to_save,
|
db_instance: db_events,
|
||||||
log_lvl
|
table_name: 'session',
|
||||||
});
|
obj_li: [processed_obj],
|
||||||
}
|
properties_to_save,
|
||||||
return processed_obj;
|
log_lvl
|
||||||
}
|
});
|
||||||
return null;
|
}
|
||||||
|
return processed_obj;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function delete_ae_obj_id__event_session({
|
export async function delete_ae_obj_id__event_session({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
event_id,
|
event_id,
|
||||||
event_session_id,
|
event_session_id,
|
||||||
method = 'delete',
|
method = 'delete',
|
||||||
try_cache = true,
|
try_cache = true,
|
||||||
log_lvl = 0
|
log_lvl = 0
|
||||||
}: {
|
}: {
|
||||||
api_cfg: any;
|
api_cfg: any;
|
||||||
event_id?: string;
|
event_id?: string;
|
||||||
event_session_id: string;
|
event_session_id: string;
|
||||||
method?: 'delete' | 'soft_delete' | 'disable' | 'hide';
|
method?: 'delete' | 'soft_delete' | 'disable' | 'hide';
|
||||||
try_cache?: boolean;
|
try_cache?: boolean;
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}) {
|
}) {
|
||||||
if (!event_id) event_id = get(slct).event_id;
|
if (!event_id) event_id = get(slct).event_id;
|
||||||
if (!event_id) {
|
if (!event_id) {
|
||||||
console.error('delete_ae_obj_id__event_session: event_id is required');
|
console.error('delete_ae_obj_id__event_session: event_id is required');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const result = await api.delete_nested_ae_obj({
|
const result = await api.delete_nested_ae_obj({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
for_obj_type: 'event',
|
for_obj_type: 'event',
|
||||||
for_obj_id: event_id,
|
for_obj_id: event_id,
|
||||||
obj_type: 'event_session',
|
obj_type: 'event_session',
|
||||||
obj_id: event_session_id,
|
obj_id: event_session_id,
|
||||||
method,
|
method,
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
if (try_cache) await db_events.session.delete(event_session_id);
|
if (try_cache) await db_events.session.delete(event_session_id);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function update_ae_obj__event_session({
|
export async function update_ae_obj__event_session({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
event_id,
|
event_id,
|
||||||
event_session_id,
|
event_session_id,
|
||||||
data_kv,
|
data_kv,
|
||||||
try_cache = true,
|
try_cache = true,
|
||||||
log_lvl = 0
|
log_lvl = 0
|
||||||
}: {
|
}: {
|
||||||
api_cfg: any;
|
api_cfg: any;
|
||||||
event_id?: string;
|
event_id?: string;
|
||||||
event_session_id: string;
|
event_session_id: string;
|
||||||
data_kv: key_val;
|
data_kv: key_val;
|
||||||
try_cache?: boolean;
|
try_cache?: boolean;
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_EventSession | null> {
|
}): Promise<ae_EventSession | null> {
|
||||||
if (!event_id) event_id = get(slct).event_id;
|
if (!event_id) event_id = get(slct).event_id;
|
||||||
if (!event_id) {
|
if (!event_id) {
|
||||||
console.error('update_ae_obj__event_session: event_id is required');
|
console.error('update_ae_obj__event_session: event_id is required');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const result = await api.update_nested_obj({
|
const result = await api.update_nested_obj({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
for_obj_type: 'event',
|
for_obj_type: 'event',
|
||||||
for_obj_id: event_id,
|
for_obj_id: event_id,
|
||||||
obj_type: 'event_session',
|
obj_type: 'event_session',
|
||||||
obj_id: event_session_id,
|
obj_id: event_session_id,
|
||||||
fields: data_kv,
|
fields: data_kv,
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
if (result) {
|
if (result) {
|
||||||
const processed = await process_ae_obj__event_session_props({ obj_li: [result], log_lvl });
|
const processed = await process_ae_obj__event_session_props({
|
||||||
const processed_obj = processed[0];
|
obj_li: [result],
|
||||||
if (try_cache) {
|
log_lvl
|
||||||
await db_save_ae_obj_li__ae_obj({
|
});
|
||||||
db_instance: db_events,
|
const processed_obj = processed[0];
|
||||||
table_name: 'session',
|
if (try_cache) {
|
||||||
obj_li: [processed_obj],
|
await db_save_ae_obj_li__ae_obj({
|
||||||
properties_to_save,
|
db_instance: db_events,
|
||||||
log_lvl
|
table_name: 'session',
|
||||||
});
|
obj_li: [processed_obj],
|
||||||
}
|
properties_to_save,
|
||||||
return processed_obj;
|
log_lvl
|
||||||
}
|
});
|
||||||
return null;
|
}
|
||||||
|
return processed_obj;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function search__event_session({
|
export async function search__event_session({
|
||||||
api_cfg, event_id, fulltext_search_qry_str = '', ft_presenter_search_qry_str = '', like_search_qry_str = '', like_presentation_search_qry_str = '', like_presenter_search_qry_str = '', like_poc_name_qry_str = '', location_name = null, qry_files = null, qry_poc_agree = null, qry_poc_kv_json = null, qry_start_datetime = null, enabled = 'enabled', hidden = 'not_hidden', view = 'default', limit = 50, offset = 0, order_by_li = [{ sort: 'ASC' }, { start_datetime: 'ASC' }, { name: 'ASC' }], try_cache = true, log_lvl = 0
|
api_cfg,
|
||||||
|
event_id,
|
||||||
|
fulltext_search_qry_str = '',
|
||||||
|
ft_presenter_search_qry_str = '',
|
||||||
|
like_search_qry_str = '',
|
||||||
|
like_presentation_search_qry_str = '',
|
||||||
|
like_presenter_search_qry_str = '',
|
||||||
|
like_poc_name_qry_str = '',
|
||||||
|
location_name = null,
|
||||||
|
qry_files = null,
|
||||||
|
qry_poc_agree = null,
|
||||||
|
qry_poc_kv_json = null,
|
||||||
|
qry_start_datetime = null,
|
||||||
|
enabled = 'enabled',
|
||||||
|
hidden = 'not_hidden',
|
||||||
|
view = 'default',
|
||||||
|
limit = 50,
|
||||||
|
offset = 0,
|
||||||
|
order_by_li = [{ sort: 'ASC' }, { start_datetime: 'ASC' }, { name: 'ASC' }],
|
||||||
|
try_cache = true,
|
||||||
|
log_lvl = 0
|
||||||
}: {
|
}: {
|
||||||
api_cfg: any; event_id: string; fulltext_search_qry_str?: string; ft_presenter_search_qry_str?: string | null; like_search_qry_str?: string; like_presentation_search_qry_str?: string; like_presenter_search_qry_str?: string; like_poc_name_qry_str?: string; location_name?: null | string; qry_files?: null | boolean; qry_poc_agree?: null | boolean; qry_poc_kv_json?: null | boolean; qry_start_datetime?: string | null; enabled?: 'enabled' | 'all' | 'not_enabled'; hidden?: 'hidden' | 'all' | 'not_hidden'; view?: string; limit?: number; offset?: number; order_by_li?: any; try_cache?: boolean; log_lvl?: number;
|
api_cfg: any;
|
||||||
|
event_id: string;
|
||||||
|
fulltext_search_qry_str?: string;
|
||||||
|
ft_presenter_search_qry_str?: string | null;
|
||||||
|
like_search_qry_str?: string;
|
||||||
|
like_presentation_search_qry_str?: string;
|
||||||
|
like_presenter_search_qry_str?: string;
|
||||||
|
like_poc_name_qry_str?: string;
|
||||||
|
location_name?: null | string;
|
||||||
|
qry_files?: null | boolean;
|
||||||
|
qry_poc_agree?: null | boolean;
|
||||||
|
qry_poc_kv_json?: null | boolean;
|
||||||
|
qry_start_datetime?: string | null;
|
||||||
|
enabled?: 'enabled' | 'all' | 'not_enabled';
|
||||||
|
hidden?: 'hidden' | 'all' | 'not_hidden';
|
||||||
|
view?: string;
|
||||||
|
limit?: number;
|
||||||
|
offset?: number;
|
||||||
|
order_by_li?: any;
|
||||||
|
try_cache?: boolean;
|
||||||
|
log_lvl?: number;
|
||||||
}): Promise<ae_EventSession[]> {
|
}): Promise<ae_EventSession[]> {
|
||||||
const search_query: any = { q: '', and: [{ field: 'event_id', op: 'eq', value: event_id }] };
|
const search_query: any = {
|
||||||
|
q: '',
|
||||||
|
and: [{ field: 'event_id', op: 'eq', value: event_id }]
|
||||||
|
};
|
||||||
if (fulltext_search_qry_str || ft_presenter_search_qry_str) {
|
if (fulltext_search_qry_str || ft_presenter_search_qry_str) {
|
||||||
const ft: any = {};
|
const ft: any = {};
|
||||||
if (fulltext_search_qry_str && fulltext_search_qry_str.length > 2) ft['default_qry_str'] = fulltext_search_qry_str;
|
if (fulltext_search_qry_str && fulltext_search_qry_str.length > 2)
|
||||||
if (ft_presenter_search_qry_str && ft_presenter_search_qry_str.length > 2) ft['event_presenter_li_qry_str'] = ft_presenter_search_qry_str;
|
ft['default_qry_str'] = fulltext_search_qry_str;
|
||||||
|
if (
|
||||||
|
ft_presenter_search_qry_str &&
|
||||||
|
ft_presenter_search_qry_str.length > 2
|
||||||
|
)
|
||||||
|
ft['event_presenter_li_qry_str'] = ft_presenter_search_qry_str;
|
||||||
if (Object.keys(ft).length) search_query.params = { ft_qry: ft };
|
if (Object.keys(ft).length) search_query.params = { ft_qry: ft };
|
||||||
}
|
}
|
||||||
if (enabled === 'enabled') search_query.and.push({ field: 'enable', op: 'eq', value: 1 });
|
if (enabled === 'enabled')
|
||||||
else if (enabled === 'not_enabled') search_query.and.push({ field: 'enable', op: 'eq', value: 0 });
|
search_query.and.push({ field: 'enable', op: 'eq', value: 1 });
|
||||||
if (hidden === 'hidden') search_query.and.push({ field: 'hide', op: 'eq', value: 1 });
|
else if (enabled === 'not_enabled')
|
||||||
else if (hidden === 'not_hidden') search_query.and.push({ field: 'hide', op: 'eq', value: 0 });
|
search_query.and.push({ field: 'enable', op: 'eq', value: 0 });
|
||||||
|
if (hidden === 'hidden')
|
||||||
|
search_query.and.push({ field: 'hide', op: 'eq', value: 1 });
|
||||||
|
else if (hidden === 'not_hidden')
|
||||||
|
search_query.and.push({ field: 'hide', op: 'eq', value: 0 });
|
||||||
|
|
||||||
if (location_name) {
|
if (location_name) {
|
||||||
search_query.and.push({ field: 'event_location_name', op: 'eq', value: location_name });
|
search_query.and.push({
|
||||||
|
field: 'event_location_name',
|
||||||
|
op: 'eq',
|
||||||
|
value: location_name
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const result_li = await api.search_ae_obj({ api_cfg, obj_type: 'event_session', search_query, order_by_li, view, limit, offset, log_lvl });
|
const result_li = await api.search_ae_obj({
|
||||||
|
api_cfg,
|
||||||
|
obj_type: 'event_session',
|
||||||
|
search_query,
|
||||||
|
order_by_li,
|
||||||
|
view,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
|
|
||||||
// Handle V3 API envelope
|
// Handle V3 API envelope
|
||||||
let valid_result_li: ae_EventSession[] = [];
|
let valid_result_li: ae_EventSession[] = [];
|
||||||
if (Array.isArray(result_li)) {
|
if (Array.isArray(result_li)) {
|
||||||
valid_result_li = result_li;
|
valid_result_li = result_li;
|
||||||
} else if (result_li && typeof result_li === 'object' && Array.isArray((result_li as any).data)) {
|
} else if (
|
||||||
|
result_li &&
|
||||||
|
typeof result_li === 'object' &&
|
||||||
|
Array.isArray((result_li as any).data)
|
||||||
|
) {
|
||||||
valid_result_li = (result_li as any).data;
|
valid_result_li = (result_li as any).data;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valid_result_li && valid_result_li.length > 0) {
|
if (valid_result_li && valid_result_li.length > 0) {
|
||||||
const processed = await process_ae_obj__event_session_props({ obj_li: valid_result_li, log_lvl });
|
const processed = await process_ae_obj__event_session_props({
|
||||||
|
obj_li: valid_result_li,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'session', obj_li: processed, properties_to_save, log_lvl });
|
await db_save_ae_obj_li__ae_obj({
|
||||||
|
db_instance: db_events,
|
||||||
|
table_name: 'session',
|
||||||
|
obj_li: processed,
|
||||||
|
properties_to_save,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return processed;
|
return processed;
|
||||||
}
|
}
|
||||||
@@ -429,18 +754,103 @@ export async function search__event_session({
|
|||||||
|
|
||||||
export const qry__event_session = search__event_session;
|
export const qry__event_session = search__event_session;
|
||||||
|
|
||||||
export async function email_sign_in__event_session({ api_cfg, to_email, to_name, base_url, person_id, person_passcode, event_id, event_session_id, session_name }: { api_cfg: any; to_email: string; to_name: string; base_url: string; person_id: string; person_passcode: string; event_id: string; event_session_id: string; session_name: string; }) {
|
export async function email_sign_in__event_session({
|
||||||
|
api_cfg,
|
||||||
|
to_email,
|
||||||
|
to_name,
|
||||||
|
base_url,
|
||||||
|
person_id,
|
||||||
|
person_passcode,
|
||||||
|
event_id,
|
||||||
|
event_session_id,
|
||||||
|
session_name
|
||||||
|
}: {
|
||||||
|
api_cfg: any;
|
||||||
|
to_email: string;
|
||||||
|
to_name: string;
|
||||||
|
base_url: string;
|
||||||
|
person_id: string;
|
||||||
|
person_passcode: string;
|
||||||
|
event_id: string;
|
||||||
|
event_session_id: string;
|
||||||
|
session_name: string;
|
||||||
|
}) {
|
||||||
const subject = `Pres Mgmt Hub Sign In Link for ${session_name}`;
|
const subject = `Pres Mgmt Hub Sign In Link for ${session_name}`;
|
||||||
const sign_in_url = encodeURI(`${base_url}/events/${event_id}/session/${event_session_id}?person_id=${person_id}&person_pass=${person_passcode}`);
|
const sign_in_url = encodeURI(
|
||||||
|
`${base_url}/events/${event_id}/session/${event_session_id}?person_id=${person_id}&person_pass=${person_passcode}`
|
||||||
|
);
|
||||||
const body_html = `<div>${to_name},<p>Your sign-in link for ${session_name}: <a href="${sign_in_url}">${sign_in_url}</a></p></div>`;
|
const body_html = `<div>${to_name},<p>Your sign-in link for ${session_name}: <a href="${sign_in_url}">${sign_in_url}</a></p></div>`;
|
||||||
return await api.send_email({ api_cfg, from_email: 'noreply+presmgmt@oneskyit.com', from_name: 'Aether Pres Mgmt', to_email, subject, body_html });
|
return await api.send_email({
|
||||||
|
api_cfg,
|
||||||
|
from_email: 'noreply+presmgmt@oneskyit.com',
|
||||||
|
from_name: 'Aether Pres Mgmt',
|
||||||
|
to_email,
|
||||||
|
subject,
|
||||||
|
body_html
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export const properties_to_save = [
|
export const properties_to_save = [
|
||||||
'id', 'event_session_id', 'event_session_id_random', 'external_id', 'code', 'for_type', 'for_id', 'for_id_random', 'type_code', 'event_id', 'event_location_id', 'poc_person_id', 'poc_agree', 'poc_kv_json', 'name', 'description', 'start_datetime', 'end_datetime', 'passcode', 'hide_event_launcher', 'alert', 'alert_msg', 'data_json', 'ux_mode', 'enable', 'hide', 'priority', 'sort', 'group', 'notes', 'created_on', 'updated_on', 'tmp_sort_1', 'tmp_sort_2', 'file_count', 'file_count_all', 'internal_use_count', 'event_file_id_li_json', 'poc_person_given_name', 'poc_person_family_name', 'poc_person_full_name', 'poc_person_primary_email', 'poc_person_passcode', 'event_name', 'event_location_code', 'event_location_name', 'event_presentation_li'
|
'id',
|
||||||
|
'event_session_id',
|
||||||
|
'event_session_id_random',
|
||||||
|
'external_id',
|
||||||
|
'code',
|
||||||
|
'for_type',
|
||||||
|
'for_id',
|
||||||
|
'for_id_random',
|
||||||
|
'type_code',
|
||||||
|
'event_id',
|
||||||
|
'event_location_id',
|
||||||
|
'poc_person_id',
|
||||||
|
'poc_agree',
|
||||||
|
'poc_kv_json',
|
||||||
|
'name',
|
||||||
|
'description',
|
||||||
|
'start_datetime',
|
||||||
|
'end_datetime',
|
||||||
|
'passcode',
|
||||||
|
'hide_event_launcher',
|
||||||
|
'alert',
|
||||||
|
'alert_msg',
|
||||||
|
'data_json',
|
||||||
|
'ux_mode',
|
||||||
|
'enable',
|
||||||
|
'hide',
|
||||||
|
'priority',
|
||||||
|
'sort',
|
||||||
|
'group',
|
||||||
|
'notes',
|
||||||
|
'created_on',
|
||||||
|
'updated_on',
|
||||||
|
'tmp_sort_1',
|
||||||
|
'tmp_sort_2',
|
||||||
|
'file_count',
|
||||||
|
'file_count_all',
|
||||||
|
'internal_use_count',
|
||||||
|
'event_file_id_li_json',
|
||||||
|
'poc_person_given_name',
|
||||||
|
'poc_person_family_name',
|
||||||
|
'poc_person_full_name',
|
||||||
|
'poc_person_primary_email',
|
||||||
|
'poc_person_passcode',
|
||||||
|
'event_name',
|
||||||
|
'event_location_code',
|
||||||
|
'event_location_name',
|
||||||
|
'event_presentation_li'
|
||||||
];
|
];
|
||||||
|
|
||||||
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[]> {
|
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 [];
|
if (!obj_li || obj_li.length === 0) return [];
|
||||||
const processed_obj_li: T[] = [];
|
const processed_obj_li: T[] = [];
|
||||||
for (const original_obj of obj_li) {
|
for (const original_obj of obj_li) {
|
||||||
@@ -456,22 +866,40 @@ async function _process_generic_props<T extends Record<string, any>>({ obj_li, o
|
|||||||
if (processed_obj[randomIdKey]) {
|
if (processed_obj[randomIdKey]) {
|
||||||
(processed_obj as any).id = processed_obj[randomIdKey];
|
(processed_obj as any).id = processed_obj[randomIdKey];
|
||||||
(processed_obj as any)[baseIdKey] = processed_obj[randomIdKey];
|
(processed_obj as any)[baseIdKey] = processed_obj[randomIdKey];
|
||||||
}
|
} else if (processed_obj[baseIdKey])
|
||||||
else if (processed_obj[baseIdKey]) (processed_obj as any).id = processed_obj[baseIdKey];
|
(processed_obj as any).id = processed_obj[baseIdKey];
|
||||||
|
|
||||||
const group = processed_obj.group ?? '0';
|
const group = processed_obj.group ?? '0';
|
||||||
const priority = processed_obj.priority ? 1 : 0;
|
const priority = processed_obj.priority ? 1 : 0;
|
||||||
const sort = processed_obj.sort ?? '0';
|
const sort = processed_obj.sort ?? '0';
|
||||||
const updated = processed_obj.updated_on ?? processed_obj.created_on ?? new Date(0).toISOString();
|
const updated =
|
||||||
|
processed_obj.updated_on ??
|
||||||
|
processed_obj.created_on ??
|
||||||
|
new Date(0).toISOString();
|
||||||
const name = processed_obj.name ?? '';
|
const name = processed_obj.name ?? '';
|
||||||
(processed_obj as any).tmp_sort_1 = `${group}_${priority}_${sort}_${updated}`;
|
(processed_obj as any).tmp_sort_1 =
|
||||||
(processed_obj as any).tmp_sort_2 = `${group}_${priority}_${sort}_${name}_${updated}`;
|
`${group}_${priority}_${sort}_${updated}`;
|
||||||
if (specific_processor) processed_obj = await Promise.resolve(specific_processor(processed_obj));
|
(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);
|
processed_obj_li.push(processed_obj as T);
|
||||||
}
|
}
|
||||||
return processed_obj_li;
|
return processed_obj_li;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function process_ae_obj__event_session_props({ obj_li, log_lvl = 0 }: { obj_li: any[]; log_lvl?: number; }) {
|
export async function process_ae_obj__event_session_props({
|
||||||
return _process_generic_props({ obj_li, obj_type: 'event_session', log_lvl });
|
obj_li,
|
||||||
|
log_lvl = 0
|
||||||
|
}: {
|
||||||
|
obj_li: any[];
|
||||||
|
log_lvl?: number;
|
||||||
|
}) {
|
||||||
|
return _process_generic_props({
|
||||||
|
obj_li,
|
||||||
|
obj_type: 'event_session',
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
}
|
}
|
||||||
@@ -92,11 +92,15 @@ async function _process_generic_props<T extends Record<string, any>>({
|
|||||||
(processed_obj as any).description = '';
|
(processed_obj as any).description = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
(processed_obj as any).tmp_sort_1 = `${group}_${priority}_${sort}_${updated}`;
|
(processed_obj as any).tmp_sort_1 =
|
||||||
(processed_obj as any).tmp_sort_2 = `${group}_${priority}_${sort}_${name}_${updated}`;
|
`${group}_${priority}_${sort}_${updated}`;
|
||||||
|
(processed_obj as any).tmp_sort_2 =
|
||||||
|
`${group}_${priority}_${sort}_${name}_${updated}`;
|
||||||
|
|
||||||
if (specific_processor) {
|
if (specific_processor) {
|
||||||
processed_obj = await Promise.resolve(specific_processor(processed_obj));
|
processed_obj = await Promise.resolve(
|
||||||
|
specific_processor(processed_obj)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
processed_obj_li.push(processed_obj as T);
|
processed_obj_li.push(processed_obj as T);
|
||||||
@@ -137,7 +141,9 @@ export async function load_ae_obj_id__event_exhibit({
|
|||||||
}): Promise<ae_EventExhibit | null> {
|
}): Promise<ae_EventExhibit | null> {
|
||||||
const start_time = performance.now();
|
const start_time = performance.now();
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`🔎 [Trace] load_ae_obj_id__event_exhibit: START (id=${exhibit_id}, try_cache=${try_cache})`);
|
console.log(
|
||||||
|
`🔎 [Trace] load_ae_obj_id__event_exhibit: START (id=${exhibit_id}, try_cache=${try_cache})`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. FAST PATH: Return cached data immediately
|
// 1. FAST PATH: Return cached data immediately
|
||||||
@@ -146,34 +152,74 @@ export async function load_ae_obj_id__event_exhibit({
|
|||||||
const cached = await db_events.exhibit.get(exhibit_id);
|
const cached = await db_events.exhibit.get(exhibit_id);
|
||||||
if (cached) {
|
if (cached) {
|
||||||
const elapsed = (performance.now() - start_time).toFixed(2);
|
const elapsed = (performance.now() - start_time).toFixed(2);
|
||||||
if (log_lvl) console.log(`✅ [Trace] load_ae_obj_id: CACHE HIT at ${elapsed}ms. Returning stale exhibit shell.`);
|
if (log_lvl)
|
||||||
|
console.log(
|
||||||
|
`✅ [Trace] load_ae_obj_id: CACHE HIT at ${elapsed}ms. Returning stale exhibit shell.`
|
||||||
|
);
|
||||||
|
|
||||||
// Background refresh (non-blocking)
|
// Background refresh (non-blocking)
|
||||||
_refresh_exhibit_id_background({ api_cfg, exhibit_id, view, try_cache, log_lvl: log_lvl > 1 ? log_lvl : 0 });
|
_refresh_exhibit_id_background({
|
||||||
|
api_cfg,
|
||||||
|
exhibit_id,
|
||||||
|
view,
|
||||||
|
try_cache,
|
||||||
|
log_lvl: log_lvl > 1 ? log_lvl : 0
|
||||||
|
});
|
||||||
return cached;
|
return cached;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (log_lvl) console.error(`❌ [Trace] load_ae_obj_id: Cache access error:`, e);
|
if (log_lvl)
|
||||||
|
console.error(
|
||||||
|
`❌ [Trace] load_ae_obj_id: Cache access error:`,
|
||||||
|
e
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. SLOW PATH: Wait for API
|
// 2. SLOW PATH: Wait for API
|
||||||
return await _refresh_exhibit_id_background({ api_cfg, exhibit_id, view, try_cache, log_lvl });
|
return await _refresh_exhibit_id_background({
|
||||||
|
api_cfg,
|
||||||
|
exhibit_id,
|
||||||
|
view,
|
||||||
|
try_cache,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function _refresh_exhibit_id_background({ api_cfg, exhibit_id, view, try_cache, log_lvl }: any) {
|
async function _refresh_exhibit_id_background({
|
||||||
|
api_cfg,
|
||||||
|
exhibit_id,
|
||||||
|
view,
|
||||||
|
try_cache,
|
||||||
|
log_lvl
|
||||||
|
}: any) {
|
||||||
const start_time = performance.now();
|
const start_time = performance.now();
|
||||||
if (typeof navigator !== 'undefined' && !navigator.onLine) return null;
|
if (typeof navigator !== 'undefined' && !navigator.onLine) return null;
|
||||||
try {
|
try {
|
||||||
if (log_lvl) console.log(`📡 [Trace] _refresh_exhibit_id: API Fetching id=${exhibit_id}`);
|
if (log_lvl)
|
||||||
const result = await api.get_ae_obj({ api_cfg, obj_type: 'event_exhibit', obj_id: exhibit_id, view, log_lvl });
|
console.log(
|
||||||
|
`📡 [Trace] _refresh_exhibit_id: API Fetching id=${exhibit_id}`
|
||||||
|
);
|
||||||
|
const result = await api.get_ae_obj({
|
||||||
|
api_cfg,
|
||||||
|
obj_type: 'event_exhibit',
|
||||||
|
obj_id: exhibit_id,
|
||||||
|
view,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
const processed = await process_ae_obj__exhibit_props({ obj_li: [result], log_lvl });
|
const processed = await process_ae_obj__exhibit_props({
|
||||||
|
obj_li: [result],
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
const processed_obj = processed[0];
|
const processed_obj = processed[0];
|
||||||
const elapsed = (performance.now() - start_time).toFixed(2);
|
const elapsed = (performance.now() - start_time).toFixed(2);
|
||||||
|
|
||||||
if (log_lvl) console.log(`📦 [Trace] _refresh_exhibit_id: Received from API at ${elapsed}ms`);
|
if (log_lvl)
|
||||||
|
console.log(
|
||||||
|
`📦 [Trace] _refresh_exhibit_id: Received from API at ${elapsed}ms`
|
||||||
|
);
|
||||||
|
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
@@ -187,7 +233,11 @@ async function _refresh_exhibit_id_background({ api_cfg, exhibit_id, view, try_c
|
|||||||
return processed_obj;
|
return processed_obj;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (log_lvl) console.error(`❌ [Trace] _refresh_exhibit_id: API error for id=${exhibit_id}:`, e);
|
if (log_lvl)
|
||||||
|
console.error(
|
||||||
|
`❌ [Trace] _refresh_exhibit_id: API error for id=${exhibit_id}:`,
|
||||||
|
e
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -225,36 +275,82 @@ export async function load_ae_obj_li__event_exhibit({
|
|||||||
}): Promise<ae_EventExhibit[]> {
|
}): Promise<ae_EventExhibit[]> {
|
||||||
const start_time = performance.now();
|
const start_time = performance.now();
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`🔎 [Trace] load_ae_obj_li__event_exhibit: START (event=${event_id}, try_cache=${try_cache})`);
|
console.log(
|
||||||
|
`🔎 [Trace] load_ae_obj_li__event_exhibit: START (event=${event_id}, try_cache=${try_cache})`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
try {
|
try {
|
||||||
const cached_li = await db_events.exhibit
|
const cached_li = await db_events.exhibit
|
||||||
.where('event_id').equals(event_id)
|
.where('event_id')
|
||||||
|
.equals(event_id)
|
||||||
.toArray();
|
.toArray();
|
||||||
|
|
||||||
if (cached_li && cached_li.length > 0) {
|
if (cached_li && cached_li.length > 0) {
|
||||||
const elapsed = (performance.now() - start_time).toFixed(2);
|
const elapsed = (performance.now() - start_time).toFixed(2);
|
||||||
if (log_lvl) console.log(`✅ [Trace] load_ae_obj_li: CACHE HIT at ${elapsed}ms (${cached_li.length} items).`);
|
if (log_lvl)
|
||||||
|
console.log(
|
||||||
|
`✅ [Trace] load_ae_obj_li: CACHE HIT at ${elapsed}ms (${cached_li.length} items).`
|
||||||
|
);
|
||||||
|
|
||||||
// Background refresh (non-blocking)
|
// Background refresh (non-blocking)
|
||||||
_refresh_exhibit_li_background({ api_cfg, event_id, enabled, hidden, view, limit, offset, order_by_li, try_cache, log_lvl: log_lvl > 1 ? log_lvl : 0 });
|
_refresh_exhibit_li_background({
|
||||||
|
api_cfg,
|
||||||
|
event_id,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
view,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
order_by_li,
|
||||||
|
try_cache,
|
||||||
|
log_lvl: log_lvl > 1 ? log_lvl : 0
|
||||||
|
});
|
||||||
return cached_li;
|
return cached_li;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (log_lvl) console.error(`❌ [Trace] load_ae_obj_li: Cache access error:`, e);
|
if (log_lvl)
|
||||||
|
console.error(
|
||||||
|
`❌ [Trace] load_ae_obj_li: Cache access error:`,
|
||||||
|
e
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return await _refresh_exhibit_li_background({ api_cfg, event_id, enabled, hidden, view, limit, offset, order_by_li, try_cache, log_lvl });
|
return await _refresh_exhibit_li_background({
|
||||||
|
api_cfg,
|
||||||
|
event_id,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
view,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
order_by_li,
|
||||||
|
try_cache,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function _refresh_exhibit_li_background({ api_cfg, event_id, enabled, hidden, view, limit, offset, order_by_li, try_cache, log_lvl }: any) {
|
async function _refresh_exhibit_li_background({
|
||||||
|
api_cfg,
|
||||||
|
event_id,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
view,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
order_by_li,
|
||||||
|
try_cache,
|
||||||
|
log_lvl
|
||||||
|
}: any) {
|
||||||
const start_time = performance.now();
|
const start_time = performance.now();
|
||||||
if (typeof navigator !== 'undefined' && !navigator.onLine) return [];
|
if (typeof navigator !== 'undefined' && !navigator.onLine) return [];
|
||||||
try {
|
try {
|
||||||
if (log_lvl) console.log(`📡 [Trace] _refresh_exhibit_li: API Fetching exhibits for event=${event_id}`);
|
if (log_lvl)
|
||||||
|
console.log(
|
||||||
|
`📡 [Trace] _refresh_exhibit_li: API Fetching exhibits for event=${event_id}`
|
||||||
|
);
|
||||||
const result_li = await api.get_ae_obj_li({
|
const result_li = await api.get_ae_obj_li({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
obj_type: 'event_exhibit',
|
obj_type: 'event_exhibit',
|
||||||
@@ -270,9 +366,15 @@ async function _refresh_exhibit_li_background({ api_cfg, event_id, enabled, hidd
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (result_li) {
|
if (result_li) {
|
||||||
const processed = await process_ae_obj__exhibit_props({ obj_li: result_li, log_lvl });
|
const processed = await process_ae_obj__exhibit_props({
|
||||||
|
obj_li: result_li,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
const elapsed = (performance.now() - start_time).toFixed(2);
|
const elapsed = (performance.now() - start_time).toFixed(2);
|
||||||
if (log_lvl) console.log(`📦 [Trace] _refresh_exhibit_li: Received ${processed.length} items from API at ${elapsed}ms.`);
|
if (log_lvl)
|
||||||
|
console.log(
|
||||||
|
`📦 [Trace] _refresh_exhibit_li: Received ${processed.length} items from API at ${elapsed}ms.`
|
||||||
|
);
|
||||||
|
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
@@ -286,7 +388,8 @@ async function _refresh_exhibit_li_background({ api_cfg, event_id, enabled, hidd
|
|||||||
return processed;
|
return processed;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (log_lvl) console.error(`❌ [Trace] _refresh_exhibit_li: API error:`, e);
|
if (log_lvl)
|
||||||
|
console.error(`❌ [Trace] _refresh_exhibit_li: API error:`, e);
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@@ -295,87 +398,93 @@ async function _refresh_exhibit_li_background({ api_cfg, event_id, enabled, hidd
|
|||||||
* Exhibit Create (V3)
|
* Exhibit Create (V3)
|
||||||
*/
|
*/
|
||||||
export async function create_ae_obj__exhibit({
|
export async function create_ae_obj__exhibit({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
event_id,
|
event_id,
|
||||||
data_kv,
|
data_kv,
|
||||||
try_cache = true,
|
try_cache = true,
|
||||||
log_lvl = 0
|
log_lvl = 0
|
||||||
}: {
|
}: {
|
||||||
api_cfg: any;
|
api_cfg: any;
|
||||||
event_id: string;
|
event_id: string;
|
||||||
data_kv: key_val;
|
data_kv: key_val;
|
||||||
try_cache?: boolean;
|
try_cache?: boolean;
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_EventExhibit | null> {
|
}): Promise<ae_EventExhibit | null> {
|
||||||
const result = await api.create_nested_obj({
|
const result = await api.create_nested_obj({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
parent_type: 'event',
|
parent_type: 'event',
|
||||||
parent_id: event_id,
|
parent_id: event_id,
|
||||||
child_type: 'event_exhibit',
|
child_type: 'event_exhibit',
|
||||||
fields: { ...data_kv },
|
fields: { ...data_kv },
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
const processed = await process_ae_obj__exhibit_props({ obj_li: [result], log_lvl });
|
const processed = await process_ae_obj__exhibit_props({
|
||||||
const processed_obj = processed[0];
|
obj_li: [result],
|
||||||
if (try_cache) {
|
log_lvl
|
||||||
await db_save_ae_obj_li__ae_obj({
|
});
|
||||||
db_instance: db_events,
|
const processed_obj = processed[0];
|
||||||
table_name: 'exhibit',
|
if (try_cache) {
|
||||||
obj_li: [processed_obj],
|
await db_save_ae_obj_li__ae_obj({
|
||||||
properties_to_save: properties_to_save_exhibit,
|
db_instance: db_events,
|
||||||
log_lvl
|
table_name: 'exhibit',
|
||||||
});
|
obj_li: [processed_obj],
|
||||||
}
|
properties_to_save: properties_to_save_exhibit,
|
||||||
return processed_obj;
|
log_lvl
|
||||||
}
|
});
|
||||||
return null;
|
}
|
||||||
|
return processed_obj;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exhibit Update (V3)
|
* Exhibit Update (V3)
|
||||||
*/
|
*/
|
||||||
export async function update_ae_obj__exhibit({
|
export async function update_ae_obj__exhibit({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
event_id,
|
event_id,
|
||||||
exhibit_id,
|
exhibit_id,
|
||||||
data_kv,
|
data_kv,
|
||||||
try_cache = true,
|
try_cache = true,
|
||||||
log_lvl = 0
|
log_lvl = 0
|
||||||
}: {
|
}: {
|
||||||
api_cfg: any;
|
api_cfg: any;
|
||||||
event_id: string;
|
event_id: string;
|
||||||
exhibit_id: string;
|
exhibit_id: string;
|
||||||
data_kv: key_val;
|
data_kv: key_val;
|
||||||
try_cache?: boolean;
|
try_cache?: boolean;
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_EventExhibit | null> {
|
}): Promise<ae_EventExhibit | null> {
|
||||||
const result = await api.update_nested_obj({
|
const result = await api.update_nested_obj({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
parent_type: 'event',
|
parent_type: 'event',
|
||||||
parent_id: event_id,
|
parent_id: event_id,
|
||||||
child_type: 'event_exhibit',
|
child_type: 'event_exhibit',
|
||||||
child_id: exhibit_id,
|
child_id: exhibit_id,
|
||||||
fields: data_kv,
|
fields: data_kv,
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
const processed = await process_ae_obj__exhibit_props({ obj_li: [result], log_lvl });
|
const processed = await process_ae_obj__exhibit_props({
|
||||||
const processed_obj = processed[0];
|
obj_li: [result],
|
||||||
if (try_cache) {
|
log_lvl
|
||||||
await db_save_ae_obj_li__ae_obj({
|
});
|
||||||
db_instance: db_events,
|
const processed_obj = processed[0];
|
||||||
table_name: 'exhibit',
|
if (try_cache) {
|
||||||
obj_li: [processed_obj],
|
await db_save_ae_obj_li__ae_obj({
|
||||||
properties_to_save: properties_to_save_exhibit,
|
db_instance: db_events,
|
||||||
log_lvl
|
table_name: 'exhibit',
|
||||||
});
|
obj_li: [processed_obj],
|
||||||
}
|
properties_to_save: properties_to_save_exhibit,
|
||||||
return processed_obj;
|
log_lvl
|
||||||
}
|
});
|
||||||
return null;
|
}
|
||||||
|
return processed_obj;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -409,24 +518,30 @@ export async function search__exhibit({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_EventExhibit[]> {
|
}): Promise<ae_EventExhibit[]> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** search__exhibit() *** event_id=${event_id} ft=${fulltext_search_qry_str}`);
|
console.log(
|
||||||
|
`*** search__exhibit() *** event_id=${event_id} ft=${fulltext_search_qry_str}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const search_query: any = {
|
const search_query: any = {
|
||||||
q: fulltext_search_qry_str || '',
|
q: fulltext_search_qry_str || '',
|
||||||
and: [
|
and: [{ field: 'event_id', op: 'eq', value: event_id }]
|
||||||
{ field: 'event_id', op: 'eq', value: event_id }
|
|
||||||
]
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (enabled === 'enabled') search_query.and.push({ field: 'enable', op: 'eq', value: 1 });
|
if (enabled === 'enabled')
|
||||||
else if (enabled === 'not_enabled') search_query.and.push({ field: 'enable', op: 'eq', value: 0 });
|
search_query.and.push({ field: 'enable', op: 'eq', value: 1 });
|
||||||
|
else if (enabled === 'not_enabled')
|
||||||
|
search_query.and.push({ field: 'enable', op: 'eq', value: 0 });
|
||||||
|
|
||||||
if (hidden === 'hidden') search_query.and.push({ field: 'hide', op: 'eq', value: 1 });
|
if (hidden === 'hidden')
|
||||||
else if (hidden === 'not_hidden') search_query.and.push({ field: 'hide', op: 'eq', value: 0 });
|
search_query.and.push({ field: 'hide', op: 'eq', value: 1 });
|
||||||
|
else if (hidden === 'not_hidden')
|
||||||
|
search_query.and.push({ field: 'hide', op: 'eq', value: 0 });
|
||||||
|
|
||||||
if (priority === 'priority') search_query.and.push({ field: 'priority', op: 'eq', value: 1 });
|
if (priority === 'priority')
|
||||||
else if (priority === 'not_priority') search_query.and.push({ field: 'priority', op: 'eq', value: 0 });
|
search_query.and.push({ field: 'priority', op: 'eq', value: 1 });
|
||||||
|
else if (priority === 'not_priority')
|
||||||
|
search_query.and.push({ field: 'priority', op: 'eq', value: 0 });
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result_li = await api.search_ae_obj({
|
const result_li = await api.search_ae_obj({
|
||||||
@@ -443,7 +558,10 @@ export async function search__exhibit({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (result_li && Array.isArray(result_li)) {
|
if (result_li && Array.isArray(result_li)) {
|
||||||
const processed = await process_ae_obj__exhibit_props({ obj_li: result_li, log_lvl });
|
const processed = await process_ae_obj__exhibit_props({
|
||||||
|
obj_li: result_li,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
db_instance: db_events,
|
db_instance: db_events,
|
||||||
|
|||||||
@@ -106,11 +106,15 @@ async function _process_generic_props<T extends Record<string, any>>({
|
|||||||
(processed_obj as any).exhibitor_notes = '';
|
(processed_obj as any).exhibitor_notes = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
(processed_obj as any).tmp_sort_1 = `${group}_${priority}_${sort}_${updated}`;
|
(processed_obj as any).tmp_sort_1 =
|
||||||
(processed_obj as any).tmp_sort_2 = `${group}_${priority}_${sort}_${name}_${updated}`;
|
`${group}_${priority}_${sort}_${updated}`;
|
||||||
|
(processed_obj as any).tmp_sort_2 =
|
||||||
|
`${group}_${priority}_${sort}_${name}_${updated}`;
|
||||||
|
|
||||||
if (specific_processor) {
|
if (specific_processor) {
|
||||||
processed_obj = await Promise.resolve(specific_processor(processed_obj));
|
processed_obj = await Promise.resolve(
|
||||||
|
specific_processor(processed_obj)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
processed_obj_li.push(processed_obj as T);
|
processed_obj_li.push(processed_obj as T);
|
||||||
@@ -151,43 +155,86 @@ export async function load_ae_obj_id__event_exhibit_tracking({
|
|||||||
}): Promise<ae_EventExhibitTracking | null> {
|
}): Promise<ae_EventExhibitTracking | null> {
|
||||||
const start_time = performance.now();
|
const start_time = performance.now();
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`🔎 [Trace] load_ae_obj_id__event_exhibit_tracking: START (id=${exhibit_tracking_id}, try_cache=${try_cache})`);
|
console.log(
|
||||||
|
`🔎 [Trace] load_ae_obj_id__event_exhibit_tracking: START (id=${exhibit_tracking_id}, try_cache=${try_cache})`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. FAST PATH: Return cached data immediately
|
// 1. FAST PATH: Return cached data immediately
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
try {
|
try {
|
||||||
const cached = await db_events.exhibit_tracking.get(exhibit_tracking_id);
|
const cached =
|
||||||
|
await db_events.exhibit_tracking.get(exhibit_tracking_id);
|
||||||
if (cached) {
|
if (cached) {
|
||||||
const elapsed = (performance.now() - start_time).toFixed(2);
|
const elapsed = (performance.now() - start_time).toFixed(2);
|
||||||
if (log_lvl) console.log(`✅ [Trace] load_ae_obj_id: CACHE HIT at ${elapsed}ms. Returning stale lead shell.`);
|
if (log_lvl)
|
||||||
|
console.log(
|
||||||
|
`✅ [Trace] load_ae_obj_id: CACHE HIT at ${elapsed}ms. Returning stale lead shell.`
|
||||||
|
);
|
||||||
|
|
||||||
// Background refresh (non-blocking)
|
// Background refresh (non-blocking)
|
||||||
_refresh_tracking_id_background({ api_cfg, exhibit_tracking_id, view, try_cache, log_lvl: log_lvl > 1 ? log_lvl : 0 });
|
_refresh_tracking_id_background({
|
||||||
|
api_cfg,
|
||||||
|
exhibit_tracking_id,
|
||||||
|
view,
|
||||||
|
try_cache,
|
||||||
|
log_lvl: log_lvl > 1 ? log_lvl : 0
|
||||||
|
});
|
||||||
return cached;
|
return cached;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (log_lvl) console.error(`❌ [Trace] load_ae_obj_id: Cache access error:`, e);
|
if (log_lvl)
|
||||||
|
console.error(
|
||||||
|
`❌ [Trace] load_ae_obj_id: Cache access error:`,
|
||||||
|
e
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. SLOW PATH: Wait for API
|
// 2. SLOW PATH: Wait for API
|
||||||
return await _refresh_tracking_id_background({ api_cfg, exhibit_tracking_id, view, try_cache, log_lvl });
|
return await _refresh_tracking_id_background({
|
||||||
|
api_cfg,
|
||||||
|
exhibit_tracking_id,
|
||||||
|
view,
|
||||||
|
try_cache,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function _refresh_tracking_id_background({ api_cfg, exhibit_tracking_id, view, try_cache, log_lvl }: any) {
|
async function _refresh_tracking_id_background({
|
||||||
|
api_cfg,
|
||||||
|
exhibit_tracking_id,
|
||||||
|
view,
|
||||||
|
try_cache,
|
||||||
|
log_lvl
|
||||||
|
}: any) {
|
||||||
const start_time = performance.now();
|
const start_time = performance.now();
|
||||||
if (typeof navigator !== 'undefined' && !navigator.onLine) return null;
|
if (typeof navigator !== 'undefined' && !navigator.onLine) return null;
|
||||||
try {
|
try {
|
||||||
if (log_lvl) console.log(`📡 [Trace] _refresh_tracking_id: API Fetching id=${exhibit_tracking_id}`);
|
if (log_lvl)
|
||||||
const result = await api.get_ae_obj({ api_cfg, obj_type: 'event_exhibit_tracking', obj_id: exhibit_tracking_id, view, log_lvl });
|
console.log(
|
||||||
|
`📡 [Trace] _refresh_tracking_id: API Fetching id=${exhibit_tracking_id}`
|
||||||
|
);
|
||||||
|
const result = await api.get_ae_obj({
|
||||||
|
api_cfg,
|
||||||
|
obj_type: 'event_exhibit_tracking',
|
||||||
|
obj_id: exhibit_tracking_id,
|
||||||
|
view,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
const processed = await process_ae_obj__exhibit_tracking_props({ obj_li: [result], log_lvl });
|
const processed = await process_ae_obj__exhibit_tracking_props({
|
||||||
|
obj_li: [result],
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
const processed_obj = processed[0];
|
const processed_obj = processed[0];
|
||||||
const elapsed = (performance.now() - start_time).toFixed(2);
|
const elapsed = (performance.now() - start_time).toFixed(2);
|
||||||
|
|
||||||
if (log_lvl) console.log(`📦 [Trace] _refresh_tracking_id: Received from API at ${elapsed}ms`);
|
if (log_lvl)
|
||||||
|
console.log(
|
||||||
|
`📦 [Trace] _refresh_tracking_id: Received from API at ${elapsed}ms`
|
||||||
|
);
|
||||||
|
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
@@ -201,7 +248,11 @@ async function _refresh_tracking_id_background({ api_cfg, exhibit_tracking_id, v
|
|||||||
return processed_obj;
|
return processed_obj;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (log_lvl) console.error(`❌ [Trace] _refresh_tracking_id: API error for id=${exhibit_tracking_id}:`, e);
|
if (log_lvl)
|
||||||
|
console.error(
|
||||||
|
`❌ [Trace] _refresh_tracking_id: API error for id=${exhibit_tracking_id}:`,
|
||||||
|
e
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -238,36 +289,82 @@ export async function load_ae_obj_li__event_exhibit_tracking({
|
|||||||
}): Promise<ae_EventExhibitTracking[]> {
|
}): Promise<ae_EventExhibitTracking[]> {
|
||||||
const start_time = performance.now();
|
const start_time = performance.now();
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`🔎 [Trace] load_ae_obj_li__event_exhibit_tracking: START (exhibit=${exhibit_id}, try_cache=${try_cache})`);
|
console.log(
|
||||||
|
`🔎 [Trace] load_ae_obj_li__event_exhibit_tracking: START (exhibit=${exhibit_id}, try_cache=${try_cache})`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
try {
|
try {
|
||||||
const cached_li = await db_events.exhibit_tracking
|
const cached_li = await db_events.exhibit_tracking
|
||||||
.where('event_exhibit_id').equals(exhibit_id)
|
.where('event_exhibit_id')
|
||||||
|
.equals(exhibit_id)
|
||||||
.toArray();
|
.toArray();
|
||||||
|
|
||||||
if (cached_li && cached_li.length > 0) {
|
if (cached_li && cached_li.length > 0) {
|
||||||
const elapsed = (performance.now() - start_time).toFixed(2);
|
const elapsed = (performance.now() - start_time).toFixed(2);
|
||||||
if (log_lvl) console.log(`✅ [Trace] load_ae_obj_li: CACHE HIT at ${elapsed}ms (${cached_li.length} items).`);
|
if (log_lvl)
|
||||||
|
console.log(
|
||||||
|
`✅ [Trace] load_ae_obj_li: CACHE HIT at ${elapsed}ms (${cached_li.length} items).`
|
||||||
|
);
|
||||||
|
|
||||||
// Background refresh (non-blocking)
|
// Background refresh (non-blocking)
|
||||||
_refresh_tracking_li_background({ api_cfg, exhibit_id, enabled, hidden, view, limit, offset, order_by_li, try_cache, log_lvl: log_lvl > 1 ? log_lvl : 0 });
|
_refresh_tracking_li_background({
|
||||||
|
api_cfg,
|
||||||
|
exhibit_id,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
view,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
order_by_li,
|
||||||
|
try_cache,
|
||||||
|
log_lvl: log_lvl > 1 ? log_lvl : 0
|
||||||
|
});
|
||||||
return cached_li;
|
return cached_li;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (log_lvl) console.error(`❌ [Trace] load_ae_obj_li: Cache access error:`, e);
|
if (log_lvl)
|
||||||
|
console.error(
|
||||||
|
`❌ [Trace] load_ae_obj_li: Cache access error:`,
|
||||||
|
e
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return await _refresh_tracking_li_background({ api_cfg, exhibit_id, enabled, hidden, view, limit, offset, order_by_li, try_cache, log_lvl });
|
return await _refresh_tracking_li_background({
|
||||||
|
api_cfg,
|
||||||
|
exhibit_id,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
view,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
order_by_li,
|
||||||
|
try_cache,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function _refresh_tracking_li_background({ api_cfg, exhibit_id, enabled, hidden, view, limit, offset, order_by_li, try_cache, log_lvl }: any) {
|
async function _refresh_tracking_li_background({
|
||||||
|
api_cfg,
|
||||||
|
exhibit_id,
|
||||||
|
enabled,
|
||||||
|
hidden,
|
||||||
|
view,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
order_by_li,
|
||||||
|
try_cache,
|
||||||
|
log_lvl
|
||||||
|
}: any) {
|
||||||
const start_time = performance.now();
|
const start_time = performance.now();
|
||||||
if (typeof navigator !== 'undefined' && !navigator.onLine) return [];
|
if (typeof navigator !== 'undefined' && !navigator.onLine) return [];
|
||||||
try {
|
try {
|
||||||
if (log_lvl) console.log(`📡 [Trace] _refresh_tracking_li: API Fetching leads for exhibit=${exhibit_id}`);
|
if (log_lvl)
|
||||||
|
console.log(
|
||||||
|
`📡 [Trace] _refresh_tracking_li: API Fetching leads for exhibit=${exhibit_id}`
|
||||||
|
);
|
||||||
const result_li = await api.get_ae_obj_li({
|
const result_li = await api.get_ae_obj_li({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
obj_type: 'event_exhibit_tracking',
|
obj_type: 'event_exhibit_tracking',
|
||||||
@@ -283,9 +380,15 @@ async function _refresh_tracking_li_background({ api_cfg, exhibit_id, enabled, h
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (result_li) {
|
if (result_li) {
|
||||||
const processed = await process_ae_obj__exhibit_tracking_props({ obj_li: result_li, log_lvl });
|
const processed = await process_ae_obj__exhibit_tracking_props({
|
||||||
|
obj_li: result_li,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
const elapsed = (performance.now() - start_time).toFixed(2);
|
const elapsed = (performance.now() - start_time).toFixed(2);
|
||||||
if (log_lvl) console.log(`📦 [Trace] _refresh_tracking_li: Received ${processed.length} items from API at ${elapsed}ms.`);
|
if (log_lvl)
|
||||||
|
console.log(
|
||||||
|
`📦 [Trace] _refresh_tracking_li: Received ${processed.length} items from API at ${elapsed}ms.`
|
||||||
|
);
|
||||||
|
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
@@ -299,7 +402,8 @@ async function _refresh_tracking_li_background({ api_cfg, exhibit_id, enabled, h
|
|||||||
return processed;
|
return processed;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (log_lvl) console.error(`❌ [Trace] _refresh_tracking_li: API error:`, e);
|
if (log_lvl)
|
||||||
|
console.error(`❌ [Trace] _refresh_tracking_li: API error:`, e);
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@@ -308,95 +412,101 @@ async function _refresh_tracking_li_background({ api_cfg, exhibit_id, enabled, h
|
|||||||
* Lead Capture (V3)
|
* Lead Capture (V3)
|
||||||
*/
|
*/
|
||||||
export async function create_ae_obj__exhibit_tracking({
|
export async function create_ae_obj__exhibit_tracking({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
exhibit_id,
|
exhibit_id,
|
||||||
event_badge_id,
|
event_badge_id,
|
||||||
external_person_id,
|
external_person_id,
|
||||||
group,
|
group,
|
||||||
try_cache = true,
|
try_cache = true,
|
||||||
log_lvl = 0
|
log_lvl = 0
|
||||||
}: {
|
}: {
|
||||||
api_cfg: any;
|
api_cfg: any;
|
||||||
exhibit_id: string;
|
exhibit_id: string;
|
||||||
event_badge_id: string;
|
event_badge_id: string;
|
||||||
external_person_id: string;
|
external_person_id: string;
|
||||||
group?: string;
|
group?: string;
|
||||||
try_cache?: boolean;
|
try_cache?: boolean;
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_EventExhibitTracking | null> {
|
}): Promise<ae_EventExhibitTracking | null> {
|
||||||
const result = await api.create_nested_obj({
|
const result = await api.create_nested_obj({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
parent_type: 'event_exhibit',
|
parent_type: 'event_exhibit',
|
||||||
parent_id: exhibit_id,
|
parent_id: exhibit_id,
|
||||||
child_type: 'event_exhibit_tracking',
|
child_type: 'event_exhibit_tracking',
|
||||||
fields: {
|
fields: {
|
||||||
event_badge_id: event_badge_id,
|
event_badge_id: event_badge_id,
|
||||||
external_person_id,
|
external_person_id,
|
||||||
group
|
group
|
||||||
},
|
},
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
const processed = await process_ae_obj__exhibit_tracking_props({ obj_li: [result], log_lvl });
|
const processed = await process_ae_obj__exhibit_tracking_props({
|
||||||
const processed_obj = processed[0];
|
obj_li: [result],
|
||||||
if (try_cache) {
|
log_lvl
|
||||||
await db_save_ae_obj_li__ae_obj({
|
});
|
||||||
db_instance: db_events,
|
const processed_obj = processed[0];
|
||||||
table_name: 'exhibit_tracking',
|
if (try_cache) {
|
||||||
obj_li: [processed_obj],
|
await db_save_ae_obj_li__ae_obj({
|
||||||
properties_to_save: properties_to_save_exhibit_tracking,
|
db_instance: db_events,
|
||||||
log_lvl
|
table_name: 'exhibit_tracking',
|
||||||
});
|
obj_li: [processed_obj],
|
||||||
}
|
properties_to_save: properties_to_save_exhibit_tracking,
|
||||||
return processed_obj;
|
log_lvl
|
||||||
}
|
});
|
||||||
return null;
|
}
|
||||||
|
return processed_obj;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lead Update (V3)
|
* Lead Update (V3)
|
||||||
*/
|
*/
|
||||||
export async function update_ae_obj__exhibit_tracking({
|
export async function update_ae_obj__exhibit_tracking({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
exhibit_id,
|
exhibit_id,
|
||||||
exhibit_tracking_id,
|
exhibit_tracking_id,
|
||||||
data,
|
data,
|
||||||
try_cache = true,
|
try_cache = true,
|
||||||
log_lvl = 0
|
log_lvl = 0
|
||||||
}: {
|
}: {
|
||||||
api_cfg: any;
|
api_cfg: any;
|
||||||
exhibit_id: string;
|
exhibit_id: string;
|
||||||
exhibit_tracking_id: string;
|
exhibit_tracking_id: string;
|
||||||
data: any;
|
data: any;
|
||||||
try_cache?: boolean;
|
try_cache?: boolean;
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_EventExhibitTracking | null> {
|
}): Promise<ae_EventExhibitTracking | null> {
|
||||||
const result = await api.update_nested_obj({
|
const result = await api.update_nested_obj({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
parent_type: 'event_exhibit',
|
parent_type: 'event_exhibit',
|
||||||
parent_id: exhibit_id,
|
parent_id: exhibit_id,
|
||||||
child_type: 'event_exhibit_tracking',
|
child_type: 'event_exhibit_tracking',
|
||||||
child_id: exhibit_tracking_id,
|
child_id: exhibit_tracking_id,
|
||||||
fields: data,
|
fields: data,
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
const processed = await process_ae_obj__exhibit_tracking_props({ obj_li: [result], log_lvl });
|
const processed = await process_ae_obj__exhibit_tracking_props({
|
||||||
const processed_obj = processed[0];
|
obj_li: [result],
|
||||||
if (try_cache) {
|
log_lvl
|
||||||
await db_save_ae_obj_li__ae_obj({
|
});
|
||||||
db_instance: db_events,
|
const processed_obj = processed[0];
|
||||||
table_name: 'exhibit_tracking',
|
if (try_cache) {
|
||||||
obj_li: [processed_obj],
|
await db_save_ae_obj_li__ae_obj({
|
||||||
properties_to_save: properties_to_save_exhibit_tracking,
|
db_instance: db_events,
|
||||||
log_lvl
|
table_name: 'exhibit_tracking',
|
||||||
});
|
obj_li: [processed_obj],
|
||||||
}
|
properties_to_save: properties_to_save_exhibit_tracking,
|
||||||
return processed_obj;
|
log_lvl
|
||||||
}
|
});
|
||||||
return null;
|
}
|
||||||
|
return processed_obj;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -428,13 +538,15 @@ export async function download_export__event_exhibit_tracking({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}) {
|
}) {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** download_export__event_exhibit_tracking() *** exhibit_id=${exhibit_id}`);
|
console.log(
|
||||||
|
`*** download_export__event_exhibit_tracking() *** exhibit_id=${exhibit_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const endpoint = `/v3/action/event_exhibit/${exhibit_id}/tracking_export`;
|
const endpoint = `/v3/action/event_exhibit/${exhibit_id}/tracking_export`;
|
||||||
const params: key_val = {
|
const params: key_val = {
|
||||||
file_type,
|
file_type,
|
||||||
return_file: 'true' // V3 convention: string 'true' for bool query flags
|
return_file: 'true' // V3 convention: string 'true' for bool query flags
|
||||||
};
|
};
|
||||||
|
|
||||||
return await api.get_object({
|
return await api.get_object({
|
||||||
@@ -485,7 +597,9 @@ export async function search__exhibit_tracking({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_EventExhibitTracking[]> {
|
}): Promise<ae_EventExhibitTracking[]> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** search__exhibit_tracking() *** exhibit_id=${event_exhibit_id} ft=${fulltext_search_qry_str}`);
|
console.log(
|
||||||
|
`*** search__exhibit_tracking() *** exhibit_id=${event_exhibit_id} ft=${fulltext_search_qry_str}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!event_id || !event_exhibit_id) return [];
|
if (!event_id || !event_exhibit_id) return [];
|
||||||
@@ -498,15 +612,30 @@ export async function search__exhibit_tracking({
|
|||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
if (qry_group) search_query.and.push({ field: 'group', op: 'eq', value: qry_group });
|
if (qry_group)
|
||||||
if (qry_external_person_id) search_query.and.push({ field: 'external_person_id', op: 'eq', value: qry_external_person_id });
|
search_query.and.push({ field: 'group', op: 'eq', value: qry_group });
|
||||||
if (qry_badge_id) search_query.and.push({ field: 'event_badge_id', op: 'eq', value: qry_badge_id });
|
if (qry_external_person_id)
|
||||||
|
search_query.and.push({
|
||||||
|
field: 'external_person_id',
|
||||||
|
op: 'eq',
|
||||||
|
value: qry_external_person_id
|
||||||
|
});
|
||||||
|
if (qry_badge_id)
|
||||||
|
search_query.and.push({
|
||||||
|
field: 'event_badge_id',
|
||||||
|
op: 'eq',
|
||||||
|
value: qry_badge_id
|
||||||
|
});
|
||||||
|
|
||||||
if (enabled === 'enabled') search_query.and.push({ field: 'enable', op: 'eq', value: 1 });
|
if (enabled === 'enabled')
|
||||||
else if (enabled === 'not_enabled') search_query.and.push({ field: 'enable', op: 'eq', value: 0 });
|
search_query.and.push({ field: 'enable', op: 'eq', value: 1 });
|
||||||
|
else if (enabled === 'not_enabled')
|
||||||
|
search_query.and.push({ field: 'enable', op: 'eq', value: 0 });
|
||||||
|
|
||||||
if (hidden === 'hidden') search_query.and.push({ field: 'hide', op: 'eq', value: 1 });
|
if (hidden === 'hidden')
|
||||||
else if (hidden === 'not_hidden') search_query.and.push({ field: 'hide', op: 'eq', value: 0 });
|
search_query.and.push({ field: 'hide', op: 'eq', value: 1 });
|
||||||
|
else if (hidden === 'not_hidden')
|
||||||
|
search_query.and.push({ field: 'hide', op: 'eq', value: 0 });
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result_li = await api.search_ae_obj({
|
const result_li = await api.search_ae_obj({
|
||||||
@@ -525,7 +654,10 @@ export async function search__exhibit_tracking({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (result_li && Array.isArray(result_li)) {
|
if (result_li && Array.isArray(result_li)) {
|
||||||
const processed = await process_ae_obj__exhibit_tracking_props({ obj_li: result_li, log_lvl });
|
const processed = await process_ae_obj__exhibit_tracking_props({
|
||||||
|
obj_li: result_li,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
db_instance: db_events,
|
db_instance: db_events,
|
||||||
|
|||||||
@@ -56,13 +56,18 @@ const export_obj = {
|
|||||||
search__event_badge: event_badge.search__event_badge,
|
search__event_badge: event_badge.search__event_badge,
|
||||||
|
|
||||||
// Event Badge Templates
|
// Event Badge Templates
|
||||||
load_ae_obj_id__event_badge_template: event_badge_template.load_ae_obj_id__event_badge_template,
|
load_ae_obj_id__event_badge_template:
|
||||||
load_ae_obj_li__event_badge_template: event_badge_template.load_ae_obj_li__event_badge_template,
|
event_badge_template.load_ae_obj_id__event_badge_template,
|
||||||
create_ae_obj__event_badge_template: event_badge_template.create_ae_obj__event_badge_template,
|
load_ae_obj_li__event_badge_template:
|
||||||
|
event_badge_template.load_ae_obj_li__event_badge_template,
|
||||||
|
create_ae_obj__event_badge_template:
|
||||||
|
event_badge_template.create_ae_obj__event_badge_template,
|
||||||
delete_ae_obj_id__event_badge_template:
|
delete_ae_obj_id__event_badge_template:
|
||||||
event_badge_template.delete_ae_obj_id__event_badge_template,
|
event_badge_template.delete_ae_obj_id__event_badge_template,
|
||||||
update_ae_obj__event_badge_template: event_badge_template.update_ae_obj__event_badge_template,
|
update_ae_obj__event_badge_template:
|
||||||
search__event_badge_template: event_badge_template.search__event_badge_template,
|
event_badge_template.update_ae_obj__event_badge_template,
|
||||||
|
search__event_badge_template:
|
||||||
|
event_badge_template.search__event_badge_template,
|
||||||
|
|
||||||
// Event Devices
|
// Event Devices
|
||||||
load_ae_obj_id__event_device: event_device.load_ae_obj_id__event_device,
|
load_ae_obj_id__event_device: event_device.load_ae_obj_id__event_device,
|
||||||
@@ -77,53 +82,72 @@ const export_obj = {
|
|||||||
search__exhibit: search__exhibit,
|
search__exhibit: search__exhibit,
|
||||||
create_ae_obj__exhibit: create_ae_obj__exhibit,
|
create_ae_obj__exhibit: create_ae_obj__exhibit,
|
||||||
update_ae_obj__exhibit: update_ae_obj__exhibit,
|
update_ae_obj__exhibit: update_ae_obj__exhibit,
|
||||||
load_ae_obj_id__event_exhibit_tracking: load_ae_obj_id__event_exhibit_tracking,
|
load_ae_obj_id__event_exhibit_tracking:
|
||||||
load_ae_obj_li__event_exhibit_tracking: load_ae_obj_li__event_exhibit_tracking,
|
load_ae_obj_id__event_exhibit_tracking,
|
||||||
|
load_ae_obj_li__event_exhibit_tracking:
|
||||||
|
load_ae_obj_li__event_exhibit_tracking,
|
||||||
search__exhibit_tracking: search__exhibit_tracking,
|
search__exhibit_tracking: search__exhibit_tracking,
|
||||||
create_ae_obj__exhibit_tracking: create_ae_obj__exhibit_tracking,
|
create_ae_obj__exhibit_tracking: create_ae_obj__exhibit_tracking,
|
||||||
update_ae_obj__exhibit_tracking: update_ae_obj__exhibit_tracking,
|
update_ae_obj__exhibit_tracking: update_ae_obj__exhibit_tracking,
|
||||||
download_export__event_exhibit_tracking: download_export__event_exhibit_tracking,
|
download_export__event_exhibit_tracking:
|
||||||
|
download_export__event_exhibit_tracking,
|
||||||
|
|
||||||
// Event Files
|
// Event Files
|
||||||
load_ae_obj_id__event_file: event_file.load_ae_obj_id__event_file,
|
load_ae_obj_id__event_file: event_file.load_ae_obj_id__event_file,
|
||||||
load_ae_obj_li__event_file: event_file.load_ae_obj_li__event_file,
|
load_ae_obj_li__event_file: event_file.load_ae_obj_li__event_file,
|
||||||
create_event_file_obj_from_hosted_file_async: event_file.create_event_file_obj_from_hosted_file_async,
|
create_event_file_obj_from_hosted_file_async:
|
||||||
|
event_file.create_event_file_obj_from_hosted_file_async,
|
||||||
delete_ae_obj_id__event_file: event_file.delete_ae_obj_id__event_file,
|
delete_ae_obj_id__event_file: event_file.delete_ae_obj_id__event_file,
|
||||||
update_ae_obj__event_file: event_file.update_ae_obj__event_file,
|
update_ae_obj__event_file: event_file.update_ae_obj__event_file,
|
||||||
qry__event_file: event_file.qry__event_file,
|
qry__event_file: event_file.qry__event_file,
|
||||||
search__event_file: event_file.search__event_file,
|
search__event_file: event_file.search__event_file,
|
||||||
|
|
||||||
// Event Locations
|
// Event Locations
|
||||||
load_ae_obj_id__event_location: event_location.load_ae_obj_id__event_location,
|
load_ae_obj_id__event_location:
|
||||||
load_ae_obj_li__event_location: event_location.load_ae_obj_li__event_location,
|
event_location.load_ae_obj_id__event_location,
|
||||||
|
load_ae_obj_li__event_location:
|
||||||
|
event_location.load_ae_obj_li__event_location,
|
||||||
create_ae_obj__event_location: event_location.create_ae_obj__event_location,
|
create_ae_obj__event_location: event_location.create_ae_obj__event_location,
|
||||||
delete_ae_obj_id__event_location: event_location.delete_ae_obj_id__event_location,
|
delete_ae_obj_id__event_location:
|
||||||
|
event_location.delete_ae_obj_id__event_location,
|
||||||
update_ae_obj__event_location: event_location.update_ae_obj__event_location,
|
update_ae_obj__event_location: event_location.update_ae_obj__event_location,
|
||||||
|
|
||||||
// Event Sessions
|
// Event Sessions
|
||||||
load_ae_obj_id__event_session: event_session.load_ae_obj_id__event_session,
|
load_ae_obj_id__event_session: event_session.load_ae_obj_id__event_session,
|
||||||
load_ae_obj_li__event_session: event_session.load_ae_obj_li__event_session,
|
load_ae_obj_li__event_session: event_session.load_ae_obj_li__event_session,
|
||||||
create_ae_obj__event_session: event_session.create_ae_obj__event_session,
|
create_ae_obj__event_session: event_session.create_ae_obj__event_session,
|
||||||
delete_ae_obj_id__event_session: event_session.delete_ae_obj_id__event_session,
|
delete_ae_obj_id__event_session:
|
||||||
|
event_session.delete_ae_obj_id__event_session,
|
||||||
update_ae_obj__event_session: event_session.update_ae_obj__event_session,
|
update_ae_obj__event_session: event_session.update_ae_obj__event_session,
|
||||||
qry__event_session: event_session.qry__event_session,
|
qry__event_session: event_session.qry__event_session,
|
||||||
search__event_session: event_session.search__event_session,
|
search__event_session: event_session.search__event_session,
|
||||||
email_sign_in__event_session: event_session.email_sign_in__event_session,
|
email_sign_in__event_session: event_session.email_sign_in__event_session,
|
||||||
|
|
||||||
// Event Presentations
|
// Event Presentations
|
||||||
load_ae_obj_id__event_presentation: event_presentation.load_ae_obj_id__event_presentation,
|
load_ae_obj_id__event_presentation:
|
||||||
load_ae_obj_li__event_presentation: event_presentation.load_ae_obj_li__event_presentation,
|
event_presentation.load_ae_obj_id__event_presentation,
|
||||||
create_ae_obj__event_presentation: event_presentation.create_ae_obj__event_presentation,
|
load_ae_obj_li__event_presentation:
|
||||||
delete_ae_obj_id__event_presentation: event_presentation.delete_ae_obj_id__event_presentation,
|
event_presentation.load_ae_obj_li__event_presentation,
|
||||||
update_ae_obj__event_presentation: event_presentation.update_ae_obj__event_presentation,
|
create_ae_obj__event_presentation:
|
||||||
|
event_presentation.create_ae_obj__event_presentation,
|
||||||
|
delete_ae_obj_id__event_presentation:
|
||||||
|
event_presentation.delete_ae_obj_id__event_presentation,
|
||||||
|
update_ae_obj__event_presentation:
|
||||||
|
event_presentation.update_ae_obj__event_presentation,
|
||||||
|
|
||||||
// Event Presenters
|
// Event Presenters
|
||||||
load_ae_obj_id__event_presenter: event_presenter.load_ae_obj_id__event_presenter,
|
load_ae_obj_id__event_presenter:
|
||||||
load_ae_obj_li__event_presenter: event_presenter.load_ae_obj_li__event_presenter,
|
event_presenter.load_ae_obj_id__event_presenter,
|
||||||
create_ae_obj__event_presenter: event_presenter.create_ae_obj__event_presenter,
|
load_ae_obj_li__event_presenter:
|
||||||
delete_ae_obj_id__event_presenter: event_presenter.delete_ae_obj_id__event_presenter,
|
event_presenter.load_ae_obj_li__event_presenter,
|
||||||
update_ae_obj__event_presenter: event_presenter.update_ae_obj__event_presenter,
|
create_ae_obj__event_presenter:
|
||||||
|
event_presenter.create_ae_obj__event_presenter,
|
||||||
|
delete_ae_obj_id__event_presenter:
|
||||||
|
event_presenter.delete_ae_obj_id__event_presenter,
|
||||||
|
update_ae_obj__event_presenter:
|
||||||
|
event_presenter.update_ae_obj__event_presenter,
|
||||||
search__event_presenter: event_presenter.search__event_presenter,
|
search__event_presenter: event_presenter.search__event_presenter,
|
||||||
email_sign_in__event_presenter: event_presenter.email_sign_in__event_presenter
|
email_sign_in__event_presenter:
|
||||||
|
event_presenter.email_sign_in__event_presenter
|
||||||
};
|
};
|
||||||
export const events_func = export_obj;
|
export const events_func = export_obj;
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
/* --- Badge front --- */
|
/* --- Badge front --- */
|
||||||
|
|
||||||
[data-layout="badge_4x5_fanfold"] .badge_front {
|
[data-layout='badge_4x5_fanfold'] .badge_front {
|
||||||
width: 4in;
|
width: 4in;
|
||||||
min-height: 5in;
|
min-height: 5in;
|
||||||
max-height: 5in;
|
max-height: 5in;
|
||||||
@@ -28,18 +28,18 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Body area: 5in total − ~1in header − ~0.5in footer = ~3.5in for content */
|
/* Body area: 5in total − ~1in header − ~0.5in footer = ~3.5in for content */
|
||||||
[data-layout="badge_4x5_fanfold"] .badge_body {
|
[data-layout='badge_4x5_fanfold'] .badge_body {
|
||||||
max-height: 3.5in;
|
max-height: 3.5in;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --- Badge back --- */
|
/* --- Badge back --- */
|
||||||
|
|
||||||
[data-layout="badge_4x5_fanfold"] .badge_back {
|
[data-layout='badge_4x5_fanfold'] .badge_back {
|
||||||
width: 4in;
|
width: 4in;
|
||||||
min-height: 5in;
|
min-height: 5in;
|
||||||
max-height: 5in;
|
max-height: 5in;
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-layout="badge_4x5_fanfold"] .badge_back_content {
|
[data-layout='badge_4x5_fanfold'] .badge_back_content {
|
||||||
max-height: 4.5in;
|
max-height: 4.5in;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,19 +16,19 @@
|
|||||||
|
|
||||||
/* --- Badge front --- */
|
/* --- Badge front --- */
|
||||||
|
|
||||||
[data-layout="badge_3.5x5.5_pvc"] .badge_front {
|
[data-layout='badge_3.5x5.5_pvc'] .badge_front {
|
||||||
width: 3.5in;
|
width: 3.5in;
|
||||||
min-height: 5.5in;
|
min-height: 5.5in;
|
||||||
max-height: 5.5in;
|
max-height: 5.5in;
|
||||||
|
|
||||||
/* debug */
|
/* debug */
|
||||||
/* outline: thick solid orange; */
|
/* outline: thick solid orange; */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Outer wrapper: remove the generic 4×6 fanfold defaults so the blue dashed
|
/* Outer wrapper: remove the generic 4×6 fanfold defaults so the blue dashed
|
||||||
outline hugs the card tightly. The badge_front CSS above supplies the exact
|
outline hugs the card tightly. The badge_front CSS above supplies the exact
|
||||||
3.5×5.5in size; wrapper just needs to fit it with no extra space. */
|
3.5×5.5in size; wrapper just needs to fit it with no extra space. */
|
||||||
[data-layout="badge_3.5x5.5_pvc"].event_badge_wrapper {
|
[data-layout='badge_3.5x5.5_pvc'].event_badge_wrapper {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
gap: 0;
|
gap: 0;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media print {
|
@media print {
|
||||||
[data-layout="badge_3.5x5.5_pvc"].event_badge_wrapper {
|
[data-layout='badge_3.5x5.5_pvc'].event_badge_wrapper {
|
||||||
width: 3.5in !important;
|
width: 3.5in !important;
|
||||||
height: 5.5in !important;
|
height: 5.5in !important;
|
||||||
max-width: 3.5in !important;
|
max-width: 3.5in !important;
|
||||||
|
|||||||
@@ -829,7 +829,7 @@ export class MySubClassedDexie extends Dexie {
|
|||||||
constructor() {
|
constructor() {
|
||||||
super('ae_events_db');
|
super('ae_events_db');
|
||||||
this.version(6).stores({
|
this.version(6).stores({
|
||||||
// NO LONGER USE "_random"
|
// NO LONGER USE "_random"
|
||||||
event: `
|
event: `
|
||||||
id, event_id, event_id_random,
|
id, event_id, event_id_random,
|
||||||
code,
|
code,
|
||||||
|
|||||||
@@ -817,7 +817,10 @@ async function _process_generic_props<T extends Record<string, any>>({
|
|||||||
const group = processed_obj.group ?? '0';
|
const group = processed_obj.group ?? '0';
|
||||||
const priority = processed_obj.priority ? 1 : 0;
|
const priority = processed_obj.priority ? 1 : 0;
|
||||||
const sort = processed_obj.sort ?? '0';
|
const sort = processed_obj.sort ?? '0';
|
||||||
const updated = processed_obj.updated_on ?? processed_obj.created_on ?? new Date(0).toISOString();
|
const updated =
|
||||||
|
processed_obj.updated_on ??
|
||||||
|
processed_obj.created_on ??
|
||||||
|
new Date(0).toISOString();
|
||||||
const name = processed_obj.name ?? '';
|
const name = processed_obj.name ?? '';
|
||||||
|
|
||||||
(processed_obj as any).tmp_sort_1 =
|
(processed_obj as any).tmp_sort_1 =
|
||||||
@@ -862,7 +865,8 @@ export async function process_ae_obj__journal_props({
|
|||||||
obj.cfg_json = obj.cfg_json ?? {};
|
obj.cfg_json = obj.cfg_json ?? {};
|
||||||
obj.data_json = obj.data_json ?? {};
|
obj.data_json = obj.data_json ?? {};
|
||||||
|
|
||||||
const updated = obj.updated_on ?? obj.created_on ?? new Date(0).toISOString();
|
const updated =
|
||||||
|
obj.updated_on ?? obj.created_on ?? new Date(0).toISOString();
|
||||||
obj.tmp_sort_3 = `${obj.group ?? '0'}_${obj.priority ? 1 : 0}_${obj.sort ?? '0'}_${
|
obj.tmp_sort_3 = `${obj.group ?? '0'}_${obj.priority ? 1 : 0}_${obj.sort ?? '0'}_${
|
||||||
obj.name
|
obj.name
|
||||||
}_${updated}`;
|
}_${updated}`;
|
||||||
|
|||||||
@@ -942,7 +942,10 @@ async function _process_generic_props<T extends Record<string, any>>({
|
|||||||
const group = processed_obj.group ?? '0';
|
const group = processed_obj.group ?? '0';
|
||||||
const priority = processed_obj.priority ? 1 : 0;
|
const priority = processed_obj.priority ? 1 : 0;
|
||||||
const sort = processed_obj.sort ?? '0';
|
const sort = processed_obj.sort ?? '0';
|
||||||
const updated = processed_obj.updated_on ?? processed_obj.created_on ?? new Date(0).toISOString();
|
const updated =
|
||||||
|
processed_obj.updated_on ??
|
||||||
|
processed_obj.created_on ??
|
||||||
|
new Date(0).toISOString();
|
||||||
const name = processed_obj.name ?? '';
|
const name = processed_obj.name ?? '';
|
||||||
|
|
||||||
(processed_obj as any).tmp_sort_1 =
|
(processed_obj as any).tmp_sort_1 =
|
||||||
@@ -1026,7 +1029,8 @@ export async function process_ae_obj__journal_entry_props({
|
|||||||
|
|
||||||
// Journal entry-specific computed sort fields, overriding generic ones if needed
|
// Journal entry-specific computed sort fields, overriding generic ones if needed
|
||||||
const sort_val = (obj.sort ?? 0).toString().padStart(3, '0');
|
const sort_val = (obj.sort ?? 0).toString().padStart(3, '0');
|
||||||
const updated = obj.updated_on ?? obj.created_on ?? new Date(0).toISOString();
|
const updated =
|
||||||
|
obj.updated_on ?? obj.created_on ?? new Date(0).toISOString();
|
||||||
obj.tmp_sort_1 = `${obj.group ?? ''}_${obj.priority ? '1' : '0'}_${
|
obj.tmp_sort_1 = `${obj.group ?? ''}_${obj.priority ? '1' : '0'}_${
|
||||||
sort_val
|
sort_val
|
||||||
}_${updated}`;
|
}_${updated}`;
|
||||||
|
|||||||
@@ -74,18 +74,19 @@ export async function load_ae_obj_id__post({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (inc_comment_li && ae_promises.load__post_obj) {
|
if (inc_comment_li && ae_promises.load__post_obj) {
|
||||||
ae_promises.load__post_obj.post_comment_li = await load_ae_obj_li__post_comment({
|
ae_promises.load__post_obj.post_comment_li =
|
||||||
api_cfg: api_cfg,
|
await load_ae_obj_li__post_comment({
|
||||||
for_obj_type: 'post',
|
api_cfg: api_cfg,
|
||||||
for_obj_id: post_id,
|
for_obj_type: 'post',
|
||||||
enabled,
|
for_obj_id: post_id,
|
||||||
hidden,
|
enabled,
|
||||||
limit,
|
hidden,
|
||||||
offset,
|
limit,
|
||||||
params,
|
offset,
|
||||||
try_cache,
|
params,
|
||||||
log_lvl
|
try_cache,
|
||||||
});
|
log_lvl
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return ae_promises.load__post_obj;
|
return ae_promises.load__post_obj;
|
||||||
@@ -151,7 +152,8 @@ export async function load_ae_obj_li__post({
|
|||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
const processed_obj_li = await process_ae_obj__post_props({
|
const processed_obj_li = await process_ae_obj__post_props({
|
||||||
obj_li: post_obj_li_get_result,
|
obj_li: post_obj_li_get_result,
|
||||||
account_id: for_obj_type === 'account' ? for_obj_id : undefined,
|
account_id:
|
||||||
|
for_obj_type === 'account' ? for_obj_id : undefined,
|
||||||
log_lvl: log_lvl
|
log_lvl: log_lvl
|
||||||
});
|
});
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
@@ -171,18 +173,19 @@ export async function load_ae_obj_li__post({
|
|||||||
if (inc_comment_li && ae_promises.load__post_obj_li) {
|
if (inc_comment_li && ae_promises.load__post_obj_li) {
|
||||||
for (let i = 0; i < ae_promises.load__post_obj_li.length; i++) {
|
for (let i = 0; i < ae_promises.load__post_obj_li.length; i++) {
|
||||||
const post_obj = ae_promises.load__post_obj_li[i];
|
const post_obj = ae_promises.load__post_obj_li[i];
|
||||||
ae_promises.load__post_obj_li[i].post_comment_li = await load_ae_obj_li__post_comment({
|
ae_promises.load__post_obj_li[i].post_comment_li =
|
||||||
api_cfg: api_cfg,
|
await load_ae_obj_li__post_comment({
|
||||||
for_obj_type: 'post',
|
api_cfg: api_cfg,
|
||||||
for_obj_id: post_obj.post_id,
|
for_obj_type: 'post',
|
||||||
enabled,
|
for_obj_id: post_obj.post_id,
|
||||||
hidden,
|
enabled,
|
||||||
limit,
|
hidden,
|
||||||
offset,
|
limit,
|
||||||
params,
|
offset,
|
||||||
try_cache,
|
params,
|
||||||
log_lvl
|
try_cache,
|
||||||
});
|
log_lvl
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,7 +294,10 @@ export async function update_ae_obj__post({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_Post | null> {
|
}): Promise<ae_Post | null> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** update_ae_obj__post() *** post_id=${post_id}`, data_kv);
|
console.log(
|
||||||
|
`*** update_ae_obj__post() *** post_id=${post_id}`,
|
||||||
|
data_kv
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await api.update_ae_obj({
|
const result = await api.update_ae_obj({
|
||||||
@@ -358,7 +364,11 @@ export async function qry__post({
|
|||||||
const search_query: any = { and: [] };
|
const search_query: any = { and: [] };
|
||||||
|
|
||||||
if (account_id) {
|
if (account_id) {
|
||||||
search_query.and.push({ field: 'account_id', op: 'eq', value: account_id });
|
search_query.and.push({
|
||||||
|
field: 'account_id',
|
||||||
|
op: 'eq',
|
||||||
|
value: account_id
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qry_str) {
|
if (qry_str) {
|
||||||
@@ -366,7 +376,11 @@ export async function qry__post({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (qry_person_id) {
|
if (qry_person_id) {
|
||||||
search_query.and.push({ field: 'external_person_id', op: 'eq', value: qry_person_id });
|
search_query.and.push({
|
||||||
|
field: 'external_person_id',
|
||||||
|
op: 'eq',
|
||||||
|
value: qry_person_id
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (qry_archive_on) {
|
// if (qry_archive_on) {
|
||||||
@@ -428,18 +442,19 @@ export async function qry__post({
|
|||||||
if (inc_comment_li && ae_promises.load__post_obj_li) {
|
if (inc_comment_li && ae_promises.load__post_obj_li) {
|
||||||
for (let i = 0; i < ae_promises.load__post_obj_li.length; i++) {
|
for (let i = 0; i < ae_promises.load__post_obj_li.length; i++) {
|
||||||
const post_obj = ae_promises.load__post_obj_li[i];
|
const post_obj = ae_promises.load__post_obj_li[i];
|
||||||
ae_promises.load__post_obj_li[i].post_comment_li = await load_ae_obj_li__post_comment({
|
ae_promises.load__post_obj_li[i].post_comment_li =
|
||||||
api_cfg: api_cfg,
|
await load_ae_obj_li__post_comment({
|
||||||
for_obj_type: 'post',
|
api_cfg: api_cfg,
|
||||||
for_obj_id: post_obj.post_id,
|
for_obj_type: 'post',
|
||||||
enabled,
|
for_obj_id: post_obj.post_id,
|
||||||
hidden,
|
enabled,
|
||||||
limit,
|
hidden,
|
||||||
offset,
|
limit,
|
||||||
// params,
|
offset,
|
||||||
try_cache: true, // Always cache comments if we are caching posts
|
// params,
|
||||||
log_lvl
|
try_cache: true, // Always cache comments if we are caching posts
|
||||||
});
|
log_lvl
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -512,14 +527,21 @@ async function _process_generic_props<T extends Record<string, any>>({
|
|||||||
const group = processed_obj.group ?? '0';
|
const group = processed_obj.group ?? '0';
|
||||||
const priority = processed_obj.priority ? 1 : 0;
|
const priority = processed_obj.priority ? 1 : 0;
|
||||||
const sort = processed_obj.sort ?? '0';
|
const sort = processed_obj.sort ?? '0';
|
||||||
const updated = processed_obj.updated_on ?? processed_obj.created_on ?? new Date(0).toISOString();
|
const updated =
|
||||||
|
processed_obj.updated_on ??
|
||||||
|
processed_obj.created_on ??
|
||||||
|
new Date(0).toISOString();
|
||||||
const name = processed_obj.username ?? processed_obj.name ?? '';
|
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_1 =
|
||||||
(processed_obj as any).tmp_sort_2 = `${group}_${priority}_${sort}_${name}_${updated}`;
|
`${group}_${priority}_${sort}_${updated}`;
|
||||||
|
(processed_obj as any).tmp_sort_2 =
|
||||||
|
`${group}_${priority}_${sort}_${name}_${updated}`;
|
||||||
|
|
||||||
if (specific_processor) {
|
if (specific_processor) {
|
||||||
processed_obj = await Promise.resolve(specific_processor(processed_obj));
|
processed_obj = await Promise.resolve(
|
||||||
|
specific_processor(processed_obj)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
processed_obj_li.push(processed_obj as T);
|
processed_obj_li.push(processed_obj as T);
|
||||||
@@ -549,7 +571,8 @@ export async function process_ae_obj__post_props({
|
|||||||
}
|
}
|
||||||
obj.name = obj.title;
|
obj.name = obj.title;
|
||||||
const sort_val = (obj.sort ?? 0).toString().padStart(3, '0');
|
const sort_val = (obj.sort ?? 0).toString().padStart(3, '0');
|
||||||
const updated = obj.updated_on ?? obj.created_on ?? new Date(0).toISOString();
|
const updated =
|
||||||
|
obj.updated_on ?? obj.created_on ?? new Date(0).toISOString();
|
||||||
obj.tmp_sort_1 = `${obj.group ?? ''}_${obj.priority ? '1' : '0'}_${
|
obj.tmp_sort_1 = `${obj.group ?? ''}_${obj.priority ? '1' : '0'}_${
|
||||||
sort_val
|
sort_val
|
||||||
}_${updated}`;
|
}_${updated}`;
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ export async function load_ae_obj_id__post_comment({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_PostComment | null> {
|
}): Promise<ae_PostComment | null> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** load_ae_obj_id__post_comment() *** post_comment_id=${post_comment_id}`);
|
console.log(
|
||||||
|
`*** load_ae_obj_id__post_comment() *** post_comment_id=${post_comment_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ae_promises.load__post_comment_obj = await api
|
ae_promises.load__post_comment_obj = await api
|
||||||
@@ -39,10 +41,11 @@ export async function load_ae_obj_id__post_comment({
|
|||||||
.then(async function (post_comment_obj_get_result) {
|
.then(async function (post_comment_obj_get_result) {
|
||||||
if (post_comment_obj_get_result) {
|
if (post_comment_obj_get_result) {
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
const processed_obj_li = await process_ae_obj__post_comment_props({
|
const processed_obj_li =
|
||||||
obj_li: [post_comment_obj_get_result],
|
await process_ae_obj__post_comment_props({
|
||||||
log_lvl: log_lvl
|
obj_li: [post_comment_obj_get_result],
|
||||||
});
|
log_lvl: log_lvl
|
||||||
|
});
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
db_instance: db_posts,
|
db_instance: db_posts,
|
||||||
table_name: 'comment',
|
table_name: 'comment',
|
||||||
@@ -121,10 +124,11 @@ export async function load_ae_obj_li__post_comment({
|
|||||||
.then(async function (post_comment_obj_li_get_result) {
|
.then(async function (post_comment_obj_li_get_result) {
|
||||||
if (post_comment_obj_li_get_result) {
|
if (post_comment_obj_li_get_result) {
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
const processed_obj_li = await process_ae_obj__post_comment_props({
|
const processed_obj_li =
|
||||||
obj_li: post_comment_obj_li_get_result,
|
await process_ae_obj__post_comment_props({
|
||||||
log_lvl: log_lvl
|
obj_li: post_comment_obj_li_get_result,
|
||||||
});
|
log_lvl: log_lvl
|
||||||
|
});
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
db_instance: db_posts,
|
db_instance: db_posts,
|
||||||
table_name: 'comment',
|
table_name: 'comment',
|
||||||
@@ -161,7 +165,9 @@ export async function create_ae_obj__post_comment({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_PostComment | null> {
|
}): Promise<ae_PostComment | null> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** create_ae_obj__post_comment() *** account_id=${account_id} post_id=${post_id}`);
|
console.log(
|
||||||
|
`*** create_ae_obj__post_comment() *** account_id=${account_id} post_id=${post_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await api.create_nested_obj({
|
const result = await api.create_nested_obj({
|
||||||
@@ -212,7 +218,9 @@ export async function delete_ae_obj_id__post_comment({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}) {
|
}) {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** delete_ae_obj_id__post_comment() *** post_comment_id=${post_comment_id}`);
|
console.log(
|
||||||
|
`*** delete_ae_obj_id__post_comment() *** post_comment_id=${post_comment_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await api.delete_ae_obj({
|
const result = await api.delete_ae_obj({
|
||||||
@@ -248,7 +256,10 @@ export async function update_ae_obj__post_comment({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_PostComment | null> {
|
}): Promise<ae_PostComment | null> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** update_ae_obj__post_comment() *** post_comment_id=${post_comment_id}`, data_kv);
|
console.log(
|
||||||
|
`*** update_ae_obj__post_comment() *** post_comment_id=${post_comment_id}`,
|
||||||
|
data_kv
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await api.update_ae_obj({
|
const result = await api.update_ae_obj({
|
||||||
@@ -336,14 +347,21 @@ async function _process_generic_props<T extends Record<string, any>>({
|
|||||||
const group = processed_obj.group ?? '0';
|
const group = processed_obj.group ?? '0';
|
||||||
const priority = processed_obj.priority ? 1 : 0;
|
const priority = processed_obj.priority ? 1 : 0;
|
||||||
const sort = processed_obj.sort ?? '0';
|
const sort = processed_obj.sort ?? '0';
|
||||||
const updated = processed_obj.updated_on ?? processed_obj.created_on ?? new Date(0).toISOString();
|
const updated =
|
||||||
|
processed_obj.updated_on ??
|
||||||
|
processed_obj.created_on ??
|
||||||
|
new Date(0).toISOString();
|
||||||
const name = processed_obj.name ?? '';
|
const name = processed_obj.name ?? '';
|
||||||
|
|
||||||
(processed_obj as any).tmp_sort_1 = `${group}_${priority}_${sort}_${updated}`;
|
(processed_obj as any).tmp_sort_1 =
|
||||||
(processed_obj as any).tmp_sort_2 = `${group}_${priority}_${sort}_${name}_${updated}`;
|
`${group}_${priority}_${sort}_${updated}`;
|
||||||
|
(processed_obj as any).tmp_sort_2 =
|
||||||
|
`${group}_${priority}_${sort}_${name}_${updated}`;
|
||||||
|
|
||||||
if (specific_processor) {
|
if (specific_processor) {
|
||||||
processed_obj = await Promise.resolve(specific_processor(processed_obj));
|
processed_obj = await Promise.resolve(
|
||||||
|
specific_processor(processed_obj)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
processed_obj_li.push(processed_obj as T);
|
processed_obj_li.push(processed_obj as T);
|
||||||
@@ -366,7 +384,8 @@ export async function process_ae_obj__post_comment_props({
|
|||||||
log_lvl,
|
log_lvl,
|
||||||
specific_processor: (obj) => {
|
specific_processor: (obj) => {
|
||||||
const sort_val = (obj.sort ?? 0).toString().padStart(3, '0');
|
const sort_val = (obj.sort ?? 0).toString().padStart(3, '0');
|
||||||
const updated = obj.updated_on ?? obj.created_on ?? new Date(0).toISOString();
|
const updated =
|
||||||
|
obj.updated_on ?? obj.created_on ?? new Date(0).toISOString();
|
||||||
obj.tmp_sort_1 = `${obj.group ?? ''}_${obj.priority ? '1' : '0'}_${
|
obj.tmp_sort_1 = `${obj.group ?? ''}_${obj.priority ? '1' : '0'}_${
|
||||||
sort_val
|
sort_val
|
||||||
}_${updated}`;
|
}_${updated}`;
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
import type { key_val } from '$lib/stores/ae_stores';
|
import type { key_val } from '$lib/stores/ae_stores';
|
||||||
import { api } from '$lib/api/api';
|
import { api } from '$lib/api/api';
|
||||||
import { process_ae_obj__activity_log_props, properties_to_save } from '$lib/ae_core/ae_core__activity_log';
|
import {
|
||||||
|
process_ae_obj__activity_log_props,
|
||||||
|
properties_to_save
|
||||||
|
} from '$lib/ae_core/ae_core__activity_log';
|
||||||
import { db_save_ae_obj_li__ae_obj } from '$lib/ae_core/core__idb_dexie';
|
import { db_save_ae_obj_li__ae_obj } from '$lib/ae_core/core__idb_dexie';
|
||||||
import { db_core } from '$lib/ae_core/db_core';
|
import { db_core } from '$lib/ae_core/db_core';
|
||||||
|
|
||||||
@@ -17,129 +20,144 @@ import { db_core } from '$lib/ae_core/db_core';
|
|||||||
* @returns A structured array of meeting report objects.
|
* @returns A structured array of meeting report objects.
|
||||||
*/
|
*/
|
||||||
export async function qry__jitsi_report({
|
export async function qry__jitsi_report({
|
||||||
api_cfg,
|
api_cfg,
|
||||||
account_id,
|
account_id,
|
||||||
enabled = 'all',
|
enabled = 'all',
|
||||||
hidden = 'all',
|
hidden = 'all',
|
||||||
limit = 500,
|
limit = 500,
|
||||||
try_cache = true,
|
try_cache = true,
|
||||||
log_lvl = 0
|
log_lvl = 0
|
||||||
}: {
|
}: {
|
||||||
api_cfg: any;
|
api_cfg: any;
|
||||||
account_id: string;
|
account_id: string;
|
||||||
enabled?: 'enabled' | 'all' | 'not_enabled' | undefined;
|
enabled?: 'enabled' | 'all' | 'not_enabled' | undefined;
|
||||||
hidden?: 'hidden' | 'all' | 'not_hidden' | undefined;
|
hidden?: 'hidden' | 'all' | 'not_hidden' | undefined;
|
||||||
limit?: number;
|
limit?: number;
|
||||||
try_cache?: boolean;
|
try_cache?: boolean;
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}) {
|
}) {
|
||||||
if (log_lvl) console.log('*** qry__jitsi_report() ***');
|
if (log_lvl) console.log('*** qry__jitsi_report() ***');
|
||||||
|
|
||||||
// Step 1: Query all relevant activity logs from the API.
|
// Step 1: Query all relevant activity logs from the API.
|
||||||
const search_query = {
|
const search_query = {
|
||||||
or: [
|
or: [
|
||||||
{ field: 'name', op: 'eq', value: 'jitsi_meeting_event' },
|
{ field: 'name', op: 'eq', value: 'jitsi_meeting_event' },
|
||||||
{ field: 'name', op: 'eq', value: 'jitsi_meeting_stats' }
|
{ field: 'name', op: 'eq', value: 'jitsi_meeting_stats' }
|
||||||
],
|
],
|
||||||
and: [
|
and: [{ field: 'account_id_random', op: 'eq', value: account_id }]
|
||||||
{ field: 'account_id_random', op: 'eq', value: account_id }
|
};
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
const result = await api.search_ae_obj({
|
const result = await api.search_ae_obj({
|
||||||
api_cfg: api_cfg,
|
api_cfg: api_cfg,
|
||||||
obj_type: 'activity_log',
|
obj_type: 'activity_log',
|
||||||
search_query,
|
search_query,
|
||||||
headers: { 'x-account-id': account_id },
|
headers: { 'x-account-id': account_id },
|
||||||
enabled,
|
enabled,
|
||||||
hidden,
|
hidden,
|
||||||
limit,
|
limit,
|
||||||
log_lvl: log_lvl
|
log_lvl: log_lvl
|
||||||
});
|
});
|
||||||
|
|
||||||
// Handle potential V3 API envelope
|
// Handle potential V3 API envelope
|
||||||
let flat_log_list: any[] = [];
|
let flat_log_list: any[] = [];
|
||||||
if (Array.isArray(result)) {
|
if (Array.isArray(result)) {
|
||||||
flat_log_list = result;
|
flat_log_list = result;
|
||||||
} else if (result && typeof result === 'object' && Array.isArray((result as any).data)) {
|
} else if (
|
||||||
flat_log_list = (result as any).data;
|
result &&
|
||||||
}
|
typeof result === 'object' &&
|
||||||
|
Array.isArray((result as any).data)
|
||||||
|
) {
|
||||||
|
flat_log_list = (result as any).data;
|
||||||
|
}
|
||||||
|
|
||||||
if (!flat_log_list || !Array.isArray(flat_log_list) || flat_log_list.length === 0) {
|
if (
|
||||||
if (log_lvl) console.log('No Jitsi activity logs found or error occurred.');
|
!flat_log_list ||
|
||||||
return [];
|
!Array.isArray(flat_log_list) ||
|
||||||
}
|
flat_log_list.length === 0
|
||||||
|
) {
|
||||||
|
if (log_lvl)
|
||||||
|
console.log('No Jitsi activity logs found or error occurred.');
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
// Frontier Standard: Process and Save to local cache
|
// Frontier Standard: Process and Save to local cache
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
const processed_obj_li = await process_ae_obj__activity_log_props({
|
const processed_obj_li = await process_ae_obj__activity_log_props({
|
||||||
obj_li: flat_log_list,
|
obj_li: flat_log_list,
|
||||||
log_lvl: log_lvl
|
log_lvl: log_lvl
|
||||||
});
|
});
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
db_instance: db_core,
|
db_instance: db_core,
|
||||||
table_name: 'activity_log',
|
table_name: 'activity_log',
|
||||||
obj_li: processed_obj_li,
|
obj_li: processed_obj_li,
|
||||||
properties_to_save: properties_to_save,
|
properties_to_save: properties_to_save,
|
||||||
log_lvl: log_lvl
|
log_lvl: log_lvl
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 2: Process the flat list into a structured report.
|
// Step 2: Process the flat list into a structured report.
|
||||||
const meetings = new Map<string, any>();
|
const meetings = new Map<string, any>();
|
||||||
|
|
||||||
for (const log of flat_log_list) {
|
for (const log of flat_log_list) {
|
||||||
const meeting_id = log.external_client_id;
|
const meeting_id = log.external_client_id;
|
||||||
if (!meeting_id) continue;
|
if (!meeting_id) continue;
|
||||||
|
|
||||||
// Make sure the name field is prefixed with "jitsi_"
|
// Make sure the name field is prefixed with "jitsi_"
|
||||||
if (!log.name.startsWith('jitsi_')) continue;
|
if (!log.name.startsWith('jitsi_')) continue;
|
||||||
|
|
||||||
// Ensure a base entry for the meeting exists
|
// Ensure a base entry for the meeting exists
|
||||||
if (!meetings.has(meeting_id)) {
|
if (!meetings.has(meeting_id)) {
|
||||||
meetings.set(meeting_id, {
|
meetings.set(meeting_id, {
|
||||||
meeting_id: meeting_id,
|
meeting_id: meeting_id,
|
||||||
room_name: 'Unknown',
|
room_name: 'Unknown',
|
||||||
start_time: log.created_on, // Fallback start time
|
start_time: log.created_on, // Fallback start time
|
||||||
final_duration: '00:00:00',
|
final_duration: '00:00:00',
|
||||||
final_participants: [],
|
final_participants: [],
|
||||||
final_participant_count: 0,
|
final_participant_count: 0,
|
||||||
events: []
|
events: []
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const meeting_report = meetings.get(meeting_id);
|
const meeting_report = meetings.get(meeting_id);
|
||||||
|
|
||||||
if (log.action === 'jitsi_meeting_init') {
|
if (log.action === 'jitsi_meeting_init') {
|
||||||
// This is the main log entry, containing the final state.
|
// This is the main log entry, containing the final state.
|
||||||
meeting_report.room_name = log.description;
|
meeting_report.room_name = log.description;
|
||||||
meeting_report.start_time = log.created_on; // The init log has the true start time
|
meeting_report.start_time = log.created_on; // The init log has the true start time
|
||||||
if (log.meta_json) {
|
if (log.meta_json) {
|
||||||
meeting_report.final_duration = log.meta_json.duration;
|
meeting_report.final_duration = log.meta_json.duration;
|
||||||
meeting_report.final_participants = log.meta_json.participants;
|
meeting_report.final_participants = log.meta_json.participants;
|
||||||
meeting_report.final_participant_count = log.meta_json.participant_count;
|
meeting_report.final_participant_count =
|
||||||
}
|
log.meta_json.participant_count;
|
||||||
} else {
|
}
|
||||||
// This is a discrete event log.
|
} else {
|
||||||
meeting_report.events.push({
|
// This is a discrete event log.
|
||||||
timestamp: log.created_on,
|
meeting_report.events.push({
|
||||||
action: log.action,
|
timestamp: log.created_on,
|
||||||
details: log.meta_json
|
action: log.action,
|
||||||
});
|
details: log.meta_json
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Sort events within each meeting chronologically
|
// Sort events within each meeting chronologically
|
||||||
for (const report of meetings.values()) {
|
for (const report of meetings.values()) {
|
||||||
report.events.sort((a: any, b: any) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
|
report.events.sort(
|
||||||
}
|
(a: any, b: any) =>
|
||||||
|
new Date(a.timestamp).getTime() -
|
||||||
|
new Date(b.timestamp).getTime()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const final_report = Array.from(meetings.values());
|
const final_report = Array.from(meetings.values());
|
||||||
final_report.sort((a, b) => new Date(b.start_time).getTime() - new Date(a.start_time).getTime());
|
final_report.sort(
|
||||||
|
(a, b) =>
|
||||||
|
new Date(b.start_time).getTime() - new Date(a.start_time).getTime()
|
||||||
|
);
|
||||||
|
|
||||||
if (log_lvl) console.log('Final Jitsi report:', final_report);
|
if (log_lvl) console.log('Final Jitsi report:', final_report);
|
||||||
|
|
||||||
return final_report;
|
return final_report;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const load_jitsi_report = qry__jitsi_report;
|
export const load_jitsi_report = qry__jitsi_report;
|
||||||
|
|||||||
@@ -175,11 +175,15 @@ async function _process_generic_props<T extends Record<string, any>>({
|
|||||||
const updated = processed_obj.updated_on ?? processed_obj.created_on;
|
const updated = processed_obj.updated_on ?? processed_obj.created_on;
|
||||||
const name = processed_obj.name ?? '';
|
const name = processed_obj.name ?? '';
|
||||||
|
|
||||||
(processed_obj as any).tmp_sort_1 = `${group}_${priority}_${sort}_${updated}`;
|
(processed_obj as any).tmp_sort_1 =
|
||||||
(processed_obj as any).tmp_sort_2 = `${group}_${priority}_${sort}_${name}_${updated}`;
|
`${group}_${priority}_${sort}_${updated}`;
|
||||||
|
(processed_obj as any).tmp_sort_2 =
|
||||||
|
`${group}_${priority}_${sort}_${name}_${updated}`;
|
||||||
|
|
||||||
if (specific_processor) {
|
if (specific_processor) {
|
||||||
processed_obj = await Promise.resolve(specific_processor(processed_obj));
|
processed_obj = await Promise.resolve(
|
||||||
|
specific_processor(processed_obj)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
processed_obj_li.push(processed_obj as T);
|
processed_obj_li.push(processed_obj as T);
|
||||||
@@ -201,7 +205,9 @@ export async function load_ae_obj_id__sponsorship_cfg({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_SponsorshipCfg | null> {
|
}): Promise<ae_SponsorshipCfg | null> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** load_ae_obj_id__sponsorship_cfg() *** [V3] id=${sponsorship_cfg_id} (SWR)`);
|
console.log(
|
||||||
|
`*** load_ae_obj_id__sponsorship_cfg() *** [V3] id=${sponsorship_cfg_id} (SWR)`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. FAST PATH: Cache hit
|
// 1. FAST PATH: Cache hit
|
||||||
@@ -209,17 +215,32 @@ export async function load_ae_obj_id__sponsorship_cfg({
|
|||||||
try {
|
try {
|
||||||
const cached = await db_sponsorships.cfg.get(sponsorship_cfg_id);
|
const cached = await db_sponsorships.cfg.get(sponsorship_cfg_id);
|
||||||
if (cached) {
|
if (cached) {
|
||||||
_refresh_sponsorship_cfg_id_background({ api_cfg, sponsorship_cfg_id, try_cache, log_lvl: 0 });
|
_refresh_sponsorship_cfg_id_background({
|
||||||
|
api_cfg,
|
||||||
|
sponsorship_cfg_id,
|
||||||
|
try_cache,
|
||||||
|
log_lvl: 0
|
||||||
|
});
|
||||||
return cached as unknown as ae_SponsorshipCfg;
|
return cached as unknown as ae_SponsorshipCfg;
|
||||||
}
|
}
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. SLOW PATH: Wait for API
|
// 2. SLOW PATH: Wait for API
|
||||||
return await _refresh_sponsorship_cfg_id_background({ api_cfg, sponsorship_cfg_id, try_cache, log_lvl });
|
return await _refresh_sponsorship_cfg_id_background({
|
||||||
|
api_cfg,
|
||||||
|
sponsorship_cfg_id,
|
||||||
|
try_cache,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function _refresh_sponsorship_cfg_id_background({ api_cfg, sponsorship_cfg_id, try_cache, log_lvl }: any) {
|
async function _refresh_sponsorship_cfg_id_background({
|
||||||
|
api_cfg,
|
||||||
|
sponsorship_cfg_id,
|
||||||
|
try_cache,
|
||||||
|
log_lvl
|
||||||
|
}: any) {
|
||||||
if (typeof navigator !== 'undefined' && !navigator.onLine) return null;
|
if (typeof navigator !== 'undefined' && !navigator.onLine) return null;
|
||||||
try {
|
try {
|
||||||
const result = await api.get_ae_obj({
|
const result = await api.get_ae_obj({
|
||||||
@@ -230,7 +251,11 @@ async function _refresh_sponsorship_cfg_id_background({ api_cfg, sponsorship_cfg
|
|||||||
});
|
});
|
||||||
if (result) {
|
if (result) {
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
const processed_obj_li = await process_ae_obj__sponsorship_cfg_props({ obj_li: [result], log_lvl });
|
const processed_obj_li =
|
||||||
|
await process_ae_obj__sponsorship_cfg_props({
|
||||||
|
obj_li: [result],
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
db_instance: db_sponsorships,
|
db_instance: db_sponsorships,
|
||||||
table_name: 'cfg',
|
table_name: 'cfg',
|
||||||
@@ -258,25 +283,43 @@ export async function load_ae_obj_id__sponsorship({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_Sponsorship | null> {
|
}): Promise<ae_Sponsorship | null> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** load_ae_obj_id__sponsorship() *** [V3] id=${sponsorship_id} (SWR)`);
|
console.log(
|
||||||
|
`*** load_ae_obj_id__sponsorship() *** [V3] id=${sponsorship_id} (SWR)`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. FAST PATH: Cache hit
|
// 1. FAST PATH: Cache hit
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
try {
|
try {
|
||||||
const cached = await db_sponsorships.sponsorship.get(sponsorship_id);
|
const cached =
|
||||||
|
await db_sponsorships.sponsorship.get(sponsorship_id);
|
||||||
if (cached) {
|
if (cached) {
|
||||||
_refresh_sponsorship_id_background({ api_cfg, sponsorship_id, try_cache, log_lvl: 0 });
|
_refresh_sponsorship_id_background({
|
||||||
|
api_cfg,
|
||||||
|
sponsorship_id,
|
||||||
|
try_cache,
|
||||||
|
log_lvl: 0
|
||||||
|
});
|
||||||
return cached as unknown as ae_Sponsorship;
|
return cached as unknown as ae_Sponsorship;
|
||||||
}
|
}
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. SLOW PATH: Wait for API
|
// 2. SLOW PATH: Wait for API
|
||||||
return await _refresh_sponsorship_id_background({ api_cfg, sponsorship_id, try_cache, log_lvl });
|
return await _refresh_sponsorship_id_background({
|
||||||
|
api_cfg,
|
||||||
|
sponsorship_id,
|
||||||
|
try_cache,
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function _refresh_sponsorship_id_background({ api_cfg, sponsorship_id, try_cache, log_lvl }: any) {
|
async function _refresh_sponsorship_id_background({
|
||||||
|
api_cfg,
|
||||||
|
sponsorship_id,
|
||||||
|
try_cache,
|
||||||
|
log_lvl
|
||||||
|
}: any) {
|
||||||
if (typeof navigator !== 'undefined' && !navigator.onLine) return null;
|
if (typeof navigator !== 'undefined' && !navigator.onLine) return null;
|
||||||
try {
|
try {
|
||||||
const result = await api.get_ae_obj({
|
const result = await api.get_ae_obj({
|
||||||
@@ -287,7 +330,11 @@ async function _refresh_sponsorship_id_background({ api_cfg, sponsorship_id, try
|
|||||||
});
|
});
|
||||||
if (result) {
|
if (result) {
|
||||||
if (try_cache) {
|
if (try_cache) {
|
||||||
const processed_obj_li = await process_ae_obj__sponsorship_props({ obj_li: [result], log_lvl });
|
const processed_obj_li =
|
||||||
|
await process_ae_obj__sponsorship_props({
|
||||||
|
obj_li: [result],
|
||||||
|
log_lvl
|
||||||
|
});
|
||||||
await db_save_ae_obj_li__ae_obj({
|
await db_save_ae_obj_li__ae_obj({
|
||||||
db_instance: db_sponsorships,
|
db_instance: db_sponsorships,
|
||||||
table_name: 'sponsorship',
|
table_name: 'sponsorship',
|
||||||
@@ -332,7 +379,9 @@ export async function load_ae_obj_li__sponsorship({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_Sponsorship[]> {
|
}): Promise<ae_Sponsorship[]> {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** load_ae_obj_li__sponsorship() *** [V3] for=${for_obj_type}:${for_obj_id}`);
|
console.log(
|
||||||
|
`*** load_ae_obj_li__sponsorship() *** [V3] for=${for_obj_type}:${for_obj_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const result_li = await api.get_ae_obj_li({
|
const result_li = await api.get_ae_obj_li({
|
||||||
|
|||||||
@@ -9,7 +9,10 @@ import {
|
|||||||
import { get_obj_li_w_match_prop } from './ae_utils__get_obj_li_w_match_prop';
|
import { get_obj_li_w_match_prop } from './ae_utils__get_obj_li_w_match_prop';
|
||||||
import { file_extension_icon } from './ae_utils__file_extension_icon';
|
import { file_extension_icon } from './ae_utils__file_extension_icon';
|
||||||
import { file_extension_icon_lucide } from './ae_utils__file_extension_icon_lucide';
|
import { file_extension_icon_lucide } from './ae_utils__file_extension_icon_lucide';
|
||||||
import { process_permission_checks, compare_access_levels } from './ae_utils__perm_checks';
|
import {
|
||||||
|
process_permission_checks,
|
||||||
|
compare_access_levels
|
||||||
|
} from './ae_utils__perm_checks';
|
||||||
import { iso_datetime_formatter } from './ae_utils__datetime_format';
|
import { iso_datetime_formatter } from './ae_utils__datetime_format';
|
||||||
import { is_datetime_recent } from './ae_utils__is_datetime_recent';
|
import { is_datetime_recent } from './ae_utils__is_datetime_recent';
|
||||||
import { extract_prefixed_form_data } from './ae_utils__extract_prefixed_form_data';
|
import { extract_prefixed_form_data } from './ae_utils__extract_prefixed_form_data';
|
||||||
@@ -81,7 +84,6 @@ function handle_url_and_message(name: string, value: null | string) {
|
|||||||
// console.log('Message sent to parent (iframe):', message);
|
// console.log('Message sent to parent (iframe):', message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ALERT: Not referenced anywhere -2026-02-03
|
// ALERT: Not referenced anywhere -2026-02-03
|
||||||
function create_a_element({
|
function create_a_element({
|
||||||
account_id,
|
account_id,
|
||||||
|
|||||||
@@ -8,12 +8,22 @@ async function generate_iv() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Updated 2025-05-08
|
// Updated 2025-05-08
|
||||||
export const encrypt_content = async function encrypt_content(content: string, keyData: string) {
|
export const encrypt_content = async function encrypt_content(
|
||||||
|
content: string,
|
||||||
|
keyData: string
|
||||||
|
) {
|
||||||
const iv = await generate_iv();
|
const iv = await generate_iv();
|
||||||
const keyBytes = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(keyData));
|
const keyBytes = await crypto.subtle.digest(
|
||||||
const key = await crypto.subtle.importKey('raw', keyBytes, { name: 'AES-CBC' }, false, [
|
'SHA-256',
|
||||||
'encrypt'
|
new TextEncoder().encode(keyData)
|
||||||
]);
|
);
|
||||||
|
const key = await crypto.subtle.importKey(
|
||||||
|
'raw',
|
||||||
|
keyBytes,
|
||||||
|
{ name: 'AES-CBC' },
|
||||||
|
false,
|
||||||
|
['encrypt']
|
||||||
|
);
|
||||||
const encodedContent = await crypto.subtle.encrypt(
|
const encodedContent = await crypto.subtle.encrypt(
|
||||||
{ name: 'AES-CBC', iv: iv.buffer as ArrayBuffer },
|
{ name: 'AES-CBC', iv: iv.buffer as ArrayBuffer },
|
||||||
key,
|
key,
|
||||||
@@ -52,7 +62,10 @@ export const combine_iv_and_base64 = function combine_iv_and_base64(
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Updated 2025-05-08
|
// Updated 2025-05-08
|
||||||
export const encrypt_wrapper = async function encrypt_wrapper(content: string, keyData: string) {
|
export const encrypt_wrapper = async function encrypt_wrapper(
|
||||||
|
content: string,
|
||||||
|
keyData: string
|
||||||
|
) {
|
||||||
if (!content) {
|
if (!content) {
|
||||||
console.error('No content provided. Returning empty string.');
|
console.error('No content provided. Returning empty string.');
|
||||||
return '';
|
return '';
|
||||||
@@ -73,11 +86,20 @@ export const decrypt_content = async function decrypt_content(
|
|||||||
iv: Uint8Array,
|
iv: Uint8Array,
|
||||||
keyData: string
|
keyData: string
|
||||||
) {
|
) {
|
||||||
const keyBytes = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(keyData));
|
const keyBytes = await crypto.subtle.digest(
|
||||||
const key = await crypto.subtle.importKey('raw', keyBytes, { name: 'AES-CBC' }, false, [
|
'SHA-256',
|
||||||
'decrypt'
|
new TextEncoder().encode(keyData)
|
||||||
]);
|
);
|
||||||
const encryptedContent = Uint8Array.from(atob(base64Content), (c) => c.charCodeAt(0));
|
const key = await crypto.subtle.importKey(
|
||||||
|
'raw',
|
||||||
|
keyBytes,
|
||||||
|
{ name: 'AES-CBC' },
|
||||||
|
false,
|
||||||
|
['decrypt']
|
||||||
|
);
|
||||||
|
const encryptedContent = Uint8Array.from(atob(base64Content), (c) =>
|
||||||
|
c.charCodeAt(0)
|
||||||
|
);
|
||||||
const decryptedContent = await crypto.subtle.decrypt(
|
const decryptedContent = await crypto.subtle.decrypt(
|
||||||
{ name: 'AES-CBC', iv: iv.buffer as ArrayBuffer },
|
{ name: 'AES-CBC', iv: iv.buffer as ArrayBuffer },
|
||||||
key,
|
key,
|
||||||
@@ -89,7 +111,9 @@ export const decrypt_content = async function decrypt_content(
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Updated 2025-05-08
|
// Updated 2025-05-08
|
||||||
export const split_iv_and_base64 = function split_iv_and_base64(combined: string) {
|
export const split_iv_and_base64 = function split_iv_and_base64(
|
||||||
|
combined: string
|
||||||
|
) {
|
||||||
if (!combined) {
|
if (!combined) {
|
||||||
console.error('No combined string provided. Returning empty object.');
|
console.error('No combined string provided. Returning empty object.');
|
||||||
return { iv: new Uint8Array(), base64: '' };
|
return { iv: new Uint8Array(), base64: '' };
|
||||||
@@ -97,7 +121,9 @@ export const split_iv_and_base64 = function split_iv_and_base64(combined: string
|
|||||||
const [iv_hex, encrypted_base64_string] = combined.split(':');
|
const [iv_hex, encrypted_base64_string] = combined.split(':');
|
||||||
const base64 = encrypted_base64_string;
|
const base64 = encrypted_base64_string;
|
||||||
const match_result = iv_hex.match(/.{1,2}/g);
|
const match_result = iv_hex.match(/.{1,2}/g);
|
||||||
const iv = new Uint8Array((match_result || []).map((byte) => parseInt(byte, 16)));
|
const iv = new Uint8Array(
|
||||||
|
(match_result || []).map((byte) => parseInt(byte, 16))
|
||||||
|
);
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`IV: ${iv}; Encrypted:`, base64);
|
console.log(`IV: ${iv}; Encrypted:`, base64);
|
||||||
}
|
}
|
||||||
@@ -105,7 +131,10 @@ export const split_iv_and_base64 = function split_iv_and_base64(combined: string
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Updated 2025-05-15
|
// Updated 2025-05-15
|
||||||
export const decrypt_wrapper = async function decrypt_wrapper(combined: string, keyData: string) {
|
export const decrypt_wrapper = async function decrypt_wrapper(
|
||||||
|
combined: string,
|
||||||
|
keyData: string
|
||||||
|
) {
|
||||||
if (!combined) {
|
if (!combined) {
|
||||||
console.error('No combined string provided. Returning empty string.');
|
console.error('No combined string provided. Returning empty string.');
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -66,7 +66,9 @@ export const iso_datetime_formatter = function iso_datetime_formatter(
|
|||||||
datetime_string = dayjs(raw_datetime).format('MM-DD hh:mm A');
|
datetime_string = dayjs(raw_datetime).format('MM-DD hh:mm A');
|
||||||
break;
|
break;
|
||||||
case 'datetime_iso_tz':
|
case 'datetime_iso_tz':
|
||||||
datetime_string = dayjs(raw_datetime).format('YYYY-MM-DD HH:mm:ss Z');
|
datetime_string = dayjs(raw_datetime).format(
|
||||||
|
'YYYY-MM-DD HH:mm:ss Z'
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case 'datetime_iso_12_no_seconds':
|
case 'datetime_iso_12_no_seconds':
|
||||||
datetime_string = dayjs(raw_datetime).format('YYYY-MM-DD hh:mm A');
|
datetime_string = dayjs(raw_datetime).format('YYYY-MM-DD hh:mm A');
|
||||||
@@ -75,7 +77,9 @@ export const iso_datetime_formatter = function iso_datetime_formatter(
|
|||||||
// datetime_string = dayjs(raw_datetime).format('YYYY-MM-DD hh:mm A');
|
// datetime_string = dayjs(raw_datetime).format('YYYY-MM-DD hh:mm A');
|
||||||
// break;
|
// break;
|
||||||
case 'datetime_us':
|
case 'datetime_us':
|
||||||
datetime_string = dayjs(raw_datetime).format('MM/DD/YYYY hh:mm:ss A');
|
datetime_string = dayjs(raw_datetime).format(
|
||||||
|
'MM/DD/YYYY hh:mm:ss A'
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case 'datetime_short':
|
case 'datetime_short':
|
||||||
datetime_string = dayjs(raw_datetime).format('MMM D, YY HH:mm');
|
datetime_string = dayjs(raw_datetime).format('MMM D, YY HH:mm');
|
||||||
@@ -93,13 +97,17 @@ export const iso_datetime_formatter = function iso_datetime_formatter(
|
|||||||
datetime_string = dayjs(raw_datetime).format('MMMM D, YYYY HH:mm');
|
datetime_string = dayjs(raw_datetime).format('MMMM D, YYYY HH:mm');
|
||||||
break;
|
break;
|
||||||
case 'datetime_12_long':
|
case 'datetime_12_long':
|
||||||
datetime_string = dayjs(raw_datetime).format('MMMM D, YYYY hh:mm A');
|
datetime_string = dayjs(raw_datetime).format(
|
||||||
|
'MMMM D, YYYY hh:mm A'
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case 'datetime_medium_sec':
|
case 'datetime_medium_sec':
|
||||||
datetime_string = dayjs(raw_datetime).format('MMM D, YYYY H:mm:ss');
|
datetime_string = dayjs(raw_datetime).format('MMM D, YYYY H:mm:ss');
|
||||||
break;
|
break;
|
||||||
case 'datetime_12_medium_sec':
|
case 'datetime_12_medium_sec':
|
||||||
datetime_string = dayjs(raw_datetime).format('MMM D, YYYY h:mm:ss A');
|
datetime_string = dayjs(raw_datetime).format(
|
||||||
|
'MMM D, YYYY h:mm:ss A'
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case 'datetime_short_month':
|
case 'datetime_short_month':
|
||||||
datetime_string = dayjs(raw_datetime).format('MMM D hh:mm A');
|
datetime_string = dayjs(raw_datetime).format('MMM D hh:mm A');
|
||||||
|
|||||||
@@ -50,7 +50,9 @@ export const extract_prefixed_form_data = function extract_prefixed_form_data({
|
|||||||
for (const field of form_data) {
|
for (const field of form_data) {
|
||||||
let [obj_prop_name, obj_prop_value] = field;
|
let [obj_prop_name, obj_prop_value] = field;
|
||||||
if (log_lvl > 1) {
|
if (log_lvl > 1) {
|
||||||
console.log(`${obj_prop_name}: ${obj_prop_value} type=${typeof obj_prop_value}`);
|
console.log(
|
||||||
|
`${obj_prop_name}: ${obj_prop_value} type=${typeof obj_prop_value}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trim string values if needed
|
// Trim string values if needed
|
||||||
@@ -83,19 +85,31 @@ export const extract_prefixed_form_data = function extract_prefixed_form_data({
|
|||||||
// if (obj_prop_name.startsWith(prefix)) {
|
// if (obj_prop_name.startsWith(prefix)) {
|
||||||
obj_prop_name = obj_prop_name.replace(prefix, '');
|
obj_prop_name = obj_prop_name.replace(prefix, '');
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`Checking: (${prefix})${obj_prop_name} value=${obj_prop_value}`);
|
console.log(
|
||||||
|
`Checking: (${prefix})${obj_prop_name} value=${obj_prop_value}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (rm_empty_id && obj_prop_name.endsWith('id_random') && !obj_prop_value) {
|
if (
|
||||||
|
rm_empty_id &&
|
||||||
|
obj_prop_name.endsWith('id_random') &&
|
||||||
|
!obj_prop_value
|
||||||
|
) {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`Match but empty *_id_random. Ignoring/removing: ${obj_prop_name}`);
|
console.log(
|
||||||
|
`Match but empty *_id_random. Ignoring/removing: ${obj_prop_name}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else if (rm_empty && !obj_prop_value) {
|
} else if (rm_empty && !obj_prop_value) {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`Match but empty. Ignoring/removing: ${obj_prop_name}`);
|
console.log(
|
||||||
|
`Match but empty. Ignoring/removing: ${obj_prop_name}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`Match: ${prefix})${obj_prop_name} value=${obj_prop_value}`);
|
console.log(
|
||||||
|
`Match: ${prefix})${obj_prop_name} value=${obj_prop_value}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
data_obj[obj_prop_name] = obj_prop_value;
|
data_obj[obj_prop_name] = obj_prop_value;
|
||||||
}
|
}
|
||||||
@@ -107,19 +121,31 @@ export const extract_prefixed_form_data = function extract_prefixed_form_data({
|
|||||||
} else {
|
} else {
|
||||||
// No prefix set
|
// No prefix set
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`Checking: ${obj_prop_name} value=${obj_prop_value}`);
|
console.log(
|
||||||
|
`Checking: ${obj_prop_name} value=${obj_prop_value}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (rm_empty_id && obj_prop_name.endsWith('id_random') && !obj_prop_value) {
|
if (
|
||||||
|
rm_empty_id &&
|
||||||
|
obj_prop_name.endsWith('id_random') &&
|
||||||
|
!obj_prop_value
|
||||||
|
) {
|
||||||
if (log_lvl > 1) {
|
if (log_lvl > 1) {
|
||||||
console.log(`Match but empty *_id_random. Ignoring/removing: ${obj_prop_name}`);
|
console.log(
|
||||||
|
`Match but empty *_id_random. Ignoring/removing: ${obj_prop_name}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else if (rm_empty && !obj_prop_value) {
|
} else if (rm_empty && !obj_prop_value) {
|
||||||
if (log_lvl > 1) {
|
if (log_lvl > 1) {
|
||||||
console.log(`Match but empty. Ignoring/removing: ${obj_prop_name}`);
|
console.log(
|
||||||
|
`Match but empty. Ignoring/removing: ${obj_prop_name}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (log_lvl > 1) {
|
if (log_lvl > 1) {
|
||||||
console.log(`Match: ${obj_prop_name} value=${obj_prop_value}`);
|
console.log(
|
||||||
|
`Match: ${obj_prop_name} value=${obj_prop_value}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
data_obj[obj_prop_name] = obj_prop_value;
|
data_obj[obj_prop_name] = obj_prop_value;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,61 +5,63 @@ import * as Lucide from 'lucide-svelte';
|
|||||||
* @param extension The file extension (e.g., 'pdf', 'jpg').
|
* @param extension The file extension (e.g., 'pdf', 'jpg').
|
||||||
* @returns The Lucide icon component.
|
* @returns The Lucide icon component.
|
||||||
*/
|
*/
|
||||||
export function file_extension_icon_lucide(extension: string | undefined | null): any {
|
export function file_extension_icon_lucide(
|
||||||
|
extension: string | undefined | null
|
||||||
|
): any {
|
||||||
const ext = extension?.toLowerCase() || '';
|
const ext = extension?.toLowerCase() || '';
|
||||||
|
|
||||||
const icon_map: Record<string, any> = {
|
const icon_map: Record<string, any> = {
|
||||||
'pdf': Lucide.FileText,
|
pdf: Lucide.FileText,
|
||||||
'doc': Lucide.FileText,
|
doc: Lucide.FileText,
|
||||||
'docx': Lucide.FileText,
|
docx: Lucide.FileText,
|
||||||
'txt': Lucide.FileText,
|
txt: Lucide.FileText,
|
||||||
'rtf': Lucide.FileText,
|
rtf: Lucide.FileText,
|
||||||
|
|
||||||
'xls': Lucide.FileSpreadsheet,
|
xls: Lucide.FileSpreadsheet,
|
||||||
'xlsx': Lucide.FileSpreadsheet,
|
xlsx: Lucide.FileSpreadsheet,
|
||||||
'csv': Lucide.FileSpreadsheet,
|
csv: Lucide.FileSpreadsheet,
|
||||||
|
|
||||||
'png': Lucide.FileImage,
|
png: Lucide.FileImage,
|
||||||
'jpg': Lucide.FileImage,
|
jpg: Lucide.FileImage,
|
||||||
'jpeg': Lucide.FileImage,
|
jpeg: Lucide.FileImage,
|
||||||
'gif': Lucide.FileImage,
|
gif: Lucide.FileImage,
|
||||||
'webp': Lucide.FileImage,
|
webp: Lucide.FileImage,
|
||||||
'bmp': Lucide.FileImage,
|
bmp: Lucide.FileImage,
|
||||||
'svg': Lucide.FileImage,
|
svg: Lucide.FileImage,
|
||||||
|
|
||||||
'mp3': Lucide.FileAudio,
|
mp3: Lucide.FileAudio,
|
||||||
'wav': Lucide.FileAudio,
|
wav: Lucide.FileAudio,
|
||||||
'm4a': Lucide.FileAudio,
|
m4a: Lucide.FileAudio,
|
||||||
'flac': Lucide.FileAudio,
|
flac: Lucide.FileAudio,
|
||||||
'aac': Lucide.FileAudio,
|
aac: Lucide.FileAudio,
|
||||||
'aif': Lucide.FileAudio,
|
aif: Lucide.FileAudio,
|
||||||
'aiff': Lucide.FileAudio,
|
aiff: Lucide.FileAudio,
|
||||||
|
|
||||||
'mp4': Lucide.FileVideo,
|
mp4: Lucide.FileVideo,
|
||||||
'mkv': Lucide.FileVideo,
|
mkv: Lucide.FileVideo,
|
||||||
'mov': Lucide.FileVideo,
|
mov: Lucide.FileVideo,
|
||||||
'avi': Lucide.FileVideo,
|
avi: Lucide.FileVideo,
|
||||||
'3gp': Lucide.FileVideo,
|
'3gp': Lucide.FileVideo,
|
||||||
|
|
||||||
'ppt': Lucide.Presentation,
|
ppt: Lucide.Presentation,
|
||||||
'pptx': Lucide.Presentation,
|
pptx: Lucide.Presentation,
|
||||||
'key': Lucide.Presentation,
|
key: Lucide.Presentation,
|
||||||
'odp': Lucide.Presentation,
|
odp: Lucide.Presentation,
|
||||||
|
|
||||||
'zip': Lucide.FileArchive,
|
zip: Lucide.FileArchive,
|
||||||
'7z': Lucide.FileArchive,
|
'7z': Lucide.FileArchive,
|
||||||
'rar': Lucide.FileArchive,
|
rar: Lucide.FileArchive,
|
||||||
'tar': Lucide.FileArchive,
|
tar: Lucide.FileArchive,
|
||||||
'gz': Lucide.FileArchive,
|
gz: Lucide.FileArchive,
|
||||||
|
|
||||||
'json': Lucide.FileJson,
|
json: Lucide.FileJson,
|
||||||
|
|
||||||
'html': Lucide.FileCode,
|
html: Lucide.FileCode,
|
||||||
'htm': Lucide.FileCode,
|
htm: Lucide.FileCode,
|
||||||
'js': Lucide.FileCode,
|
js: Lucide.FileCode,
|
||||||
'ts': Lucide.FileCode,
|
ts: Lucide.FileCode,
|
||||||
'css': Lucide.FileCode,
|
css: Lucide.FileCode,
|
||||||
'php': Lucide.FileCode
|
php: Lucide.FileCode
|
||||||
};
|
};
|
||||||
|
|
||||||
return icon_map[ext] || Lucide.File;
|
return icon_map[ext] || Lucide.File;
|
||||||
|
|||||||
@@ -12,12 +12,18 @@ export const clean_filename = function clean_filename(
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
const cleaned_filename = filename.replace(unacceptable_chars, replacement_char);
|
const cleaned_filename = filename.replace(
|
||||||
|
unacceptable_chars,
|
||||||
|
replacement_char
|
||||||
|
);
|
||||||
// console.log(cleaned_filename);
|
// console.log(cleaned_filename);
|
||||||
return cleaned_filename;
|
return cleaned_filename;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const format_bytes = function format_bytes(bytes: number, decimals: number = 2) {
|
export const format_bytes = function format_bytes(
|
||||||
|
bytes: number,
|
||||||
|
decimals: number = 2
|
||||||
|
) {
|
||||||
if (bytes === 0) return '0 Bytes';
|
if (bytes === 0) return '0 Bytes';
|
||||||
|
|
||||||
const k = 1024;
|
const k = 1024;
|
||||||
@@ -30,14 +36,19 @@ export const format_bytes = function format_bytes(bytes: number, decimals: numbe
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Updated 2024-08-12
|
// Updated 2024-08-12
|
||||||
export const guess_file_name = function guess_file_name(filename_string: string) {
|
export const guess_file_name = function guess_file_name(
|
||||||
|
filename_string: string
|
||||||
|
) {
|
||||||
// console.log('*** guess_file_name() ***');
|
// console.log('*** guess_file_name() ***');
|
||||||
if (!filename_string) {
|
if (!filename_string) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filename_string.includes('.')) {
|
if (filename_string.includes('.')) {
|
||||||
const file_name = filename_string.substring(0, filename_string.lastIndexOf('.'));
|
const file_name = filename_string.substring(
|
||||||
|
0,
|
||||||
|
filename_string.lastIndexOf('.')
|
||||||
|
);
|
||||||
// console.log(file_name);
|
// console.log(file_name);
|
||||||
return file_name;
|
return file_name;
|
||||||
} else {
|
} else {
|
||||||
@@ -46,7 +57,9 @@ export const guess_file_name = function guess_file_name(filename_string: string)
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Updated 2024-08-12
|
// Updated 2024-08-12
|
||||||
export const guess_file_extension = function guess_file_extension(filename_string: string) {
|
export const guess_file_extension = function guess_file_extension(
|
||||||
|
filename_string: string
|
||||||
|
) {
|
||||||
// console.log('*** guess_file_extension() ***');
|
// console.log('*** guess_file_extension() ***');
|
||||||
if (!filename_string) {
|
if (!filename_string) {
|
||||||
return '';
|
return '';
|
||||||
@@ -57,21 +70,27 @@ export const guess_file_extension = function guess_file_extension(filename_strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
const file_extension =
|
const file_extension =
|
||||||
filename_string.substring(filename_string.lastIndexOf('.') + 1, filename_string.length) ||
|
filename_string.substring(
|
||||||
filename_string;
|
filename_string.lastIndexOf('.') + 1,
|
||||||
|
filename_string.length
|
||||||
|
) || filename_string;
|
||||||
// console.log(file_extension);
|
// console.log(file_extension);
|
||||||
return file_extension;
|
return file_extension;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Updated 2024-08-12
|
// Updated 2024-08-12
|
||||||
export const get_file_hash = async function get_file_hash(file: File): Promise<string> {
|
export const get_file_hash = async function get_file_hash(
|
||||||
|
file: File
|
||||||
|
): Promise<string> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const file_reader = new FileReader();
|
const file_reader = new FileReader();
|
||||||
|
|
||||||
file_reader.onload = async function () {
|
file_reader.onload = async function () {
|
||||||
const result = file_reader.result;
|
const result = file_reader.result;
|
||||||
if (!result || typeof result === 'string') {
|
if (!result || typeof result === 'string') {
|
||||||
console.log('File was not read completely or is in wrong format');
|
console.log(
|
||||||
|
'File was not read completely or is in wrong format'
|
||||||
|
);
|
||||||
reject('Error reading the file');
|
reject('Error reading the file');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -84,7 +103,9 @@ export const get_file_hash = async function get_file_hash(file: File): Promise<s
|
|||||||
|
|
||||||
const hash_buffer = await crypto.subtle.digest('SHA-256', result);
|
const hash_buffer = await crypto.subtle.digest('SHA-256', result);
|
||||||
const hash_array = Array.from(new Uint8Array(hash_buffer));
|
const hash_array = Array.from(new Uint8Array(hash_buffer));
|
||||||
const hash_hex = hash_array.map((b) => b.toString(16).padStart(2, '0')).join('');
|
const hash_hex = hash_array
|
||||||
|
.map((b) => b.toString(16).padStart(2, '0'))
|
||||||
|
.join('');
|
||||||
|
|
||||||
resolve(hash_hex);
|
resolve(hash_hex);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -10,11 +10,16 @@ export function format_html(html: string): string {
|
|||||||
return html
|
return html
|
||||||
.replace(/>\s*</g, '>\n<') // Add newlines between tags
|
.replace(/>\s*</g, '>\n<') // Add newlines between tags
|
||||||
.split('\n')
|
.split('\n')
|
||||||
.map(line => {
|
.map((line) => {
|
||||||
line = line.trim();
|
line = line.trim();
|
||||||
if (line.match(/<\//)) indent--; // Decrease indent for closing tags
|
if (line.match(/<\//)) indent--; // Decrease indent for closing tags
|
||||||
const out = tab.repeat(Math.max(0, indent)) + line;
|
const out = tab.repeat(Math.max(0, indent)) + line;
|
||||||
if (line.match(/<[^\/!]/) && !line.match(/\/>/) && !line.match(/<\//)) indent++; // Increase indent for opening tags
|
if (
|
||||||
|
line.match(/<[^\/!]/) &&
|
||||||
|
!line.match(/\/>/) &&
|
||||||
|
!line.match(/<\//)
|
||||||
|
)
|
||||||
|
indent++; // Increase indent for opening tags
|
||||||
return out;
|
return out;
|
||||||
})
|
})
|
||||||
.join('\n');
|
.join('\n');
|
||||||
|
|||||||
@@ -9,7 +9,9 @@ export const is_datetime_recent = function is_datetime_recent({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}) {
|
}) {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** is_datetime_recent() *** datetime=${datetime} minutes=${minutes}`);
|
console.log(
|
||||||
|
`*** is_datetime_recent() *** datetime=${datetime} minutes=${minutes}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const now: any = new Date();
|
const now: any = new Date();
|
||||||
|
|||||||
@@ -17,7 +17,10 @@ export const access_level_order = [
|
|||||||
* Compares two access levels based on the hierarchy.
|
* Compares two access levels based on the hierarchy.
|
||||||
* @returns 1 if level_a is higher, -1 if level_b is higher, 0 if equal.
|
* @returns 1 if level_a is higher, -1 if level_b is higher, 0 if equal.
|
||||||
*/
|
*/
|
||||||
export const compare_access_levels = function (level_a: string, level_b: string): number {
|
export const compare_access_levels = function (
|
||||||
|
level_a: string,
|
||||||
|
level_b: string
|
||||||
|
): number {
|
||||||
const index_a = access_level_order.indexOf(level_a || 'anonymous');
|
const index_a = access_level_order.indexOf(level_a || 'anonymous');
|
||||||
const index_b = access_level_order.indexOf(level_b || 'anonymous');
|
const index_b = access_level_order.indexOf(level_b || 'anonymous');
|
||||||
|
|
||||||
@@ -30,7 +33,9 @@ export const compare_access_levels = function (level_a: string, level_b: string)
|
|||||||
// NOTE: I know there is a better more efficient way to do this, but I don't have time for that right now.
|
// NOTE: I know there is a better more efficient way to do this, but I don't have time for that right now.
|
||||||
// Reminder: super > manager > administrator > trusted > public > authenticated > anonymous
|
// Reminder: super > manager > administrator > trusted > public > authenticated > anonymous
|
||||||
// Super is the highest level. Anonymous is the lowest level.
|
// Super is the highest level. Anonymous is the lowest level.
|
||||||
export const process_permission_checks = function process_permission_checks(access_type: string) {
|
export const process_permission_checks = function process_permission_checks(
|
||||||
|
access_type: string
|
||||||
|
) {
|
||||||
// let access_checks = { 'access_type': null, 'super_check': null };
|
// let access_checks = { 'access_type': null, 'super_check': null };
|
||||||
const access_checks: key_val = {};
|
const access_checks: key_val = {};
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,9 @@ import type { key_val } from './ae_utils';
|
|||||||
*/
|
*/
|
||||||
// Updated 2022-02-11
|
// Updated 2022-02-11
|
||||||
|
|
||||||
export const process_data_string = function process_data_string(data_string: string) {
|
export const process_data_string = function process_data_string(
|
||||||
|
data_string: string
|
||||||
|
) {
|
||||||
console.log('*** process_data_string() ***');
|
console.log('*** process_data_string() ***');
|
||||||
// console.log(data_string);
|
// console.log(data_string);
|
||||||
if (!data_string || data_string.length < 1) {
|
if (!data_string || data_string.length < 1) {
|
||||||
@@ -70,14 +72,18 @@ export const process_data_string = function process_data_string(data_string: str
|
|||||||
obj['type'] = 'url';
|
obj['type'] = 'url';
|
||||||
obj['url'] = data_string;
|
obj['url'] = data_string;
|
||||||
} else {
|
} else {
|
||||||
console.log('The unknown data string type was found. Returning the string part.');
|
console.log(
|
||||||
|
'The unknown data string type was found. Returning the string part.'
|
||||||
|
);
|
||||||
const unknown_str = data_string.slice(colon_index + 1);
|
const unknown_str = data_string.slice(colon_index + 1);
|
||||||
console.log(unknown_str);
|
console.log(unknown_str);
|
||||||
|
|
||||||
obj['str'] = unknown_str;
|
obj['str'] = unknown_str;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log('The data string type was not found. Returning the entire string.');
|
console.log(
|
||||||
|
'The data string type was not found. Returning the entire string.'
|
||||||
|
);
|
||||||
console.log(data_string);
|
console.log(data_string);
|
||||||
|
|
||||||
obj['qr_type'] = 'UNKNOWN';
|
obj['qr_type'] = 'UNKNOWN';
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ export function return_obj_type_path({
|
|||||||
obj_type = null,
|
obj_type = null,
|
||||||
obj_type_prop_name = null
|
obj_type_prop_name = null
|
||||||
}: {
|
}: {
|
||||||
obj_type?: string | null,
|
obj_type?: string | null;
|
||||||
obj_type_prop_name?: string | null
|
obj_type_prop_name?: string | null;
|
||||||
}) {
|
}) {
|
||||||
console.log('*** return_obj_type_path() ***');
|
console.log('*** return_obj_type_path() ***');
|
||||||
|
|
||||||
@@ -14,29 +14,69 @@ export function return_obj_type_path({
|
|||||||
{ name: 'archive', display: 'Archive', path: 'archive' },
|
{ name: 'archive', display: 'Archive', path: 'archive' },
|
||||||
{ name: 'address', display: 'Address', path: 'address' },
|
{ name: 'address', display: 'Address', path: 'address' },
|
||||||
{ name: 'archive', display: 'Archive', path: 'archive' },
|
{ name: 'archive', display: 'Archive', path: 'archive' },
|
||||||
{ name: 'archive_content', display: 'Archive Content', path: 'archive/content' },
|
{
|
||||||
|
name: 'archive_content',
|
||||||
|
display: 'Archive Content',
|
||||||
|
path: 'archive/content'
|
||||||
|
},
|
||||||
{ name: 'contact', display: 'Contact', path: 'contact' },
|
{ name: 'contact', display: 'Contact', path: 'contact' },
|
||||||
{ name: 'data_store', display: 'Data Store', path: 'data_store' },
|
{ name: 'data_store', display: 'Data Store', path: 'data_store' },
|
||||||
{ name: 'event_abstract', display: 'Event Abstract', path: 'event/abstract' },
|
{
|
||||||
|
name: 'event_abstract',
|
||||||
|
display: 'Event Abstract',
|
||||||
|
path: 'event/abstract'
|
||||||
|
},
|
||||||
{ name: 'event_badge', display: 'Event Badge', path: 'event/badge' },
|
{ name: 'event_badge', display: 'Event Badge', path: 'event/badge' },
|
||||||
{ name: 'event_device', display: 'Event Device', path: 'event/device' },
|
{ name: 'event_device', display: 'Event Device', path: 'event/device' },
|
||||||
{ name: 'event_exhibit', display: 'Event Exhibit', path: 'event/exhibit' },
|
{
|
||||||
|
name: 'event_exhibit',
|
||||||
|
display: 'Event Exhibit',
|
||||||
|
path: 'event/exhibit'
|
||||||
|
},
|
||||||
{ name: 'event_file', display: 'Event File', path: 'event/file' },
|
{ name: 'event_file', display: 'Event File', path: 'event/file' },
|
||||||
{ name: 'event_location', display: 'Event Location', path: 'event/location' },
|
{
|
||||||
|
name: 'event_location',
|
||||||
|
display: 'Event Location',
|
||||||
|
path: 'event/location'
|
||||||
|
},
|
||||||
{ name: 'event_person', display: 'Event Person', path: 'event/person' },
|
{ name: 'event_person', display: 'Event Person', path: 'event/person' },
|
||||||
{ name: 'event_presentation', display: 'Event Presentation', path: 'event/' },
|
{
|
||||||
{ name: 'event_presenter', display: 'Event Presenter', path: 'event/presenter' },
|
name: 'event_presentation',
|
||||||
{ name: 'event_registration', display: 'Event Registration', path: 'event/registration' },
|
display: 'Event Presentation',
|
||||||
{ name: 'event_session', display: 'Event Session', path: 'event/session' },
|
path: 'event/'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'event_presenter',
|
||||||
|
display: 'Event Presenter',
|
||||||
|
path: 'event/presenter'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'event_registration',
|
||||||
|
display: 'Event Registration',
|
||||||
|
path: 'event/registration'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'event_session',
|
||||||
|
display: 'Event Session',
|
||||||
|
path: 'event/session'
|
||||||
|
},
|
||||||
{ name: 'event', display: 'Event', path: 'event' },
|
{ name: 'event', display: 'Event', path: 'event' },
|
||||||
{ name: 'hosted_file', display: 'Hosted File', path: 'hosted_file' },
|
{ name: 'hosted_file', display: 'Hosted File', path: 'hosted_file' },
|
||||||
{ name: 'journal', display: 'Journal', path: 'journal' },
|
{ name: 'journal', display: 'Journal', path: 'journal' },
|
||||||
{ name: 'journal_entry', display: 'Journal Entry', path: 'journal/entry' },
|
{
|
||||||
|
name: 'journal_entry',
|
||||||
|
display: 'Journal Entry',
|
||||||
|
path: 'journal/entry'
|
||||||
|
},
|
||||||
{ name: 'order_line', display: 'Order Line', path: 'order/line' },
|
{ name: 'order_line', display: 'Order Line', path: 'order/line' },
|
||||||
{ name: 'order', display: 'Order', path: 'order' },
|
{ name: 'order', display: 'Order', path: 'order' },
|
||||||
{ name: 'person', display: 'Person', path: 'person' },
|
{ name: 'person', display: 'Person', path: 'person' },
|
||||||
{ name: 'post', display: 'Archive', path: 'post' },
|
{ name: 'post', display: 'Archive', path: 'post' },
|
||||||
{ name: 'post_comment', display: 'Archive Content', path: 'post/comment' },
|
{
|
||||||
|
name: 'post_comment',
|
||||||
|
display: 'Archive Content',
|
||||||
|
path: 'post/comment'
|
||||||
|
},
|
||||||
{ name: 'user', display: 'User', path: 'user' }
|
{ name: 'user', display: 'User', path: 'user' }
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -76,7 +76,10 @@ export function set_obj_prop_display_name({
|
|||||||
// console.log(known_obj_type_li_dict[i]);
|
// console.log(known_obj_type_li_dict[i]);
|
||||||
if (prop_name.startsWith(known_obj_type_li_dict[i].name)) {
|
if (prop_name.startsWith(known_obj_type_li_dict[i].name)) {
|
||||||
// console.log(`Found ${known_obj_type_li_dict[i].name}`);
|
// console.log(`Found ${known_obj_type_li_dict[i].name}`);
|
||||||
prop_display_name = prop_name.replace(known_obj_type_li_dict[i].name, '');
|
prop_display_name = prop_name.replace(
|
||||||
|
known_obj_type_li_dict[i].name,
|
||||||
|
''
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -101,7 +104,10 @@ export function set_obj_prop_display_name({
|
|||||||
// console.log(`Found ${known_obj_type_li_dict[i].name}`);
|
// console.log(`Found ${known_obj_type_li_dict[i].name}`);
|
||||||
found_obj_type = known_obj_type_li_dict[i].name;
|
found_obj_type = known_obj_type_li_dict[i].name;
|
||||||
if (found_obj_type == obj_type) {
|
if (found_obj_type == obj_type) {
|
||||||
prop_display_name = prop_name.replace(known_obj_type_li_dict[i].name, '');
|
prop_display_name = prop_name.replace(
|
||||||
|
known_obj_type_li_dict[i].name,
|
||||||
|
''
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ export function to_title_case(text_string: string) {
|
|||||||
array[index - 3] !== ':' &&
|
array[index - 3] !== ':' &&
|
||||||
array[index + 1] !== ':' &&
|
array[index + 1] !== ':' &&
|
||||||
/* Ignore small words that start a hyphenated phrase */
|
/* Ignore small words that start a hyphenated phrase */
|
||||||
(array[index + 1] !== '-' || (array[index - 1] === '-' && array[index + 1] === '-'))
|
(array[index + 1] !== '-' ||
|
||||||
|
(array[index - 1] === '-' && array[index + 1] === '-'))
|
||||||
) {
|
) {
|
||||||
return current.toLowerCase();
|
return current.toLowerCase();
|
||||||
}
|
}
|
||||||
@@ -36,9 +37,12 @@ export function to_title_case(text_string: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Capitalize the first letter */
|
/* Capitalize the first letter */
|
||||||
return current.replace(alphanumericPattern, function (match: string) {
|
return current.replace(
|
||||||
return match.toUpperCase();
|
alphanumericPattern,
|
||||||
});
|
function (match: string) {
|
||||||
|
return match.toUpperCase();
|
||||||
|
}
|
||||||
|
);
|
||||||
})
|
})
|
||||||
.join('');
|
.join('');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
import { describe, it, expect } from 'vitest';
|
import { describe, it, expect } from 'vitest';
|
||||||
import { compare_access_levels, process_permission_checks, access_level_order } from './ae_utils__perm_checks';
|
import {
|
||||||
|
compare_access_levels,
|
||||||
|
process_permission_checks,
|
||||||
|
access_level_order
|
||||||
|
} from './ae_utils__perm_checks';
|
||||||
|
|
||||||
describe('Permission Hierarchy Tests', () => {
|
describe('Permission Hierarchy Tests', () => {
|
||||||
describe('compare_access_levels', () => {
|
describe('compare_access_levels', () => {
|
||||||
@@ -15,7 +19,9 @@ describe('Permission Hierarchy Tests', () => {
|
|||||||
it('should correctly identify downgrades', () => {
|
it('should correctly identify downgrades', () => {
|
||||||
// Low to High should return -1
|
// Low to High should return -1
|
||||||
expect(compare_access_levels('manager', 'super')).toBe(-1);
|
expect(compare_access_levels('manager', 'super')).toBe(-1);
|
||||||
expect(compare_access_levels('anonymous', 'authenticated')).toBe(-1);
|
expect(compare_access_levels('anonymous', 'authenticated')).toBe(
|
||||||
|
-1
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return 0 for equal levels', () => {
|
it('should return 0 for equal levels', () => {
|
||||||
@@ -25,7 +31,9 @@ describe('Permission Hierarchy Tests', () => {
|
|||||||
|
|
||||||
it('should handle null/empty as anonymous', () => {
|
it('should handle null/empty as anonymous', () => {
|
||||||
expect(compare_access_levels('trusted', '')).toBe(1);
|
expect(compare_access_levels('trusted', '')).toBe(1);
|
||||||
expect(compare_access_levels(null as any, 'authenticated')).toBe(-1);
|
expect(compare_access_levels(null as any, 'authenticated')).toBe(
|
||||||
|
-1
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,9 @@ export const get_ae_obj_li_for_lu = async function get_ae_obj_li_for_lu({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}) {
|
}) {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** get_ae_obj_li_for_lu() *** for_lu_type=${for_lu_type}`);
|
console.log(
|
||||||
|
`*** get_ae_obj_li_for_lu() *** for_lu_type=${for_lu_type}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass headers as-is — get_object will auto-promote the real account_id from api_cfg.
|
// Pass headers as-is — get_object will auto-promote the real account_id from api_cfg.
|
||||||
@@ -331,7 +333,9 @@ export const delete_ae_obj_id_crud = async function delete_ae_obj_id_crud({
|
|||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}) {
|
}) {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`*** delete_ae_obj_id_crud() *** obj_type: ${obj_type} obj_id: ${obj_id}`);
|
console.log(
|
||||||
|
`*** delete_ae_obj_id_crud() *** obj_type: ${obj_type} obj_id: ${obj_id}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
data['super_key'] = key;
|
data['super_key'] = key;
|
||||||
@@ -369,7 +373,6 @@ export const delete_ae_obj_id_crud = async function delete_ae_obj_id_crud({
|
|||||||
return object_obj_delete_promise;
|
return object_obj_delete_promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* BEGIN: Hosted File Related */
|
/* BEGIN: Hosted File Related */
|
||||||
|
|
||||||
// Updated 2026-01-07
|
// Updated 2026-01-07
|
||||||
@@ -473,74 +476,75 @@ export const delete_hosted_file = async function delete_hosted_file({
|
|||||||
/* BEGIN: Data Store Related */
|
/* BEGIN: Data Store Related */
|
||||||
|
|
||||||
// Updated 2023-06-29
|
// Updated 2023-06-29
|
||||||
export const get_data_store_obj_w_code = async function get_data_store_obj_w_code({
|
export const get_data_store_obj_w_code =
|
||||||
api_cfg,
|
async function get_data_store_obj_w_code({
|
||||||
data_store_code,
|
api_cfg,
|
||||||
data_type = 'text',
|
data_store_code,
|
||||||
headers = {},
|
data_type = 'text',
|
||||||
params = {},
|
headers = {},
|
||||||
timeout = 25000,
|
params = {},
|
||||||
log_lvl = 0
|
timeout = 25000,
|
||||||
}: {
|
log_lvl = 0
|
||||||
api_cfg: any;
|
}: {
|
||||||
data_store_code: string;
|
api_cfg: any;
|
||||||
data_type?: string;
|
data_store_code: string;
|
||||||
headers?: key_val;
|
data_type?: string;
|
||||||
params?: key_val;
|
headers?: key_val;
|
||||||
timeout?: number;
|
params?: key_val;
|
||||||
log_lvl?: number;
|
timeout?: number;
|
||||||
}) {
|
log_lvl?: number;
|
||||||
if (log_lvl) {
|
}) {
|
||||||
console.log('*** get_data_store_obj_w_code() ***');
|
if (log_lvl) {
|
||||||
}
|
console.log('*** get_data_store_obj_w_code() ***');
|
||||||
|
}
|
||||||
|
|
||||||
// let get_item_result = window.localStorage.getItem(code);
|
// let get_item_result = window.localStorage.getItem(code);
|
||||||
|
|
||||||
const endpoint = `/data_store/code/${data_store_code}`;
|
const endpoint = `/data_store/code/${data_store_code}`;
|
||||||
let data_store_obj_get_promise = await api.get_object({
|
let data_store_obj_get_promise = await api.get_object({
|
||||||
api_cfg: api_cfg,
|
api_cfg: api_cfg,
|
||||||
endpoint: endpoint,
|
|
||||||
headers: headers,
|
|
||||||
params: params,
|
|
||||||
timeout: timeout,
|
|
||||||
log_lvl: log_lvl
|
|
||||||
});
|
|
||||||
|
|
||||||
if (data_store_obj_get_promise === false) {
|
|
||||||
console.log('Data Store - RUN AGAIN WITH BACKUP');
|
|
||||||
const original_api_base_url = api_cfg['base_url'];
|
|
||||||
|
|
||||||
const temp_api = api_cfg;
|
|
||||||
temp_api['base_url'] = temp_api['base_url_bak'];
|
|
||||||
|
|
||||||
data_store_obj_get_promise = await api.get_object({
|
|
||||||
api_cfg: temp_api,
|
|
||||||
endpoint: endpoint,
|
endpoint: endpoint,
|
||||||
headers: headers,
|
headers: headers,
|
||||||
params: params,
|
params: params,
|
||||||
timeout: timeout,
|
timeout: timeout,
|
||||||
log_lvl: log_lvl
|
log_lvl: log_lvl
|
||||||
});
|
});
|
||||||
temp_api['base_url'] = original_api_base_url;
|
|
||||||
}
|
|
||||||
|
|
||||||
const data_store_obj = data_store_obj_get_promise;
|
if (data_store_obj_get_promise === false) {
|
||||||
|
console.log('Data Store - RUN AGAIN WITH BACKUP');
|
||||||
|
const original_api_base_url = api_cfg['base_url'];
|
||||||
|
|
||||||
if (data_type == 'text') {
|
const temp_api = api_cfg;
|
||||||
// console.log(data_store_obj.text);
|
temp_api['base_url'] = temp_api['base_url_bak'];
|
||||||
// window.localStorage.setItem(data_store_code, data_store_obj.text);
|
|
||||||
// localStorage.setItem(data_store_code, data_store_obj.text);
|
|
||||||
} else if (data_type == 'json') {
|
|
||||||
// console.log(data_store_obj.json);
|
|
||||||
// window.localStorage.setItem(data_store_code, JSON.stringify(data_store_obj.json));
|
|
||||||
// localStorage.setItem(data_store_code, JSON.stringify(data_store_obj.json));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (log_lvl > 1) {
|
data_store_obj_get_promise = await api.get_object({
|
||||||
console.log('Response Data:', data_store_obj);
|
api_cfg: temp_api,
|
||||||
}
|
endpoint: endpoint,
|
||||||
return data_store_obj;
|
headers: headers,
|
||||||
};
|
params: params,
|
||||||
|
timeout: timeout,
|
||||||
|
log_lvl: log_lvl
|
||||||
|
});
|
||||||
|
temp_api['base_url'] = original_api_base_url;
|
||||||
|
}
|
||||||
|
|
||||||
|
const data_store_obj = data_store_obj_get_promise;
|
||||||
|
|
||||||
|
if (data_type == 'text') {
|
||||||
|
// console.log(data_store_obj.text);
|
||||||
|
// window.localStorage.setItem(data_store_code, data_store_obj.text);
|
||||||
|
// localStorage.setItem(data_store_code, data_store_obj.text);
|
||||||
|
} else if (data_type == 'json') {
|
||||||
|
// console.log(data_store_obj.json);
|
||||||
|
// window.localStorage.setItem(data_store_code, JSON.stringify(data_store_obj.json));
|
||||||
|
// localStorage.setItem(data_store_code, JSON.stringify(data_store_obj.json));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (log_lvl > 1) {
|
||||||
|
console.log('Response Data:', data_store_obj);
|
||||||
|
}
|
||||||
|
return data_store_obj;
|
||||||
|
};
|
||||||
/* END: Data Store Related */
|
/* END: Data Store Related */
|
||||||
|
|
||||||
/* BEGIN: Utility: Email Related */
|
/* BEGIN: Utility: Email Related */
|
||||||
@@ -591,8 +595,13 @@ export const send_email = async function send_email({
|
|||||||
|
|
||||||
// Skip email sending entirely when running in a test/Playwright environment.
|
// Skip email sending entirely when running in a test/Playwright environment.
|
||||||
// Set window.__ae_test_mode = true via addInitScript to activate this guard.
|
// Set window.__ae_test_mode = true via addInitScript to activate this guard.
|
||||||
if (typeof globalThis !== 'undefined' && (globalThis as any).__ae_test_mode) {
|
if (
|
||||||
console.log(`[TEST MODE] send_email() suppressed — would have sent to: ${to_email}, subject: ${subject}`);
|
typeof globalThis !== 'undefined' &&
|
||||||
|
(globalThis as any).__ae_test_mode
|
||||||
|
) {
|
||||||
|
console.log(
|
||||||
|
`[TEST MODE] send_email() suppressed — would have sent to: ${to_email}, subject: ${subject}`
|
||||||
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -663,7 +672,7 @@ const obj = {
|
|||||||
create_nested_obj: create_nested_obj,
|
create_nested_obj: create_nested_obj,
|
||||||
update_ae_obj: update_ae_obj,
|
update_ae_obj: update_ae_obj,
|
||||||
update_nested_obj: update_nested_obj,
|
update_nested_obj: update_nested_obj,
|
||||||
delete_ae_obj:delete_ae_obj,
|
delete_ae_obj: delete_ae_obj,
|
||||||
delete_nested_ae_obj: delete_nested_ae_obj,
|
delete_nested_ae_obj: delete_nested_ae_obj,
|
||||||
create_ae_obj_crud: create_ae_obj_crud,
|
create_ae_obj_crud: create_ae_obj_crud,
|
||||||
update_ae_obj_id_crud: update_ae_obj_id_crud,
|
update_ae_obj_id_crud: update_ae_obj_id_crud,
|
||||||
|
|||||||
@@ -1,295 +1,320 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
// *** Import Svelte specific
|
// *** Import Svelte specific
|
||||||
import { onDestroy, onMount, tick } from 'svelte';
|
import { onDestroy, onMount, tick } from 'svelte';
|
||||||
import { afterNavigate } from '$app/navigation';
|
import { afterNavigate } from '$app/navigation';
|
||||||
|
|
||||||
// *** Import other supporting libraries
|
// *** Import other supporting libraries
|
||||||
// import { liveQuery } from "dexie";
|
// import { liveQuery } from "dexie";
|
||||||
import { Lock, LockOpen, RefreshCw, ShieldEllipsis, ShieldMinus, ShieldPlus, ShieldUser, Unlink, User, UserCheck, UserRound, Wand2 } from '@lucide/svelte';
|
import {
|
||||||
// *** Import Aether specific variables and functions
|
Lock,
|
||||||
import { ae_util } from '$lib/ae_utils/ae_utils';
|
LockOpen,
|
||||||
import { ae_loc, ae_sess, ae_api, slct, slct_trigger } from '$lib/stores/ae_stores';
|
RefreshCw,
|
||||||
// import { core_func } from '$lib/ae_core/ae_core_functions';
|
ShieldEllipsis,
|
||||||
// Ideally the Event related stores should not be imported here?
|
ShieldMinus,
|
||||||
import { events_loc } from '$lib/stores/ae_events_stores';
|
ShieldPlus,
|
||||||
// import { db_events } from "$lib/db_events";
|
ShieldUser,
|
||||||
|
Unlink,
|
||||||
|
User,
|
||||||
|
UserCheck,
|
||||||
|
UserRound,
|
||||||
|
Wand2
|
||||||
|
} from '@lucide/svelte';
|
||||||
|
// *** Import Aether specific variables and functions
|
||||||
|
import { ae_util } from '$lib/ae_utils/ae_utils';
|
||||||
|
import {
|
||||||
|
ae_loc,
|
||||||
|
ae_sess,
|
||||||
|
ae_api,
|
||||||
|
slct,
|
||||||
|
slct_trigger
|
||||||
|
} from '$lib/stores/ae_stores';
|
||||||
|
// import { core_func } from '$lib/ae_core/ae_core_functions';
|
||||||
|
// Ideally the Event related stores should not be imported here?
|
||||||
|
import { events_loc } from '$lib/stores/ae_events_stores';
|
||||||
|
// import { db_events } from "$lib/db_events";
|
||||||
|
|
||||||
// export let hidden: boolean = false;
|
// export let hidden: boolean = false;
|
||||||
|
|
||||||
// *** Setup Svelte properties
|
// *** Setup Svelte properties
|
||||||
interface Props {
|
interface Props {
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
hide?: null | boolean;
|
hide?: null | boolean;
|
||||||
focus_input: boolean;
|
focus_input: boolean;
|
||||||
expand?: boolean;
|
expand?: boolean;
|
||||||
show_passcode_input: boolean;
|
show_passcode_input: boolean;
|
||||||
trigger_clear_access: null | boolean;
|
trigger_clear_access: null | boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
let {
|
||||||
|
log_lvl = $bindable(0),
|
||||||
|
hide = $bindable(false),
|
||||||
|
focus_input = $bindable(false),
|
||||||
|
expand = $bindable(false),
|
||||||
|
show_passcode_input = $bindable(false),
|
||||||
|
trigger_clear_access = $bindable(null)
|
||||||
|
}: Props = $props();
|
||||||
|
|
||||||
|
let entered_passcode: null | string = $state(null);
|
||||||
|
let checked_passcode: null | string = $state(null);
|
||||||
|
// let password_checked: boolean = $state(false);
|
||||||
|
// let entered_passcode: null|string = '';
|
||||||
|
// let show_passcode_input: boolean = $state(false);
|
||||||
|
// let show_passcode_input: boolean = false;
|
||||||
|
|
||||||
|
// let trigger: null|string|boolean = null;
|
||||||
|
let trigger: null | string | boolean = $state(null);
|
||||||
|
|
||||||
|
// const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
|
// WARNING: There is a bug (I think) around here related to the entered_passcode not being cleared. There seems to be something different about how Svelte handles state in this component compared to the others. This might be related to the `$effect` or `$derived` usage. Maybe there are conflicting things trying to update the $ae_loc store at the same time.
|
||||||
|
onMount(() => {
|
||||||
|
// log_lvl = 2;
|
||||||
|
if (log_lvl > 1) {
|
||||||
|
console.log('** Element Mounted: ** Element Access Type');
|
||||||
|
}
|
||||||
|
entered_passcode = '';
|
||||||
|
trigger = null;
|
||||||
|
|
||||||
|
// /** @type {HTMLElement | null} */
|
||||||
|
// const to_focus = document.getElementById('access_passcode_input');
|
||||||
|
// to_focus?.focus();
|
||||||
|
});
|
||||||
|
|
||||||
|
onDestroy(() => {
|
||||||
|
if (log_lvl > 1) {
|
||||||
|
console.log('** Element Destroyed: ** Element Access Type');
|
||||||
}
|
}
|
||||||
|
|
||||||
let {
|
// Clean up any references or listeners if needed
|
||||||
log_lvl = $bindable(0),
|
entered_passcode = null; // Clear the entered passcode
|
||||||
hide = $bindable(false),
|
show_passcode_input = false;
|
||||||
focus_input = $bindable(false),
|
|
||||||
expand = $bindable(false),
|
|
||||||
show_passcode_input = $bindable(false),
|
|
||||||
trigger_clear_access = $bindable(null)
|
|
||||||
}: Props = $props();
|
|
||||||
|
|
||||||
let entered_passcode: null | string = $state(null);
|
// Reset trigger
|
||||||
let checked_passcode: null | string = $state(null);
|
trigger = null;
|
||||||
// let password_checked: boolean = $state(false);
|
});
|
||||||
// let entered_passcode: null|string = '';
|
|
||||||
// let show_passcode_input: boolean = $state(false);
|
|
||||||
// let show_passcode_input: boolean = false;
|
|
||||||
|
|
||||||
// let trigger: null|string|boolean = null;
|
// afterNavigate(() => {
|
||||||
let trigger: null | string | boolean = $state(null);
|
// /** @type {HTMLElement | null} */
|
||||||
|
// const to_focus = document.getElementById('access_passcode_input');
|
||||||
|
// to_focus?.focus();
|
||||||
|
// });
|
||||||
|
|
||||||
// const dispatch = createEventDispatcher();
|
$effect(() => {
|
||||||
|
if (
|
||||||
|
entered_passcode &&
|
||||||
|
entered_passcode.length >= 5 &&
|
||||||
|
entered_passcode != checked_passcode
|
||||||
|
) {
|
||||||
|
checked_passcode = entered_passcode;
|
||||||
|
if (log_lvl) {
|
||||||
|
console.log(`entered_passcode=${entered_passcode}`);
|
||||||
|
}
|
||||||
|
handle_check_access_type_passcode();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// WARNING: There is a bug (I think) around here related to the entered_passcode not being cleared. There seems to be something different about how Svelte handles state in this component compared to the others. This might be related to the `$effect` or `$derived` usage. Maybe there are conflicting things trying to update the $ae_loc store at the same time.
|
$effect(() => {
|
||||||
onMount(() => {
|
if (trigger && $ae_loc.access_type) {
|
||||||
|
trigger = false;
|
||||||
|
if (log_lvl) {
|
||||||
|
console.log(`$ae_loc.access_type=${$ae_loc.access_type}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
let access_checks_results = ae_util.process_permission_checks(
|
||||||
|
$ae_loc.access_type
|
||||||
|
);
|
||||||
|
|
||||||
|
$ae_loc = { ...$ae_loc, ...access_checks_results };
|
||||||
|
$ae_loc = $ae_loc;
|
||||||
|
$ae_loc.sys_menu.expand = false;
|
||||||
|
} else if (trigger) {
|
||||||
|
trigger = false;
|
||||||
|
if (log_lvl) {
|
||||||
|
console.log(`$ae_loc.access_type=not set`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send an empty string to reset the permissions. This is the same as sending 'anonymous'.
|
||||||
|
let access_checks_results = ae_util.process_permission_checks('');
|
||||||
|
|
||||||
|
$ae_loc = { ...$ae_loc, ...access_checks_results };
|
||||||
|
$ae_loc = $ae_loc;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// This does not seem to work. I feel like it should though...?
|
||||||
|
$effect(() => {
|
||||||
|
if (!hide && focus_input) {
|
||||||
|
focus_input = false;
|
||||||
// log_lvl = 2;
|
// log_lvl = 2;
|
||||||
|
// await tick();
|
||||||
|
// document.getElementById('access_passcode_input')?.focus();
|
||||||
if (log_lvl > 1) {
|
if (log_lvl > 1) {
|
||||||
console.log('** Element Mounted: ** Element Access Type');
|
console.log('Effect: Setting focus on the passcode input field');
|
||||||
}
|
}
|
||||||
entered_passcode = '';
|
/** @type {HTMLElement | null} */
|
||||||
trigger = null;
|
const to_focus = document.getElementById('access_passcode_input');
|
||||||
|
to_focus?.focus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// /** @type {HTMLElement | null} */
|
$effect(() => {
|
||||||
// const to_focus = document.getElementById('access_passcode_input');
|
if (trigger_clear_access) {
|
||||||
// to_focus?.focus();
|
trigger_clear_access = false;
|
||||||
});
|
if (log_lvl) {
|
||||||
|
console.log(`trigger_clear_access=${trigger_clear_access}`);
|
||||||
onDestroy(() => {
|
|
||||||
if (log_lvl > 1) {
|
|
||||||
console.log('** Element Destroyed: ** Element Access Type');
|
|
||||||
}
|
}
|
||||||
|
handle_clear_access();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Clean up any references or listeners if needed
|
function handle_check_access_type_passcode() {
|
||||||
entered_passcode = null; // Clear the entered passcode
|
if (log_lvl > 1) {
|
||||||
show_passcode_input = false;
|
console.log(
|
||||||
|
`*** handle_check_access_type_passcode() *** passcode list:`,
|
||||||
|
$ae_loc.site_access_code_kv
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Reset trigger
|
// Reminder: super > manager > administrator > trusted > public > authenticated > anonymous
|
||||||
trigger = null;
|
|
||||||
});
|
|
||||||
|
|
||||||
// afterNavigate(() => {
|
if (entered_passcode && entered_passcode.length >= 5) {
|
||||||
// /** @type {HTMLElement | null} */
|
|
||||||
// const to_focus = document.getElementById('access_passcode_input');
|
|
||||||
// to_focus?.focus();
|
|
||||||
// });
|
|
||||||
|
|
||||||
$effect(() => {
|
|
||||||
if (
|
if (
|
||||||
entered_passcode &&
|
$ae_loc.site_access_code_kv.super.length >= 8 &&
|
||||||
entered_passcode.length >= 5 &&
|
$ae_loc.site_access_code_kv.super == entered_passcode
|
||||||
entered_passcode != checked_passcode
|
|
||||||
) {
|
) {
|
||||||
checked_passcode = entered_passcode;
|
console.log('Super passcode matched');
|
||||||
if (log_lvl) {
|
|
||||||
console.log(`entered_passcode=${entered_passcode}`);
|
|
||||||
}
|
|
||||||
handle_check_access_type_passcode();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$effect(() => {
|
window.localStorage.setItem('access_type', 'super');
|
||||||
if (trigger && $ae_loc.access_type) {
|
|
||||||
trigger = false;
|
|
||||||
if (log_lvl) {
|
|
||||||
console.log(`$ae_loc.access_type=${$ae_loc.access_type}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
let access_checks_results = ae_util.process_permission_checks($ae_loc.access_type);
|
$ae_loc.access_type = 'super';
|
||||||
|
} else if (
|
||||||
|
$ae_loc.site_access_code_kv.manager.length >= 5 &&
|
||||||
|
$ae_loc.site_access_code_kv.manager == entered_passcode
|
||||||
|
) {
|
||||||
|
console.log('Manager passcode matched');
|
||||||
|
|
||||||
$ae_loc = { ...$ae_loc, ...access_checks_results };
|
window.localStorage.setItem('access_type', 'manager');
|
||||||
$ae_loc = $ae_loc;
|
|
||||||
$ae_loc.sys_menu.expand = false;
|
|
||||||
} else if (trigger) {
|
|
||||||
trigger = false;
|
|
||||||
if (log_lvl) {
|
|
||||||
console.log(`$ae_loc.access_type=not set`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send an empty string to reset the permissions. This is the same as sending 'anonymous'.
|
$ae_loc.access_type = 'manager';
|
||||||
let access_checks_results = ae_util.process_permission_checks('');
|
} else if (
|
||||||
|
$ae_loc.site_access_code_kv.administrator.length >= 5 &&
|
||||||
|
$ae_loc.site_access_code_kv.administrator == entered_passcode
|
||||||
|
) {
|
||||||
|
console.log('Administrator passcode matched');
|
||||||
|
|
||||||
$ae_loc = { ...$ae_loc, ...access_checks_results };
|
window.localStorage.setItem('access_type', 'administrator');
|
||||||
$ae_loc = $ae_loc;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// This does not seem to work. I feel like it should though...?
|
$ae_loc.access_type = 'administrator';
|
||||||
$effect(() => {
|
} else if (
|
||||||
if (!hide && focus_input) {
|
$ae_loc.site_access_code_kv.trusted.length >= 5 &&
|
||||||
focus_input = false;
|
$ae_loc.site_access_code_kv.trusted == entered_passcode
|
||||||
// log_lvl = 2;
|
) {
|
||||||
// await tick();
|
console.log('Trusted passcode matched');
|
||||||
// document.getElementById('access_passcode_input')?.focus();
|
|
||||||
|
window.localStorage.setItem('access_type', 'trusted');
|
||||||
|
|
||||||
|
$ae_loc.access_type = 'trusted';
|
||||||
|
} else if (
|
||||||
|
$ae_loc.site_access_code_kv.public.length >= 5 &&
|
||||||
|
$ae_loc.site_access_code_kv.public == entered_passcode
|
||||||
|
) {
|
||||||
|
console.log('Public passcode matched');
|
||||||
|
|
||||||
|
window.localStorage.setItem('access_type', 'public');
|
||||||
|
|
||||||
|
$ae_loc.access_type = 'public';
|
||||||
|
} else if (
|
||||||
|
$ae_loc.site_access_code_kv.authenticated == entered_passcode
|
||||||
|
) {
|
||||||
|
console.log('Authenticated passcode matched');
|
||||||
|
|
||||||
|
window.localStorage.setItem('access_type', 'authenticated');
|
||||||
|
|
||||||
|
$ae_loc.access_type = 'authenticated';
|
||||||
|
} else {
|
||||||
if (log_lvl > 1) {
|
if (log_lvl > 1) {
|
||||||
console.log('Effect: Setting focus on the passcode input field');
|
console.log(
|
||||||
}
|
'Entered passcode does not match any of the site access codes.'
|
||||||
/** @type {HTMLElement | null} */
|
);
|
||||||
const to_focus = document.getElementById('access_passcode_input');
|
|
||||||
to_focus?.focus();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$effect(() => {
|
|
||||||
if (trigger_clear_access) {
|
|
||||||
trigger_clear_access = false;
|
|
||||||
if (log_lvl) {
|
|
||||||
console.log(`trigger_clear_access=${trigger_clear_access}`);
|
|
||||||
}
|
|
||||||
handle_clear_access();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function handle_check_access_type_passcode() {
|
|
||||||
if (log_lvl > 1) {
|
|
||||||
console.log(
|
|
||||||
`*** handle_check_access_type_passcode() *** passcode list:`,
|
|
||||||
$ae_loc.site_access_code_kv
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reminder: super > manager > administrator > trusted > public > authenticated > anonymous
|
|
||||||
|
|
||||||
if (entered_passcode && entered_passcode.length >= 5) {
|
|
||||||
if (
|
|
||||||
$ae_loc.site_access_code_kv.super.length >= 8 &&
|
|
||||||
$ae_loc.site_access_code_kv.super == entered_passcode
|
|
||||||
) {
|
|
||||||
console.log('Super passcode matched');
|
|
||||||
|
|
||||||
window.localStorage.setItem('access_type', 'super');
|
|
||||||
|
|
||||||
$ae_loc.access_type = 'super';
|
|
||||||
} else if (
|
|
||||||
$ae_loc.site_access_code_kv.manager.length >= 5 &&
|
|
||||||
$ae_loc.site_access_code_kv.manager == entered_passcode
|
|
||||||
) {
|
|
||||||
console.log('Manager passcode matched');
|
|
||||||
|
|
||||||
window.localStorage.setItem('access_type', 'manager');
|
|
||||||
|
|
||||||
$ae_loc.access_type = 'manager';
|
|
||||||
} else if (
|
|
||||||
$ae_loc.site_access_code_kv.administrator.length >= 5 &&
|
|
||||||
$ae_loc.site_access_code_kv.administrator == entered_passcode
|
|
||||||
) {
|
|
||||||
console.log('Administrator passcode matched');
|
|
||||||
|
|
||||||
window.localStorage.setItem('access_type', 'administrator');
|
|
||||||
|
|
||||||
$ae_loc.access_type = 'administrator';
|
|
||||||
} else if (
|
|
||||||
$ae_loc.site_access_code_kv.trusted.length >= 5 &&
|
|
||||||
$ae_loc.site_access_code_kv.trusted == entered_passcode
|
|
||||||
) {
|
|
||||||
console.log('Trusted passcode matched');
|
|
||||||
|
|
||||||
window.localStorage.setItem('access_type', 'trusted');
|
|
||||||
|
|
||||||
$ae_loc.access_type = 'trusted';
|
|
||||||
} else if (
|
|
||||||
$ae_loc.site_access_code_kv.public.length >= 5 &&
|
|
||||||
$ae_loc.site_access_code_kv.public == entered_passcode
|
|
||||||
) {
|
|
||||||
console.log('Public passcode matched');
|
|
||||||
|
|
||||||
window.localStorage.setItem('access_type', 'public');
|
|
||||||
|
|
||||||
$ae_loc.access_type = 'public';
|
|
||||||
} else if ($ae_loc.site_access_code_kv.authenticated == entered_passcode) {
|
|
||||||
console.log('Authenticated passcode matched');
|
|
||||||
|
|
||||||
window.localStorage.setItem('access_type', 'authenticated');
|
|
||||||
|
|
||||||
$ae_loc.access_type = 'authenticated';
|
|
||||||
} else {
|
|
||||||
if (log_lvl > 1) {
|
|
||||||
console.log('Entered passcode does not match any of the site access codes.');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($ae_loc.access_type != 'anonymous') {
|
|
||||||
console.log('Access type is not anonymous');
|
|
||||||
}
|
|
||||||
// window.localStorage.setItem('access_type', 'anonymous');
|
|
||||||
|
|
||||||
// $ae_loc.access_type = 'anonymous';
|
|
||||||
|
|
||||||
// trigger = 'process_permission_check';
|
|
||||||
|
|
||||||
// $ae_loc = $ae_loc; // Trigger Svelte just in case
|
|
||||||
// ae_loc.set($ae_loc);
|
|
||||||
// console.log($ae_loc);
|
|
||||||
|
|
||||||
// dispatch_access_type_changed();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
entered_passcode = '';
|
if ($ae_loc.access_type != 'anonymous') {
|
||||||
show_passcode_input = false;
|
console.log('Access type is not anonymous');
|
||||||
trigger = 'process_permission_check';
|
|
||||||
|
|
||||||
$ae_loc.app_cfg.show_element__menu = false;
|
|
||||||
$ae_loc.app_cfg.show_element__menu_btn = true;
|
|
||||||
|
|
||||||
// WARNING 2024-08-21: For some reason the config element does not auto show or hide when the access type changes.
|
|
||||||
if (!$ae_loc.iframe && $ae_loc.authenticated_access) {
|
|
||||||
$ae_loc.app_cfg.show_element__access_type = true;
|
|
||||||
$ae_loc.app_cfg.show_element__cfg = true;
|
|
||||||
} else if ($ae_loc.iframe && $ae_loc.trusted_access) {
|
|
||||||
$ae_loc.app_cfg.show_element__access_type = true;
|
|
||||||
$ae_loc.app_cfg.show_element__cfg = true;
|
|
||||||
} else {
|
|
||||||
$ae_loc.app_cfg.show_element__access_type = true;
|
|
||||||
$ae_loc.app_cfg.show_element__cfg = false;
|
|
||||||
}
|
}
|
||||||
|
// window.localStorage.setItem('access_type', 'anonymous');
|
||||||
|
|
||||||
|
// $ae_loc.access_type = 'anonymous';
|
||||||
|
|
||||||
|
// trigger = 'process_permission_check';
|
||||||
|
|
||||||
|
// $ae_loc = $ae_loc; // Trigger Svelte just in case
|
||||||
|
// ae_loc.set($ae_loc);
|
||||||
|
// console.log($ae_loc);
|
||||||
|
|
||||||
// dispatch_access_type_changed();
|
// dispatch_access_type_changed();
|
||||||
|
|
||||||
return true;
|
return false;
|
||||||
} else {
|
|
||||||
if (log_lvl > 1) {
|
|
||||||
console.log('Entered passcode too short.');
|
|
||||||
}
|
|
||||||
|
|
||||||
// $ae_loc.access_type = null; // 'anonymous';
|
|
||||||
|
|
||||||
// dispatch_access_type_changed()
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function handle_clear_access() {
|
entered_passcode = '';
|
||||||
// console.log('handle_clear_access()');
|
show_passcode_input = false;
|
||||||
// NOTE: I think it makes since to reset this to anonymous even if logged in as an admin or similar.
|
|
||||||
window.localStorage.setItem('access_type', 'anonymous');
|
|
||||||
|
|
||||||
// $ae_loc.access_type = null; // 'anonymous';
|
|
||||||
// Revert back to the user's access type after quick access (temporarily escalate permissions) is turned off.
|
|
||||||
$ae_loc.access_type = $ae_loc.user_access_type ?? 'anonymous';
|
|
||||||
trigger = 'process_permission_check';
|
trigger = 'process_permission_check';
|
||||||
|
|
||||||
entered_passcode = ''; // Clear the entered passcode
|
|
||||||
// Reset so the same passcode can be re-entered after clearing.
|
|
||||||
// Without this, the $effect guard (entered_passcode != checked_passcode) silently
|
|
||||||
// blocks re-entry of the same passcode until the component remounts (page refresh).
|
|
||||||
checked_passcode = null;
|
|
||||||
show_passcode_input = true;
|
|
||||||
|
|
||||||
$ae_loc.app_cfg.show_element__menu = false;
|
$ae_loc.app_cfg.show_element__menu = false;
|
||||||
$ae_loc.app_cfg.show_element__menu_btn = true;
|
$ae_loc.app_cfg.show_element__menu_btn = true;
|
||||||
|
|
||||||
$ae_loc.edit_mode = false;
|
// WARNING 2024-08-21: For some reason the config element does not auto show or hide when the access type changes.
|
||||||
|
if (!$ae_loc.iframe && $ae_loc.authenticated_access) {
|
||||||
|
$ae_loc.app_cfg.show_element__access_type = true;
|
||||||
|
$ae_loc.app_cfg.show_element__cfg = true;
|
||||||
|
} else if ($ae_loc.iframe && $ae_loc.trusted_access) {
|
||||||
|
$ae_loc.app_cfg.show_element__access_type = true;
|
||||||
|
$ae_loc.app_cfg.show_element__cfg = true;
|
||||||
|
} else {
|
||||||
|
$ae_loc.app_cfg.show_element__access_type = true;
|
||||||
|
$ae_loc.app_cfg.show_element__cfg = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// dispatch_access_type_changed();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
} else {
|
||||||
|
if (log_lvl > 1) {
|
||||||
|
console.log('Entered passcode too short.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// $ae_loc.access_type = null; // 'anonymous';
|
||||||
|
|
||||||
|
// dispatch_access_type_changed()
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handle_clear_access() {
|
||||||
|
// console.log('handle_clear_access()');
|
||||||
|
// NOTE: I think it makes since to reset this to anonymous even if logged in as an admin or similar.
|
||||||
|
window.localStorage.setItem('access_type', 'anonymous');
|
||||||
|
|
||||||
|
// $ae_loc.access_type = null; // 'anonymous';
|
||||||
|
// Revert back to the user's access type after quick access (temporarily escalate permissions) is turned off.
|
||||||
|
$ae_loc.access_type = $ae_loc.user_access_type ?? 'anonymous';
|
||||||
|
trigger = 'process_permission_check';
|
||||||
|
|
||||||
|
entered_passcode = ''; // Clear the entered passcode
|
||||||
|
// Reset so the same passcode can be re-entered after clearing.
|
||||||
|
// Without this, the $effect guard (entered_passcode != checked_passcode) silently
|
||||||
|
// blocks re-entry of the same passcode until the component remounts (page refresh).
|
||||||
|
checked_passcode = null;
|
||||||
|
show_passcode_input = true;
|
||||||
|
|
||||||
|
$ae_loc.app_cfg.show_element__menu = false;
|
||||||
|
$ae_loc.app_cfg.show_element__menu_btn = true;
|
||||||
|
|
||||||
|
$ae_loc.edit_mode = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<section
|
<section
|
||||||
@@ -298,24 +323,23 @@
|
|||||||
ae_access_type
|
ae_access_type
|
||||||
hidden-print
|
hidden-print
|
||||||
|
|
||||||
bg-blue-100 text-gray-900
|
flex w-full
|
||||||
dark:bg-blue-800 dark:text-gray-200
|
flex-col flex-wrap
|
||||||
|
|
||||||
flex flex-col flex-wrap gap-1
|
items-end justify-center gap-1 border-2
|
||||||
items-end justify-center
|
border-gray-200 bg-blue-100
|
||||||
|
|
||||||
w-full
|
|
||||||
p-1
|
p-1
|
||||||
border-2 border-gray-200
|
text-gray-900
|
||||||
|
transition-all delay-150
|
||||||
|
|
||||||
duration-300 delay-150 hover:delay-1000 hover:ease-out
|
duration-300 hover:delay-1000 hover:ease-out dark:bg-blue-800
|
||||||
transition-all
|
dark:text-gray-200
|
||||||
"
|
"
|
||||||
class:hidden={hide}
|
class:hidden={hide}>
|
||||||
>
|
|
||||||
<!-- class:hidden={!$ae_sess.show__sign_in_out__fields} -->
|
<!-- class:hidden={!$ae_sess.show__sign_in_out__fields} -->
|
||||||
<header class="ae_header hidden">
|
<header class="ae_header hidden">
|
||||||
<h2 class="text-sm text-center font-semibold">Passcode Sign In</h2>
|
<h2 class="text-center text-sm font-semibold">Passcode Sign In</h2>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<!-- Show list of authorized sessions and presentations for a user -->
|
<!-- Show list of authorized sessions and presentations for a user -->
|
||||||
@@ -349,9 +373,8 @@
|
|||||||
// tick();
|
// tick();
|
||||||
return false;
|
return false;
|
||||||
}}
|
}}
|
||||||
class="btn btn-sm preset-tonal-success border border-success-500 hover:preset-filled-success-500 transition-all hover:transition-all *:hover:inline"
|
class="btn btn-sm preset-tonal-success border-success-500 hover:preset-filled-success-500 border transition-all hover:transition-all *:hover:inline"
|
||||||
title="Syncing the local configuration with the remote configuration."
|
title="Syncing the local configuration with the remote configuration.">
|
||||||
>
|
|
||||||
<RefreshCw size="1em" class="m-1" />
|
<RefreshCw size="1em" class="m-1" />
|
||||||
<span class="hidden"> Sync </span>
|
<span class="hidden"> Sync </span>
|
||||||
</button>
|
</button>
|
||||||
@@ -369,9 +392,8 @@
|
|||||||
// tick();
|
// tick();
|
||||||
return true;
|
return true;
|
||||||
}}
|
}}
|
||||||
class="btn btn-sm preset-tonal-warning border border-warning-500 hover:preset-filled-warning-500 transition-all hover:transition-all *:hover:inline"
|
class="btn btn-sm preset-tonal-warning border-warning-500 hover:preset-filled-warning-500 border transition-all hover:transition-all *:hover:inline"
|
||||||
title="Currently not syncing with the remote server. Re-sync the local configuration with the remote configuration?"
|
title="Currently not syncing with the remote server. Re-sync the local configuration with the remote configuration?">
|
||||||
>
|
|
||||||
<Unlink size="1em" class="m-1" />
|
<Unlink size="1em" class="m-1" />
|
||||||
<span class="hidden"> Re-sync? </span>
|
<span class="hidden"> Re-sync? </span>
|
||||||
</button>
|
</button>
|
||||||
@@ -411,7 +433,8 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-row flex-wrap gap-1 items-end justify-end w-full transition-all">
|
<div
|
||||||
|
class="flex w-full flex-row flex-wrap items-end justify-end gap-1 transition-all">
|
||||||
{#if $ae_loc?.access_type && $ae_loc?.access_type == 'anonymous'}
|
{#if $ae_loc?.access_type && $ae_loc?.access_type == 'anonymous'}
|
||||||
<span>
|
<span>
|
||||||
<button
|
<button
|
||||||
@@ -421,15 +444,16 @@
|
|||||||
show_passcode_input = !show_passcode_input;
|
show_passcode_input = !show_passcode_input;
|
||||||
}}
|
}}
|
||||||
class="btn btn-sm preset-tonal-success hover:preset-filled-warning-500 access_type_unlock_btn transition-all"
|
class="btn btn-sm preset-tonal-success hover:preset-filled-warning-500 access_type_unlock_btn transition-all"
|
||||||
title={show_passcode_input ? 'Cancel passcode entry' : 'Enter a passcode to unlock access'}
|
title={show_passcode_input
|
||||||
>
|
? 'Cancel passcode entry'
|
||||||
|
: 'Enter a passcode to unlock access'}>
|
||||||
{#if show_passcode_input}
|
{#if show_passcode_input}
|
||||||
<LockOpen size="1em" class="mx-1" />
|
<LockOpen size="1em" class="mx-1" />
|
||||||
<span>Cancel</span>
|
<span>Cancel</span>
|
||||||
{:else}
|
{:else}
|
||||||
<Lock size="1em" class="mx-1" />
|
<Lock size="1em" class="mx-1" />
|
||||||
<span class="lock_icon">Locked</span>
|
<span class="lock_icon">Locked</span>
|
||||||
<LockOpen size="1em" class="mx-1 unlock_icon hidden" />
|
<LockOpen size="1em" class="unlock_icon mx-1 hidden" />
|
||||||
<span class="unlock_text">Access?</span>
|
<span class="unlock_text">Access?</span>
|
||||||
{/if}
|
{/if}
|
||||||
</button>
|
</button>
|
||||||
@@ -437,14 +461,13 @@
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if $ae_loc?.access_type && $ae_loc?.access_type != 'anonymous'}
|
{#if $ae_loc?.access_type && $ae_loc?.access_type != 'anonymous'}
|
||||||
<span class="flex flex-row gap-1 items-center justify-center">
|
<span class="flex flex-row items-center justify-center gap-1">
|
||||||
<!-- <span class="fas fa-unlock mx-1"></span> -->
|
<!-- <span class="fas fa-unlock mx-1"></span> -->
|
||||||
<ShieldPlus class="inline-block" />
|
<ShieldPlus class="inline-block" />
|
||||||
|
|
||||||
<span
|
<span
|
||||||
class="*:hover:inline"
|
class="*:hover:inline"
|
||||||
title={`Current access type/level: ${$ae_loc.access_type}`}
|
title={`Current access type/level: ${$ae_loc.access_type}`}>
|
||||||
>
|
|
||||||
{#if $ae_loc.access_type == 'super'}
|
{#if $ae_loc.access_type == 'super'}
|
||||||
<Wand2 size="1em" class="m-1" />
|
<Wand2 size="1em" class="m-1" />
|
||||||
<span class="hidden">Super</span>
|
<span class="hidden">Super</span>
|
||||||
@@ -478,9 +501,8 @@
|
|||||||
// trigger_clear_access = true;
|
// trigger_clear_access = true;
|
||||||
show_passcode_input = true;
|
show_passcode_input = true;
|
||||||
}}
|
}}
|
||||||
class="btn btn-sm variant-outline-surface hover:preset-tonal-warning border border-warning-500 transition-all"
|
class="btn btn-sm variant-outline-surface hover:preset-tonal-warning border-warning-500 border transition-all"
|
||||||
title={`Current user access level: "${$ae_loc.user_access_type}". Click use passcode for a different access level.`}
|
title={`Current user access level: "${$ae_loc.user_access_type}". Click use passcode for a different access level.`}>
|
||||||
>
|
|
||||||
<!-- <span class="fas fa-lock mx-1"></span> -->
|
<!-- <span class="fas fa-lock mx-1"></span> -->
|
||||||
<!-- <ShieldMinus /> -->
|
<!-- <ShieldMinus /> -->
|
||||||
<ShieldEllipsis class="inline-block" />
|
<ShieldEllipsis class="inline-block" />
|
||||||
@@ -495,9 +517,8 @@
|
|||||||
show_passcode_input = true;
|
show_passcode_input = true;
|
||||||
// show_passcode_input = true;
|
// show_passcode_input = true;
|
||||||
}}
|
}}
|
||||||
class="btn btn-sm variant-outline-warning hover:preset-tonal-warning border border-warning-500 transition-all"
|
class="btn btn-sm variant-outline-warning hover:preset-tonal-warning border-warning-500 border transition-all"
|
||||||
title={`Current access level: "${$ae_loc.access_type}". Click to clear the temporary access level.`}
|
title={`Current access level: "${$ae_loc.access_type}". Click to clear the temporary access level.`}>
|
||||||
>
|
|
||||||
<!-- <span class="fas fa-lock mx-1"></span> -->
|
<!-- <span class="fas fa-lock mx-1"></span> -->
|
||||||
<ShieldMinus class="inline-block" />
|
<ShieldMinus class="inline-block" />
|
||||||
Clear?
|
Clear?
|
||||||
@@ -507,7 +528,8 @@
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if show_passcode_input}
|
{#if show_passcode_input}
|
||||||
<span class="flex flex-row gap-1 items-center justify-between w-full">
|
<span
|
||||||
|
class="flex w-full flex-row items-center justify-between gap-1">
|
||||||
<span>
|
<span>
|
||||||
<ShieldEllipsis class="inline-block text-gray-500" />
|
<ShieldEllipsis class="inline-block text-gray-500" />
|
||||||
<span class="unlock_text text-sm">Passcode:</span>
|
<span class="unlock_text text-sm">Passcode:</span>
|
||||||
@@ -521,8 +543,7 @@
|
|||||||
class:hidden={!show_passcode_input}
|
class:hidden={!show_passcode_input}
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Passcode"
|
placeholder="Passcode"
|
||||||
autofocus={show_passcode_input}
|
autofocus={show_passcode_input} />
|
||||||
/>
|
|
||||||
<!-- <div class="current_text transition-all">{$ae_loc.access_type}</div> -->
|
<!-- <div class="current_text transition-all">{$ae_loc.access_type}</div> -->
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -530,8 +551,8 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
/* BEGIN: AE's Svelte Quick Access Type component */
|
/* BEGIN: AE's Svelte Quick Access Type component */
|
||||||
/*
|
/*
|
||||||
#xxx-AE-Quick-Access-Type {
|
#xxx-AE-Quick-Access-Type {
|
||||||
// position: absolute;
|
// position: absolute;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@@ -569,7 +590,7 @@
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#xxx-AE-Quick-Access-Type:hover {
|
#xxx-AE-Quick-Access-Type:hover {
|
||||||
|
|
||||||
border-top: solid thin hsla(0,0%,0%,.95);
|
border-top: solid thin hsla(0,0%,0%,.95);
|
||||||
@@ -586,21 +607,21 @@
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* #Access-Type .unlock_text {
|
/* #Access-Type .unlock_text {
|
||||||
transition: width 2s, height 2s, background-color 2s, transform 2s;
|
transition: width 2s, height 2s, background-color 2s, transform 2s;
|
||||||
} */
|
} */
|
||||||
/* END: Svelte Access Type component */
|
/* END: Svelte Access Type component */
|
||||||
|
|
||||||
.access_type_unlock_btn .unlock_text {
|
.access_type_unlock_btn .unlock_text {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.access_type_unlock_btn:hover .unlock_text {
|
.access_type_unlock_btn:hover .unlock_text {
|
||||||
display: initial;
|
display: initial;
|
||||||
/* outline: solid thin red; */
|
/* outline: solid thin red; */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
.ae_access_type .current_text {
|
.ae_access_type .current_text {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,44 +1,54 @@
|
|||||||
<script lang="ts" module>
|
<script lang="ts" module>
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
dataLayer: any[];
|
dataLayer: any[];
|
||||||
gtag: (...args: any[]) => void;
|
gtag: (...args: any[]) => void;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { browser } from '$app/environment';
|
import { browser } from '$app/environment';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
site_google_tracking_id?: string;
|
site_google_tracking_id?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
let { log_lvl = 0, site_google_tracking_id = $bindable('') }: Props = $props();
|
let { log_lvl = 0, site_google_tracking_id = $bindable('') }: Props = $props();
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (browser && site_google_tracking_id) {
|
if (browser && site_google_tracking_id) {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`AE Analytics: site_google_tracking_id = `, site_google_tracking_id);
|
console.log(
|
||||||
}
|
`AE Analytics: site_google_tracking_id = `,
|
||||||
|
site_google_tracking_id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
window.dataLayer = window.dataLayer || [];
|
window.dataLayer = window.dataLayer || [];
|
||||||
window.gtag = window.gtag || function gtag() {
|
window.gtag =
|
||||||
|
window.gtag ||
|
||||||
|
function gtag() {
|
||||||
window.dataLayer.push(arguments);
|
window.dataLayer.push(arguments);
|
||||||
};
|
};
|
||||||
window.gtag('js', new Date());
|
window.gtag('js', new Date());
|
||||||
window.gtag('config', site_google_tracking_id);
|
window.gtag('config', site_google_tracking_id);
|
||||||
|
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`AE Analytics: Google Analytics Tracking ID = `, site_google_tracking_id);
|
console.log(
|
||||||
}
|
`AE Analytics: Google Analytics Tracking ID = `,
|
||||||
|
site_google_tracking_id
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
{#if site_google_tracking_id}
|
{#if site_google_tracking_id}
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id={site_google_tracking_id}"></script>
|
<script
|
||||||
|
async
|
||||||
|
src="https://www.googletagmanager.com/gtag/js?id={site_google_tracking_id}"></script>
|
||||||
{/if}
|
{/if}
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|||||||
@@ -1,103 +1,120 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Code, Eraser, LockOpen, RefreshCw, Settings, ShieldCheck, ShieldUser, Trash2, UserRound, Users } from '@lucide/svelte';
|
import {
|
||||||
import { ae_util } from '$lib/ae_utils/ae_utils';
|
Code,
|
||||||
import { ae_loc, ae_sess, ae_api, slct, slct_trigger } from '$lib/stores/ae_stores';
|
Eraser,
|
||||||
import E_app_url_builder from '$lib/app_components/e_app_url_builder.svelte';
|
LockOpen,
|
||||||
|
RefreshCw,
|
||||||
|
Settings,
|
||||||
|
ShieldCheck,
|
||||||
|
ShieldUser,
|
||||||
|
Trash2,
|
||||||
|
UserRound,
|
||||||
|
Users
|
||||||
|
} from '@lucide/svelte';
|
||||||
|
import { ae_util } from '$lib/ae_utils/ae_utils';
|
||||||
|
import {
|
||||||
|
ae_loc,
|
||||||
|
ae_sess,
|
||||||
|
ae_api,
|
||||||
|
slct,
|
||||||
|
slct_trigger
|
||||||
|
} from '$lib/stores/ae_stores';
|
||||||
|
import E_app_url_builder from '$lib/app_components/e_app_url_builder.svelte';
|
||||||
|
|
||||||
// import Element_theme from '$lib/e_app_theme.svelte';
|
// import Element_theme from '$lib/e_app_theme.svelte';
|
||||||
|
|
||||||
let notes: null | string = null;
|
let notes: null | string = null;
|
||||||
let all: boolean = false;
|
let all: boolean = false;
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
hide?: null | boolean;
|
hide?: null | boolean;
|
||||||
expand?: boolean;
|
expand?: boolean;
|
||||||
// export let theme_mode: null|string = null;
|
// export let theme_mode: null|string = null;
|
||||||
// set_theme_mode?: null|boolean;
|
// set_theme_mode?: null|boolean;
|
||||||
// export let theme_name: null|string = null;
|
// export let theme_name: null|string = null;
|
||||||
// set_theme_name?: null|boolean;
|
// set_theme_name?: null|boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
let {
|
let {
|
||||||
log_lvl = $bindable(0),
|
log_lvl = $bindable(0),
|
||||||
hide = $bindable(false),
|
hide = $bindable(false),
|
||||||
expand = $bindable(false)
|
expand = $bindable(false)
|
||||||
// set_theme_mode = null,
|
// set_theme_mode = null,
|
||||||
// set_theme_name = null
|
// set_theme_name = null
|
||||||
}: Props = $props();
|
}: Props = $props();
|
||||||
|
|
||||||
// const dispatch = createEventDispatcher();
|
// const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
// onMount(() => {
|
// onMount(() => {
|
||||||
// // console.log('** Element Mounted: ** Element App Config');
|
// // console.log('** Element Mounted: ** Element App Config');
|
||||||
// if (set_theme_mode) {
|
// if (set_theme_mode) {
|
||||||
// $slct_trigger = 'set_theme_mode';
|
// $slct_trigger = 'set_theme_mode';
|
||||||
// }
|
// }
|
||||||
// if (set_theme_name) {
|
// if (set_theme_name) {
|
||||||
// $slct_trigger = 'set_theme_name';
|
// $slct_trigger = 'set_theme_name';
|
||||||
// }
|
// }
|
||||||
// });
|
// });
|
||||||
|
|
||||||
// $: if ($slct_trigger == 'set_theme_mode' && $ae_loc?.app_cfg?.theme_mode) {
|
// $: if ($slct_trigger == 'set_theme_mode' && $ae_loc?.app_cfg?.theme_mode) {
|
||||||
// console.log(`$ae_loc.app_cfg.theme_mode=${$ae_loc?.app_cfg?.theme_mode}`);
|
// console.log(`$ae_loc.app_cfg.theme_mode=${$ae_loc?.app_cfg?.theme_mode}`);
|
||||||
// $slct_trigger = null;
|
// $slct_trigger = null;
|
||||||
// if ($ae_loc.app_cfg.theme_mode == 'light') {
|
// if ($ae_loc.app_cfg.theme_mode == 'light') {
|
||||||
// document.documentElement.classList.remove('dark');
|
// document.documentElement.classList.remove('dark');
|
||||||
// document.documentElement.classList.add('light');
|
// document.documentElement.classList.add('light');
|
||||||
// } else if ($ae_loc.app_cfg.theme_mode == 'dark') {
|
// } else if ($ae_loc.app_cfg.theme_mode == 'dark') {
|
||||||
// document.documentElement.classList.remove('light');
|
// document.documentElement.classList.remove('light');
|
||||||
// document.documentElement.classList.add('dark');
|
// document.documentElement.classList.add('dark');
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// $: if ($slct_trigger == 'set_theme_name' && $ae_loc?.app_cfg?.theme_name) {
|
// $: if ($slct_trigger == 'set_theme_name' && $ae_loc?.app_cfg?.theme_name) {
|
||||||
// console.log(`$ae_loc?.app_cfg?.theme_name=${$ae_loc?.app_cfg?.theme_name}`);
|
// console.log(`$ae_loc?.app_cfg?.theme_name=${$ae_loc?.app_cfg?.theme_name}`);
|
||||||
// $slct_trigger = null;
|
// $slct_trigger = null;
|
||||||
// // Update the body attribute named "data-theme" to the current theme name.
|
// // Update the body attribute named "data-theme" to the current theme name.
|
||||||
// document.body.setAttribute('data-theme', $ae_loc?.app_cfg?.theme_name);
|
// document.body.setAttribute('data-theme', $ae_loc?.app_cfg?.theme_name);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// $: if (entered_passcode && entered_passcode.length >= 5) {
|
// $: if (entered_passcode && entered_passcode.length >= 5) {
|
||||||
// console.log(`entered_passcode=${entered_passcode}`);
|
// console.log(`entered_passcode=${entered_passcode}`);
|
||||||
// handle_check_access_type_passcode();
|
// handle_check_access_type_passcode();
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// $: if (trigger && $ae_loc.access_type) {
|
// $: if (trigger && $ae_loc.access_type) {
|
||||||
// console.log(`$ae_loc.access_type=${$ae_loc.access_type}`);
|
// console.log(`$ae_loc.access_type=${$ae_loc.access_type}`);
|
||||||
|
|
||||||
// let access_checks_results = ae_util.process_permission_checks($ae_loc.access_type);
|
// let access_checks_results = ae_util.process_permission_checks($ae_loc.access_type);
|
||||||
|
|
||||||
// $ae_loc = {...$ae_loc, ...access_checks_results};
|
// $ae_loc = {...$ae_loc, ...access_checks_results};
|
||||||
// } else if (trigger) {
|
// } else if (trigger) {
|
||||||
// console.log(`$ae_loc.access_type=not set`);
|
// console.log(`$ae_loc.access_type=not set`);
|
||||||
|
|
||||||
// // Send an empty string to reset the permissions. This is the same as sending 'anonymous'.
|
// // Send an empty string to reset the permissions. This is the same as sending 'anonymous'.
|
||||||
// let access_checks_results = ae_util.process_permission_checks('');
|
// let access_checks_results = ae_util.process_permission_checks('');
|
||||||
|
|
||||||
// $ae_loc = {...$ae_loc, ...access_checks_results};
|
// $ae_loc = {...$ae_loc, ...access_checks_results};
|
||||||
// }
|
// }
|
||||||
|
|
||||||
function handle_something() {
|
function handle_something() {
|
||||||
// console.log('*** handle_something() ***');
|
// console.log('*** handle_something() ***');
|
||||||
}
|
}
|
||||||
|
|
||||||
function handle_clear_storage(item: null | string) {
|
function handle_clear_storage(item: null | string) {
|
||||||
// console.log('*** handle_clear_storage() ***');
|
// console.log('*** handle_clear_storage() ***');
|
||||||
// window.localStorage.setItem('access_type', 'anonymous');
|
// window.localStorage.setItem('access_type', 'anonymous');
|
||||||
// return true;
|
// return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// function dispatch_something_changed() {
|
// function dispatch_something_changed() {
|
||||||
// console.log('*** dispatch_something_changed() ***');
|
// console.log('*** dispatch_something_changed() ***');
|
||||||
|
|
||||||
// console.log(ae_util);
|
// console.log(ae_util);
|
||||||
// console.log($ae_loc);
|
// console.log($ae_loc);
|
||||||
|
|
||||||
// dispatch('access_type_changed', {
|
// dispatch('access_type_changed', {
|
||||||
// access_type: $ae_loc.access_type
|
// access_type: $ae_loc.access_type
|
||||||
// });
|
// });
|
||||||
// }
|
// }
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- transition duration-500 delay-1000 hover:duration-500 hover:delay-1000 hover:transition-all -->
|
<!-- transition duration-500 delay-1000 hover:duration-500 hover:delay-1000 hover:transition-all -->
|
||||||
@@ -107,30 +124,28 @@
|
|||||||
ae_app_cfg
|
ae_app_cfg
|
||||||
hidden-print
|
hidden-print
|
||||||
|
|
||||||
bg-blue-100 text-gray-900
|
flex w-72
|
||||||
dark:bg-blue-800 dark:text-gray-200
|
max-w-72 flex-col
|
||||||
|
|
||||||
flex flex-col flex-wrap gap-1
|
flex-wrap items-end justify-center gap-1
|
||||||
items-end justify-center
|
|
||||||
|
|
||||||
w-72 max-w-72
|
|
||||||
p-1
|
|
||||||
border-2 border-gray-200
|
border-2 border-gray-200
|
||||||
|
|
||||||
duration-300 delay-150 hover:delay-1000 hover:ease-out
|
bg-blue-100 p-1
|
||||||
transition-all
|
text-gray-900
|
||||||
|
transition-all delay-150
|
||||||
|
|
||||||
|
duration-300 hover:delay-1000 hover:ease-out dark:bg-blue-800
|
||||||
|
dark:text-gray-200
|
||||||
"
|
"
|
||||||
class:hidden={hide}
|
class:hidden={hide}>
|
||||||
>
|
|
||||||
<header class:hidden={!expand} class="ae_header w-full">
|
<header class:hidden={!expand} class="ae_header w-full">
|
||||||
<h2 class="text-sm text-center font-semibold">Config</h2>
|
<h2 class="text-center text-sm font-semibold">Config</h2>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="ae_cfg_content text-xs space-y-4 my-4"
|
class="ae_cfg_content my-4 space-y-4 text-xs"
|
||||||
class:hidden={!expand}
|
class:hidden={!expand}
|
||||||
data-sveltekit-preload-data="false"
|
data-sveltekit-preload-data="false">
|
||||||
>
|
|
||||||
<section class="space-y-2">
|
<section class="space-y-2">
|
||||||
<div>
|
<div>
|
||||||
<h2 class="strong">Access Type:</h2>
|
<h2 class="strong">Access Type:</h2>
|
||||||
@@ -172,12 +187,16 @@
|
|||||||
</a>
|
</a>
|
||||||
|
|
||||||
{#if $ae_loc.iframe}
|
{#if $ae_loc.iframe}
|
||||||
<a class="btn btn-sm preset-tonal-secondary" href="/?iframe=false">
|
<a
|
||||||
|
class="btn btn-sm preset-tonal-secondary"
|
||||||
|
href="/?iframe=false">
|
||||||
<Code size="1em" class="mx-1" />
|
<Code size="1em" class="mx-1" />
|
||||||
Exit iframe Mode
|
Exit iframe Mode
|
||||||
</a>
|
</a>
|
||||||
{:else}
|
{:else}
|
||||||
<a class="btn btn-sm preset-tonal-secondary" href="/?iframe=true">
|
<a
|
||||||
|
class="btn btn-sm preset-tonal-secondary"
|
||||||
|
href="/?iframe=true">
|
||||||
<Code size="1em" class="mx-1" />
|
<Code size="1em" class="mx-1" />
|
||||||
Use iframe Mode
|
Use iframe Mode
|
||||||
</a>
|
</a>
|
||||||
@@ -190,8 +209,7 @@
|
|||||||
onclick={() => {
|
onclick={() => {
|
||||||
// $ae_loc.
|
// $ae_loc.
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
}}
|
}}>
|
||||||
>
|
|
||||||
<RefreshCw size="1em" class="mx-1" />
|
<RefreshCw size="1em" class="mx-1" />
|
||||||
Reload &
|
Reload &
|
||||||
<Trash2 size="1em" class="mx-1" />
|
<Trash2 size="1em" class="mx-1" />
|
||||||
@@ -219,8 +237,7 @@
|
|||||||
|
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
// alert('Local and Session Storage cleared and Indexed DBs deleted. You will probably want to refresh the page.');
|
// alert('Local and Session Storage cleared and Indexed DBs deleted. You will probably want to refresh the page.');
|
||||||
}}
|
}}>
|
||||||
>
|
|
||||||
<Eraser size="1em" class="mx-1" />
|
<Eraser size="1em" class="mx-1" />
|
||||||
Clear Storage & DB
|
Clear Storage & DB
|
||||||
</button>
|
</button>
|
||||||
@@ -235,7 +252,7 @@
|
|||||||
|
|
||||||
<!-- class:justify-between={expand}
|
<!-- class:justify-between={expand}
|
||||||
class:justify-end={!expand} -->
|
class:justify-end={!expand} -->
|
||||||
<div class="flex flex-row gap-2 items-center justify-between w-full">
|
<div class="flex w-full flex-row items-center justify-between gap-2">
|
||||||
<!-- {#if !expand} -->
|
<!-- {#if !expand} -->
|
||||||
<span>
|
<span>
|
||||||
{#if $ae_loc.access_type && $ae_loc.access_type != 'anonymous'}
|
{#if $ae_loc.access_type && $ae_loc.access_type != 'anonymous'}
|
||||||
@@ -270,14 +287,13 @@ class:justify-end={!expand} -->
|
|||||||
<button
|
<button
|
||||||
class="
|
class="
|
||||||
ae_cfg_btn
|
ae_cfg_btn
|
||||||
btn btn-sm text-sm
|
btn btn-sm preset-tonal-warning
|
||||||
preset-tonal-warning
|
group
|
||||||
group transition-all
|
text-sm transition-all
|
||||||
"
|
"
|
||||||
onclick={() => {
|
onclick={() => {
|
||||||
expand = !expand;
|
expand = !expand;
|
||||||
}}
|
}}>
|
||||||
>
|
|
||||||
<!-- <span class="fas fa-cog m-1"></span> -->
|
<!-- <span class="fas fa-cog m-1"></span> -->
|
||||||
<span class="inline-block" title="Settings">
|
<span class="inline-block" title="Settings">
|
||||||
<Settings class="m-1" />
|
<Settings class="m-1" />
|
||||||
@@ -287,8 +303,7 @@ class:justify-end={!expand} -->
|
|||||||
cfg_text
|
cfg_text
|
||||||
hidden
|
hidden
|
||||||
group-hover:inline
|
group-hover:inline
|
||||||
"
|
">
|
||||||
>
|
|
||||||
Settings
|
Settings
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
@@ -296,21 +311,21 @@ class:justify-end={!expand} -->
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<style lang="postcss">
|
<style lang="postcss">
|
||||||
.ae_cfg_btn .cfg_text {
|
.ae_cfg_btn .cfg_text {
|
||||||
/* display: none; */
|
/* display: none; */
|
||||||
}
|
}
|
||||||
|
|
||||||
.ae_cfg_btn:hover .cfg_text {
|
.ae_cfg_btn:hover .cfg_text {
|
||||||
/* display: initial; */
|
/* display: initial; */
|
||||||
/* outline: solid thin red; */
|
/* outline: solid thin red; */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* .access_type .current_text {
|
/* .access_type .current_text {
|
||||||
display: none;
|
display: none;
|
||||||
} */
|
} */
|
||||||
|
|
||||||
/* .access_type:hover .current_text {
|
/* .access_type:hover .current_text {
|
||||||
display: initial;
|
display: initial;
|
||||||
} */
|
} */
|
||||||
/* END: AE's Svelte App Config component */
|
/* END: AE's Svelte App Config component */
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,73 +1,73 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
interface Props {
|
interface Props {
|
||||||
children?: import('svelte').Snippet;
|
children?: import('svelte').Snippet;
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
value: any;
|
value: any;
|
||||||
success?: boolean;
|
success?: boolean;
|
||||||
btn_text?: string;
|
btn_text?: string;
|
||||||
btn_title?: string;
|
btn_title?: string;
|
||||||
btn_class?: string;
|
btn_class?: string;
|
||||||
hide_icon?: boolean;
|
hide_icon?: boolean;
|
||||||
hide_text?: boolean;
|
hide_text?: boolean;
|
||||||
icon_name?: string;
|
icon_name?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
let {
|
||||||
|
children,
|
||||||
|
log_lvl = 0,
|
||||||
|
value = $bindable(''),
|
||||||
|
success = $bindable(false),
|
||||||
|
btn_text = 'Copy to Clipboard',
|
||||||
|
btn_title = 'Copy to Clipboard',
|
||||||
|
btn_class = 'btn btn-sm preset-tonal-warning text-warning-500 m-1',
|
||||||
|
hide_icon = false,
|
||||||
|
hide_text = false,
|
||||||
|
icon_name = 'copy' // copy, check, link
|
||||||
|
}: Props = $props();
|
||||||
|
|
||||||
|
// *** Import Svelte specific
|
||||||
|
// import { browser } from '$app/environment';
|
||||||
|
|
||||||
|
// *** Import other supporting libraries
|
||||||
|
import {
|
||||||
|
// ArrowBigRight,
|
||||||
|
// CircleX,
|
||||||
|
CircleCheck,
|
||||||
|
Copy,
|
||||||
|
// Eye, EyeOff,
|
||||||
|
// Key,
|
||||||
|
Link
|
||||||
|
// LogIn, LogOut, LockKeyhole,
|
||||||
|
// Mail, MailCheck,
|
||||||
|
// Menu,
|
||||||
|
// RefreshCw, RefreshCcw, RefreshCcwDot,
|
||||||
|
// ShieldEllipsis, ShieldMinus, ShieldPlus, ShieldUser,
|
||||||
|
// User, UserCheck
|
||||||
|
} from '@lucide/svelte';
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
if (log_lvl) {
|
||||||
|
console.log(`Clipboard component initialized with value:`, value);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
let {
|
// Select your trigger element
|
||||||
children,
|
// const elemButton: HTMLButtonElement | null = document.querySelector('[data-button]');
|
||||||
log_lvl = 0,
|
|
||||||
value = $bindable(''),
|
|
||||||
success = $bindable(false),
|
|
||||||
btn_text = 'Copy to Clipboard',
|
|
||||||
btn_title = 'Copy to Clipboard',
|
|
||||||
btn_class = 'btn btn-sm preset-tonal-warning text-warning-500 m-1',
|
|
||||||
hide_icon = false,
|
|
||||||
hide_text = false,
|
|
||||||
icon_name = 'copy' // copy, check, link
|
|
||||||
}: Props = $props();
|
|
||||||
|
|
||||||
// *** Import Svelte specific
|
// Add a click event handler to the trigger
|
||||||
// import { browser } from '$app/environment';
|
// elemButton?.addEventListener('click', () => {
|
||||||
|
// // Call the Clipboard API
|
||||||
// *** Import other supporting libraries
|
// navigator.clipboard
|
||||||
import {
|
// // Use the `writeText` method write content to the clipboard
|
||||||
// ArrowBigRight,
|
// .writeText(value)
|
||||||
// CircleX,
|
// // Handle confirmation
|
||||||
CircleCheck,
|
// .then(() => {
|
||||||
Copy,
|
// if (log_lvl) {
|
||||||
// Eye, EyeOff,
|
// console.log(`Clipboard write successful: ${value}`);
|
||||||
// Key,
|
// }
|
||||||
Link
|
// success = true;
|
||||||
// LogIn, LogOut, LockKeyhole,
|
// });
|
||||||
// Mail, MailCheck,
|
// });
|
||||||
// Menu,
|
|
||||||
// RefreshCw, RefreshCcw, RefreshCcwDot,
|
|
||||||
// ShieldEllipsis, ShieldMinus, ShieldPlus, ShieldUser,
|
|
||||||
// User, UserCheck
|
|
||||||
} from '@lucide/svelte';
|
|
||||||
|
|
||||||
$effect(() => {
|
|
||||||
if (log_lvl) {
|
|
||||||
console.log(`Clipboard component initialized with value:`, value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Select your trigger element
|
|
||||||
// const elemButton: HTMLButtonElement | null = document.querySelector('[data-button]');
|
|
||||||
|
|
||||||
// Add a click event handler to the trigger
|
|
||||||
// elemButton?.addEventListener('click', () => {
|
|
||||||
// // Call the Clipboard API
|
|
||||||
// navigator.clipboard
|
|
||||||
// // Use the `writeText` method write content to the clipboard
|
|
||||||
// .writeText(value)
|
|
||||||
// // Handle confirmation
|
|
||||||
// .then(() => {
|
|
||||||
// if (log_lvl) {
|
|
||||||
// console.log(`Clipboard write successful: ${value}`);
|
|
||||||
// }
|
|
||||||
// success = true;
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
@@ -93,15 +93,20 @@
|
|||||||
// }
|
// }
|
||||||
}}
|
}}
|
||||||
class={btn_class}
|
class={btn_class}
|
||||||
title={btn_title}
|
title={btn_title}>
|
||||||
>
|
|
||||||
<!-- {@render btn_text} -->
|
<!-- {@render btn_text} -->
|
||||||
{#if icon_name === 'link'}
|
{#if icon_name === 'link'}
|
||||||
<Link class="mx-1 {hide_icon ? 'hidden' : 'inline-block'}" size="1.2em" />
|
<Link
|
||||||
|
class="mx-1 {hide_icon ? 'hidden' : 'inline-block'}"
|
||||||
|
size="1.2em" />
|
||||||
{:else if icon_name === 'check'}
|
{:else if icon_name === 'check'}
|
||||||
<CircleCheck class="mx-1 {hide_icon ? 'hidden' : 'inline-block'}" size="1.2em" />
|
<CircleCheck
|
||||||
|
class="mx-1 {hide_icon ? 'hidden' : 'inline-block'}"
|
||||||
|
size="1.2em" />
|
||||||
{:else}
|
{:else}
|
||||||
<Copy class="mx-1 {hide_icon ? 'hidden' : 'inline-block'}" size="1.2em" />
|
<Copy
|
||||||
|
class="mx-1 {hide_icon ? 'hidden' : 'inline-block'}"
|
||||||
|
size="1.2em" />
|
||||||
{/if}
|
{/if}
|
||||||
<span class={hide_text ? 'hidden' : 'inline-block'}>
|
<span class={hide_text ? 'hidden' : 'inline-block'}>
|
||||||
{btn_text}
|
{btn_text}
|
||||||
|
|||||||
@@ -1,25 +1,31 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
// *** Import Svelte specific
|
// *** Import Svelte specific
|
||||||
|
|
||||||
// *** Import other supporting libraries
|
// *** Import other supporting libraries
|
||||||
import { Bug, CircleX, Info, ToggleLeft, ToggleRight, X } from '@lucide/svelte';
|
import { Bug, CircleX, Info, ToggleLeft, ToggleRight, X } from '@lucide/svelte';
|
||||||
|
|
||||||
// *** Import Aether specific variables and functions
|
// *** Import Aether specific variables and functions
|
||||||
// import { ae_util } from '$lib/ae_utils/ae_utils';
|
// import { ae_util } from '$lib/ae_utils/ae_utils';
|
||||||
import { ae_loc, ae_sess, ae_api, slct, slct_trigger } from '$lib/stores/ae_stores';
|
import {
|
||||||
|
ae_loc,
|
||||||
|
ae_sess,
|
||||||
|
ae_api,
|
||||||
|
slct,
|
||||||
|
slct_trigger
|
||||||
|
} from '$lib/stores/ae_stores';
|
||||||
|
|
||||||
// *** Setup Svelte properties
|
// *** Setup Svelte properties
|
||||||
interface Props {
|
interface Props {
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
hide?: null | boolean;
|
hide?: null | boolean;
|
||||||
expand?: boolean;
|
expand?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
let {
|
let {
|
||||||
log_lvl = $bindable(0),
|
log_lvl = $bindable(0),
|
||||||
hide = $bindable(false),
|
hide = $bindable(false),
|
||||||
expand = $bindable(false)
|
expand = $bindable(false)
|
||||||
}: Props = $props();
|
}: Props = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- App Debug Menu -->
|
<!-- App Debug Menu -->
|
||||||
@@ -31,28 +37,28 @@ hover:opacity-100 -->
|
|||||||
ae_app__debug_menu
|
ae_app__debug_menu
|
||||||
|
|
||||||
hidden-print
|
hidden-print
|
||||||
z-50
|
md:text-md
|
||||||
absolute bottom-0 left-0
|
lg:text-md xl:text-md transition-delay-1000
|
||||||
|
|
||||||
flex
|
|
||||||
text-sm sm:text-sm md:text-md lg:text-md xl:text-md 2xl:text-lg
|
|
||||||
|
|
||||||
dark:text-slate-400 dark:hover:text-slate-200
|
|
||||||
bg-red-100/60 dark:bg-red-800/50
|
|
||||||
hover:bg-red-200 hover:dark:bg-red-900
|
|
||||||
|
|
||||||
mx-1 my-2
|
|
||||||
max-h-min
|
|
||||||
max-w-lg
|
|
||||||
transition-all
|
|
||||||
transition-delay-1000
|
|
||||||
transition-duration-1000
|
transition-duration-1000
|
||||||
|
absolute bottom-0 left-0 z-50 mx-1 my-2
|
||||||
|
|
||||||
|
flex max-h-min
|
||||||
|
max-w-lg border-2
|
||||||
|
border-red-300 bg-red-100/60
|
||||||
|
|
||||||
|
text-sm transition-all
|
||||||
ease-in
|
ease-in
|
||||||
|
hover:border-red-500
|
||||||
|
hover:bg-red-200
|
||||||
|
sm:text-sm
|
||||||
|
2xl:text-lg
|
||||||
|
dark:border-red-700
|
||||||
|
|
||||||
|
|
||||||
border-2
|
dark:bg-red-800/50
|
||||||
border-red-300 dark:border-red-700
|
dark:text-slate-400 hover:dark:border-red-500
|
||||||
hover:border-red-500 hover:dark:border-red-500
|
hover:dark:bg-red-900 dark:hover:text-slate-200
|
||||||
"
|
"
|
||||||
class:top-0={expand}
|
class:top-0={expand}
|
||||||
class:w-full={expand}
|
class:w-full={expand}
|
||||||
@@ -60,29 +66,27 @@ hover:opacity-100 -->
|
|||||||
class:border-transparent={!expand}
|
class:border-transparent={!expand}
|
||||||
class:dark:border-transparent={!expand}
|
class:dark:border-transparent={!expand}
|
||||||
class:hover:border-transparent={!expand}
|
class:hover:border-transparent={!expand}
|
||||||
class:hover:bg-transparent={!expand}
|
class:hover:bg-transparent={!expand}>
|
||||||
>
|
|
||||||
<div
|
<div
|
||||||
class:hidden={!expand}
|
class:hidden={!expand}
|
||||||
class:border-red-200={expand}
|
class:border-red-200={expand}
|
||||||
class:dark:border-red-800={expand}
|
class:dark:border-red-800={expand}
|
||||||
class="
|
class="
|
||||||
|
|
||||||
transition-all
|
|
||||||
transition-delay-1000
|
transition-delay-1000
|
||||||
transition-duration-1000
|
transition-duration-1000
|
||||||
ease-in
|
|
||||||
overflow-y-auto
|
|
||||||
px-1 py-4
|
|
||||||
opacity-50
|
|
||||||
hover:opacity-100
|
|
||||||
relative
|
relative
|
||||||
"
|
overflow-y-auto
|
||||||
>
|
px-1
|
||||||
|
py-4 opacity-50
|
||||||
|
transition-all
|
||||||
|
ease-in
|
||||||
|
hover:opacity-100
|
||||||
|
">
|
||||||
<!-- flex flex-col items-center justify-center max-h-full outline -->
|
<!-- flex flex-col items-center justify-center max-h-full outline -->
|
||||||
<div>
|
<div>
|
||||||
<!-- <span class="fas fa-bug mx-1"></span> -->
|
<!-- <span class="fas fa-bug mx-1"></span> -->
|
||||||
<Bug class="inline-block mx-1" />
|
<Bug class="mx-1 inline-block" />
|
||||||
<span>Debug</span>
|
<span>Debug</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -91,7 +95,8 @@ hover:opacity-100 -->
|
|||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span class="absolute top-0 right-0 flex flex-row gap-1 items-center justify-center">
|
<span
|
||||||
|
class="absolute top-0 right-0 flex flex-row items-center justify-center gap-1">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onclick={() => {
|
onclick={() => {
|
||||||
@@ -104,16 +109,21 @@ hover:opacity-100 -->
|
|||||||
hover:preset-tonal-success
|
hover:preset-tonal-success
|
||||||
transition-all
|
transition-all
|
||||||
"
|
"
|
||||||
title="Turn debug content and styles off and on"
|
title="Turn debug content and styles off and on">
|
||||||
>
|
|
||||||
{#if $ae_loc?.debug_mode}
|
{#if $ae_loc?.debug_mode}
|
||||||
<!-- <span class="fas fa-toggle-on mx-1"></span> -->
|
<!-- <span class="fas fa-toggle-on mx-1"></span> -->
|
||||||
<ToggleRight strokeWidth="2.5" color="green" class="inline-block mx-1" />
|
<ToggleRight
|
||||||
|
strokeWidth="2.5"
|
||||||
|
color="green"
|
||||||
|
class="mx-1 inline-block" />
|
||||||
<span>Debug</span>
|
<span>Debug</span>
|
||||||
<span class="hidden"> Mode On </span>
|
<span class="hidden"> Mode On </span>
|
||||||
{:else}
|
{:else}
|
||||||
<!-- <span class="fas fa-toggle-off mx-1"></span> -->
|
<!-- <span class="fas fa-toggle-off mx-1"></span> -->
|
||||||
<ToggleLeft strokeWidth="1" color="gray" class="inline-block mx-1" />
|
<ToggleLeft
|
||||||
|
strokeWidth="1"
|
||||||
|
color="gray"
|
||||||
|
class="mx-1 inline-block" />
|
||||||
<span>Debug?</span>
|
<span>Debug?</span>
|
||||||
<span class="hidden"> Mode Off </span>
|
<span class="hidden"> Mode Off </span>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -137,10 +147,9 @@ hover:opacity-100 -->
|
|||||||
preset-outlined-surface-400-600 preset-filled-suface-200-800
|
preset-outlined-surface-400-600 preset-filled-suface-200-800
|
||||||
hover:preset-tonal-success
|
hover:preset-tonal-success
|
||||||
transition-all
|
transition-all
|
||||||
"
|
">
|
||||||
>
|
|
||||||
<!-- <span class="fas fa-info-circle mx-1"></span> -->
|
<!-- <span class="fas fa-info-circle mx-1"></span> -->
|
||||||
<Info class="inline-block mx-1" />
|
<Info class="mx-1 inline-block" />
|
||||||
Quick Info
|
Quick Info
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@@ -157,11 +166,10 @@ hover:opacity-100 -->
|
|||||||
hover:preset-tonal-warning
|
hover:preset-tonal-warning
|
||||||
transition-all
|
transition-all
|
||||||
"
|
"
|
||||||
title="Turn debug content and styles off and on"
|
title="Turn debug content and styles off and on">
|
||||||
>
|
|
||||||
<!-- <span class="fas fa-toggle-on mx-1"></span> -->
|
<!-- <span class="fas fa-toggle-on mx-1"></span> -->
|
||||||
<!-- <ToggleRight class="inline-block mx-1" /> -->
|
<!-- <ToggleRight class="inline-block mx-1" /> -->
|
||||||
<CircleX class="inline-block mx-1" />
|
<CircleX class="mx-1 inline-block" />
|
||||||
<span class="hidden"> Close </span>
|
<span class="hidden"> Close </span>
|
||||||
<span>Debug</span>
|
<span>Debug</span>
|
||||||
</button>
|
</button>
|
||||||
@@ -177,18 +185,17 @@ hover:opacity-100 -->
|
|||||||
id="AE-Quick-Debug"
|
id="AE-Quick-Debug"
|
||||||
class="
|
class="
|
||||||
btn btn-icon
|
btn btn-icon
|
||||||
text-xs
|
|
||||||
p-1
|
|
||||||
preset-outlined-surface-100-900
|
preset-outlined-surface-100-900
|
||||||
hover:preset-filled-warning-100-900
|
hover:preset-filled-warning-100-900
|
||||||
|
fixed
|
||||||
|
bottom-8
|
||||||
|
|
||||||
transition-all
|
left-2
|
||||||
fixed bottom-8 left-2
|
p-1 text-xs text-neutral-300
|
||||||
text-neutral-300 hover:text-neutral-800
|
transition-all hover:text-neutral-800
|
||||||
dark:text-neutral-700 dark:hover:text-neutral-200
|
dark:text-neutral-700 dark:hover:text-neutral-200
|
||||||
"
|
"
|
||||||
title="Turn debug content and styles off and on"
|
title="Turn debug content and styles off and on">
|
||||||
>
|
|
||||||
<!-- absolute bottom-2 left-2 -->
|
<!-- absolute bottom-2 left-2 -->
|
||||||
<!-- fixed bottom-0 left-0 -->
|
<!-- fixed bottom-0 left-0 -->
|
||||||
π
|
π
|
||||||
|
|||||||
@@ -1,80 +1,87 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
interface Props {
|
interface Props {
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
additional_kv?: key_val;
|
additional_kv?: key_val;
|
||||||
e_success?: boolean;
|
e_success?: boolean;
|
||||||
e_class?: string;
|
e_class?: string;
|
||||||
e_title?: string;
|
e_title?: string;
|
||||||
e_text?: string;
|
e_text?: string;
|
||||||
e_class_h1?: string;
|
e_class_h1?: string;
|
||||||
e_class_h2?: string;
|
e_class_h2?: string;
|
||||||
e_class_form_hidden?: string;
|
e_class_form_hidden?: string;
|
||||||
e_class_form_showing?: string;
|
e_class_form_showing?: string;
|
||||||
btn_text?: string;
|
btn_text?: string;
|
||||||
btn_title?: string;
|
btn_title?: string;
|
||||||
btn_class?: string;
|
btn_class?: string;
|
||||||
show_btn_class?: string;
|
show_btn_class?: string;
|
||||||
hide_icon?: boolean;
|
hide_icon?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
let {
|
let {
|
||||||
log_lvl = $bindable(0),
|
log_lvl = $bindable(0),
|
||||||
additional_kv = $bindable({}),
|
additional_kv = $bindable({}),
|
||||||
e_success = $bindable(false),
|
e_success = $bindable(false),
|
||||||
e_class = '',
|
e_class = '',
|
||||||
// e_title = 'Technical Help',
|
// e_title = 'Technical Help',
|
||||||
// e_text = 'Request technical help for this application.',
|
// e_text = 'Request technical help for this application.',
|
||||||
e_class_h1 = $bindable(''),
|
e_class_h1 = $bindable(''),
|
||||||
e_class_h2 = $bindable(''),
|
e_class_h2 = $bindable(''),
|
||||||
e_class_form_hidden = $bindable(''),
|
e_class_form_hidden = $bindable(''),
|
||||||
e_class_form_showing = $bindable(''),
|
e_class_form_showing = $bindable(''),
|
||||||
btn_text = 'Technical Help',
|
btn_text = 'Technical Help',
|
||||||
btn_title = 'Technical support help',
|
btn_title = 'Technical support help',
|
||||||
btn_class = '',
|
btn_class = '',
|
||||||
show_btn_class = '',
|
show_btn_class = '',
|
||||||
hide_icon = false
|
hide_icon = false
|
||||||
}: Props = $props();
|
}: Props = $props();
|
||||||
|
|
||||||
// *** Import Svelte specific
|
// *** Import Svelte specific
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
|
|
||||||
// *** Import other supporting libraries
|
// *** Import other supporting libraries
|
||||||
import { BadgeQuestionMark, ChevronDown, ChevronRight, LifeBuoy, RefreshCw, SquareX } from '@lucide/svelte';
|
import {
|
||||||
// *** Import Aether specific variables and functions
|
BadgeQuestionMark,
|
||||||
import {
|
ChevronDown,
|
||||||
ae_snip,
|
ChevronRight,
|
||||||
ae_loc,
|
LifeBuoy,
|
||||||
ae_sess,
|
RefreshCw,
|
||||||
ae_api,
|
SquareX
|
||||||
ae_trig,
|
} from '@lucide/svelte';
|
||||||
slct,
|
// *** Import Aether specific variables and functions
|
||||||
slct_trigger,
|
import {
|
||||||
type key_val
|
ae_snip,
|
||||||
} from '$lib/stores/ae_stores';
|
ae_loc,
|
||||||
import { api } from '$lib/api/api';
|
ae_sess,
|
||||||
|
ae_api,
|
||||||
|
ae_trig,
|
||||||
|
slct,
|
||||||
|
slct_trigger,
|
||||||
|
type key_val
|
||||||
|
} from '$lib/stores/ae_stores';
|
||||||
|
import { api } from '$lib/api/api';
|
||||||
|
|
||||||
|
if (log_lvl) {
|
||||||
|
console.log(`Help - technical support component loaded`);
|
||||||
|
}
|
||||||
|
|
||||||
|
let help_tech_text: string = $state('');
|
||||||
|
let hide_additional_info: boolean = $state(true);
|
||||||
|
|
||||||
|
function prevent_default<T extends Event>(fn: (event: T) => void) {
|
||||||
|
return function (event: T) {
|
||||||
|
event.preventDefault();
|
||||||
|
fn(event);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function send_help_tech_email() {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`Help - technical support component loaded`);
|
console.log(`*** send_help_tech_email() ***`);
|
||||||
}
|
}
|
||||||
|
|
||||||
let help_tech_text: string = $state('');
|
let subject = `Technical Notification - ${$ae_loc.name}`;
|
||||||
let hide_additional_info: boolean = $state(true);
|
|
||||||
|
|
||||||
function prevent_default<T extends Event>(fn: (event: T) => void) {
|
let body_html = `
|
||||||
return function (event: T) {
|
|
||||||
event.preventDefault();
|
|
||||||
fn(event);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function send_help_tech_email() {
|
|
||||||
if (log_lvl) {
|
|
||||||
console.log(`*** send_help_tech_email() ***`);
|
|
||||||
}
|
|
||||||
|
|
||||||
let subject = `Technical Notification - ${$ae_loc.name}`;
|
|
||||||
|
|
||||||
let body_html = `
|
|
||||||
<div>
|
<div>
|
||||||
Technical Notification,\n\n
|
Technical Notification,\n\n
|
||||||
<ul>
|
<ul>
|
||||||
@@ -102,25 +109,24 @@
|
|||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
api.send_email({
|
api.send_email({
|
||||||
api_cfg: $ae_api,
|
api_cfg: $ae_api,
|
||||||
from_email:
|
from_email:
|
||||||
$ae_loc.site_cfg_json?.noreply_email ??
|
$ae_loc.site_cfg_json?.noreply_email ?? 'noreply+tech@oneskyit.com',
|
||||||
'noreply+tech@oneskyit.com',
|
from_name: $ae_loc.site_cfg_json?.noreply_name ?? 'IT NoReply',
|
||||||
from_name: $ae_loc.site_cfg_json?.noreply_name ?? 'IT NoReply',
|
// to_email: $ae_loc.site_cfg_json?.admin_email ?? 'admin+tech@oneskyit.com', // 'scott+idaabb@oneskyit.com',
|
||||||
// to_email: $ae_loc.site_cfg_json?.admin_email ?? 'admin+tech@oneskyit.com', // 'scott+idaabb@oneskyit.com',
|
to_email: 'it+tech@oneskyit.com',
|
||||||
to_email: 'it+tech@oneskyit.com',
|
// to_email: $idaa_slct.post_obj.email,
|
||||||
// to_email: $idaa_slct.post_obj.email,
|
// to_email: 'scott+idaabb@oneskyit.com',
|
||||||
// to_email: 'scott+idaabb@oneskyit.com',
|
// to_name: $ae_loc.site_cfg_json?.admin_name ?? 'IT Tech',
|
||||||
// to_name: $ae_loc.site_cfg_json?.admin_name ?? 'IT Tech',
|
to_name: 'IT Tech',
|
||||||
to_name: 'IT Tech',
|
// to_name: $idaa_slct.post_obj.full_name ?? 'IDAA BB Poster',
|
||||||
// to_name: $idaa_slct.post_obj.full_name ?? 'IDAA BB Poster',
|
subject: subject,
|
||||||
subject: subject,
|
body_html: body_html
|
||||||
body_html: body_html
|
});
|
||||||
});
|
|
||||||
|
|
||||||
help_tech_text = ''; // Clear the text area after sending
|
help_tech_text = ''; // Clear the text area after sending
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- class:bg-radial-[at_55%_50%]={$ae_sess.show_help_tech}
|
<!-- class:bg-radial-[at_55%_50%]={$ae_sess.show_help_tech}
|
||||||
@@ -131,8 +137,8 @@ class:to-90%={$ae_sess.show_help_tech} -->
|
|||||||
class="
|
class="
|
||||||
flex flex-row
|
flex flex-row
|
||||||
items-center justify-center
|
items-center justify-center
|
||||||
rounded-lg shadow-2xl
|
rounded-lg border
|
||||||
border border-transparent
|
border-transparent shadow-2xl
|
||||||
transition-all
|
transition-all
|
||||||
{e_class}
|
{e_class}
|
||||||
{!$ae_sess.show_help_tech ? e_class_form_hidden : e_class_form_showing}
|
{!$ae_sess.show_help_tech ? e_class_form_hidden : e_class_form_showing}
|
||||||
@@ -148,48 +154,42 @@ class:to-90%={$ae_sess.show_help_tech} -->
|
|||||||
class:hover:shadow-blue-200={$ae_sess.show_help_tech}
|
class:hover:shadow-blue-200={$ae_sess.show_help_tech}
|
||||||
class:hover:dark:shadow-blue-800={$ae_sess.show_help_tech}
|
class:hover:dark:shadow-blue-800={$ae_sess.show_help_tech}
|
||||||
class:bg-blue-100={$ae_sess.show_help_tech}
|
class:bg-blue-100={$ae_sess.show_help_tech}
|
||||||
class:dark:bg-blue-900={$ae_sess.show_help_tech}
|
class:dark:bg-blue-900={$ae_sess.show_help_tech}>
|
||||||
>
|
|
||||||
{#if $ae_sess.show_help_tech}
|
{#if $ae_sess.show_help_tech}
|
||||||
<div
|
<div
|
||||||
class="
|
class="
|
||||||
w-xl
|
flex
|
||||||
flex flex-col gap-1
|
w-xl flex-col items-center
|
||||||
items-center justify-center
|
justify-center gap-1
|
||||||
|
rounded-xl
|
||||||
|
border border-gray-500/20 bg-blue-200
|
||||||
p-2
|
p-2
|
||||||
border rounded-xl border-gray-500/20
|
|
||||||
bg-blue-200
|
|
||||||
dark:bg-blue-800
|
|
||||||
transition-all
|
transition-all
|
||||||
"
|
dark:bg-blue-800
|
||||||
>
|
">
|
||||||
<div
|
<div
|
||||||
class="
|
class="
|
||||||
d-flex align-items-center justify-content-between
|
d-flex align-items-center justify-content-between
|
||||||
flex flex-row gap-1 items-center justify-between
|
flex w-full flex-row items-center justify-between
|
||||||
w-full
|
gap-1
|
||||||
"
|
">
|
||||||
>
|
|
||||||
<h1
|
<h1
|
||||||
class="
|
class="
|
||||||
h1
|
h1
|
||||||
text-base font-semibold text-gray-800 dark:text-gray-200
|
w-fit text-base font-semibold text-gray-800
|
||||||
w-fit
|
dark:text-gray-200
|
||||||
{e_class_h1}
|
{e_class_h1}
|
||||||
"
|
">
|
||||||
>
|
|
||||||
{#if e_success}
|
{#if e_success}
|
||||||
<span
|
<span
|
||||||
class="text-lg text-green-800 dark:text-green-200 font-semibold"
|
class="text-lg font-semibold text-green-800 dark:text-green-200">
|
||||||
>
|
<BadgeQuestionMark class="mr-2 inline-block" />
|
||||||
<BadgeQuestionMark class="inline-block mr-2" />
|
|
||||||
Help Requested
|
Help Requested
|
||||||
</span>
|
</span>
|
||||||
{:else}
|
{:else}
|
||||||
<span
|
<span
|
||||||
class="text-lg text-gray-800 dark:text-gray-200 font-semibold"
|
class="text-lg font-semibold text-gray-800 dark:text-gray-200">
|
||||||
>
|
<BadgeQuestionMark class="mr-2 inline-block" />
|
||||||
<BadgeQuestionMark class="inline-block mr-2" />
|
|
||||||
<!-- Request Technical Help -->
|
<!-- Request Technical Help -->
|
||||||
Notify Technical Support
|
Notify Technical Support
|
||||||
</span>
|
</span>
|
||||||
@@ -211,8 +211,7 @@ class:to-90%={$ae_sess.show_help_tech} -->
|
|||||||
transition-all
|
transition-all
|
||||||
{btn_class}
|
{btn_class}
|
||||||
"
|
"
|
||||||
title="Close Help Request Form"
|
title="Close Help Request Form">
|
||||||
>
|
|
||||||
<!-- <span class="fas fa-times"></span> -->
|
<!-- <span class="fas fa-times"></span> -->
|
||||||
<SquareX size="1em" />
|
<SquareX size="1em" />
|
||||||
<span class="sr-only">Close</span>
|
<span class="sr-only">Close</span>
|
||||||
@@ -222,9 +221,9 @@ class:to-90%={$ae_sess.show_help_tech} -->
|
|||||||
<form
|
<form
|
||||||
class="
|
class="
|
||||||
m-1
|
m-1
|
||||||
flex flex-col gap-1
|
flex w-md max-w-lg
|
||||||
items-center justify-center
|
flex-col items-center
|
||||||
w-md max-w-lg
|
justify-center gap-1
|
||||||
"
|
"
|
||||||
onsubmit={prevent_default(() => {
|
onsubmit={prevent_default(() => {
|
||||||
// Do stuff...
|
// Do stuff...
|
||||||
@@ -234,40 +233,37 @@ class:to-90%={$ae_sess.show_help_tech} -->
|
|||||||
$ae_sess.show_help_tech = false;
|
$ae_sess.show_help_tech = false;
|
||||||
|
|
||||||
alert('Notification sent to the IT team.');
|
alert('Notification sent to the IT team.');
|
||||||
})}
|
})}>
|
||||||
>
|
|
||||||
<textarea
|
<textarea
|
||||||
class="
|
class="
|
||||||
form-control
|
form-control
|
||||||
w-full max-w-lg h-24 p-2
|
h-24 w-full max-w-lg rounded
|
||||||
border border-gray-300 rounded
|
border border-gray-300 bg-white
|
||||||
text-gray-950 dark:text-gray-50
|
p-2 text-gray-950
|
||||||
bg-white dark:bg-gray-500
|
dark:bg-gray-500 dark:text-gray-50
|
||||||
hover:dark:bg-gray-50
|
hover:dark:bg-gray-50
|
||||||
hover:dark:text-gray-950
|
hover:dark:text-gray-950
|
||||||
"
|
"
|
||||||
placeholder="Send with or without a description...."
|
placeholder="Send with or without a description...."
|
||||||
bind:value={help_tech_text}
|
bind:value={help_tech_text}></textarea>
|
||||||
></textarea>
|
|
||||||
|
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
class="
|
class="
|
||||||
btn btn-lg
|
btn btn-lg
|
||||||
m-1
|
|
||||||
preset-tonal-warning
|
preset-tonal-warning
|
||||||
preset-outlined-warning-100-900
|
preset-outlined-warning-100-900
|
||||||
hover:preset-filled-warning-200-800
|
hover:preset-filled-warning-200-800
|
||||||
|
m-1
|
||||||
|
|
||||||
|
|
||||||
transition-all
|
transition-all
|
||||||
{btn_class}
|
{btn_class}
|
||||||
"
|
"
|
||||||
title={btn_title}
|
title={btn_title}>
|
||||||
>
|
|
||||||
{#if !hide_icon}
|
{#if !hide_icon}
|
||||||
<!-- <BadgeQuestionMark class="inline-block mr-2" /> -->
|
<!-- <BadgeQuestionMark class="inline-block mr-2" /> -->
|
||||||
<LifeBuoy class="inline-block m-1" />
|
<LifeBuoy class="m-1 inline-block" />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if !help_tech_text}
|
{#if !help_tech_text}
|
||||||
@@ -280,9 +276,8 @@ class:to-90%={$ae_sess.show_help_tech} -->
|
|||||||
|
|
||||||
<div
|
<div
|
||||||
class="
|
class="
|
||||||
text-sm text-gray-700 dark:text-gray-300 text-center italic
|
text-center text-sm text-gray-700 italic dark:text-gray-300
|
||||||
"
|
">
|
||||||
>
|
|
||||||
This is intended for technical issues only. Please contact your
|
This is intended for technical issues only. Please contact your
|
||||||
organization's staff if you have a question about your
|
organization's staff if you have a question about your
|
||||||
membership, recorded content, meetings, or posts.
|
membership, recorded content, meetings, or posts.
|
||||||
@@ -290,29 +285,25 @@ class:to-90%={$ae_sess.show_help_tech} -->
|
|||||||
|
|
||||||
<div
|
<div
|
||||||
class="
|
class="
|
||||||
border border-gray-300 rounded p-2
|
w-full max-w-2xl overflow-scroll rounded
|
||||||
w-full
|
border
|
||||||
max-w-2xl
|
border-gray-300
|
||||||
overflow-scroll
|
p-2
|
||||||
"
|
">
|
||||||
>
|
|
||||||
<div
|
<div
|
||||||
class="
|
class="
|
||||||
d-flex align-items-center justify-content-between
|
d-flex align-items-center justify-content-between
|
||||||
flex flex-row gap-1 items-center justify-between
|
flex w-full flex-row items-center justify-between
|
||||||
w-full
|
gap-1
|
||||||
"
|
">
|
||||||
>
|
|
||||||
<h2
|
<h2
|
||||||
class="
|
class="
|
||||||
h2
|
h2
|
||||||
text-base font-semibold text-gray-800 dark:text-gray-200
|
text-base font-semibold text-gray-800 dark:text-gray-200
|
||||||
{e_class_h2}
|
{e_class_h2}
|
||||||
"
|
">
|
||||||
>
|
|
||||||
<span
|
<span
|
||||||
class="text-base font-semibold text-gray-800 dark:text-gray-200"
|
class="text-base font-semibold text-gray-800 dark:text-gray-200">
|
||||||
>
|
|
||||||
Additional Information Included
|
Additional Information Included
|
||||||
</span>
|
</span>
|
||||||
</h2>
|
</h2>
|
||||||
@@ -325,8 +316,7 @@ class:to-90%={$ae_sess.show_help_tech} -->
|
|||||||
"
|
"
|
||||||
onclick={() =>
|
onclick={() =>
|
||||||
(hide_additional_info = !hide_additional_info)}
|
(hide_additional_info = !hide_additional_info)}
|
||||||
title="Toggle additional information"
|
title="Toggle additional information">
|
||||||
>
|
|
||||||
<span>
|
<span>
|
||||||
{#if hide_additional_info}
|
{#if hide_additional_info}
|
||||||
<!-- <span class="fas fa-caret-right"></span> -->
|
<!-- <span class="fas fa-caret-right"></span> -->
|
||||||
@@ -341,89 +331,75 @@ class:to-90%={$ae_sess.show_help_tech} -->
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<ul
|
<ul
|
||||||
class="list-disc list-inside text-sm text-gray-800 dark:text-gray-200"
|
class="list-inside list-disc text-sm text-gray-800 dark:text-gray-200"
|
||||||
class:hidden={hide_additional_info}
|
class:hidden={hide_additional_info}>
|
||||||
>
|
|
||||||
<li>
|
<li>
|
||||||
<span class="text-sm text-gray-500 dark:text-gray-400"
|
<span class="text-sm text-gray-500 dark:text-gray-400"
|
||||||
>Datetime =</span
|
>Datetime =</span>
|
||||||
>
|
|
||||||
{new Date().toISOString()}
|
{new Date().toISOString()}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span class="text-sm text-gray-500 dark:text-gray-400"
|
<span class="text-sm text-gray-500 dark:text-gray-400"
|
||||||
>URL =</span
|
>URL =</span>
|
||||||
>
|
|
||||||
{window.location.href}
|
{window.location.href}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span class="text-sm text-gray-500 dark:text-gray-400"
|
<span class="text-sm text-gray-500 dark:text-gray-400"
|
||||||
>Browser =</span
|
>Browser =</span>
|
||||||
>
|
|
||||||
{navigator.userAgent}
|
{navigator.userAgent}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span class="text-sm text-gray-500 dark:text-gray-400"
|
<span class="text-sm text-gray-500 dark:text-gray-400"
|
||||||
>Viewport Size =</span
|
>Viewport Size =</span>
|
||||||
>
|
|
||||||
{window.innerWidth} x {window.innerHeight}
|
{window.innerWidth} x {window.innerHeight}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span class="text-sm text-gray-500 dark:text-gray-400"
|
<span class="text-sm text-gray-500 dark:text-gray-400"
|
||||||
>Screen Resolution =</span
|
>Screen Resolution =</span>
|
||||||
>
|
|
||||||
{window.screen.width} x {window.screen.height}
|
{window.screen.width} x {window.screen.height}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span class="text-sm text-gray-500 dark:text-gray-400"
|
<span class="text-sm text-gray-500 dark:text-gray-400"
|
||||||
>Dark mode =</span
|
>Dark mode =</span>
|
||||||
>
|
|
||||||
{window?.matchMedia?.('(prefers-color-scheme:dark)')
|
{window?.matchMedia?.('(prefers-color-scheme:dark)')
|
||||||
?.matches ?? false}
|
?.matches ?? false}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span class="text-sm text-gray-500 dark:text-gray-400"
|
<span class="text-sm text-gray-500 dark:text-gray-400"
|
||||||
>In iframe =</span
|
>In iframe =</span>
|
||||||
>
|
|
||||||
{$ae_loc?.iframe}
|
{$ae_loc?.iframe}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span class="text-sm text-gray-500 dark:text-gray-400"
|
<span class="text-sm text-gray-500 dark:text-gray-400"
|
||||||
>Theme Mode =</span
|
>Theme Mode =</span>
|
||||||
>
|
|
||||||
{$ae_loc?.theme_mode}
|
{$ae_loc?.theme_mode}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span class="text-sm text-gray-500 dark:text-gray-400"
|
<span class="text-sm text-gray-500 dark:text-gray-400"
|
||||||
>Theme Name =</span
|
>Theme Name =</span>
|
||||||
>
|
|
||||||
{$ae_loc?.theme_name}
|
{$ae_loc?.theme_name}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span class="text-sm text-gray-500 dark:text-gray-400"
|
<span class="text-sm text-gray-500 dark:text-gray-400"
|
||||||
>Account ID =</span
|
>Account ID =</span>
|
||||||
>
|
|
||||||
{$slct.account_id}
|
{$slct.account_id}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span class="text-sm text-gray-500 dark:text-gray-400"
|
<span class="text-sm text-gray-500 dark:text-gray-400"
|
||||||
>Access Type =</span
|
>Access Type =</span>
|
||||||
>
|
|
||||||
{$ae_loc?.access_type}
|
{$ae_loc?.access_type}
|
||||||
</li>
|
</li>
|
||||||
{#if $ae_loc?.person_id}
|
{#if $ae_loc?.person_id}
|
||||||
<li>
|
<li>
|
||||||
<span
|
<span
|
||||||
class="text-sm text-gray-500 dark:text-gray-400"
|
class="text-sm text-gray-500 dark:text-gray-400"
|
||||||
>person_id =</span
|
>person_id =</span>
|
||||||
>
|
|
||||||
{$ae_loc?.person_id}
|
{$ae_loc?.person_id}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span
|
<span
|
||||||
class="text-sm text-gray-500 dark:text-gray-400"
|
class="text-sm text-gray-500 dark:text-gray-400"
|
||||||
>full_name =</span
|
>full_name =</span>
|
||||||
>
|
|
||||||
{$ae_loc?.full_name}
|
{$ae_loc?.full_name}
|
||||||
</li>
|
</li>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -431,29 +407,25 @@ class:to-90%={$ae_sess.show_help_tech} -->
|
|||||||
<li>
|
<li>
|
||||||
<span
|
<span
|
||||||
class="text-sm text-gray-500 dark:text-gray-400"
|
class="text-sm text-gray-500 dark:text-gray-400"
|
||||||
>user_id =</span
|
>user_id =</span>
|
||||||
>
|
|
||||||
{$ae_loc?.user_id}
|
{$ae_loc?.user_id}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span
|
<span
|
||||||
class="text-sm text-gray-500 dark:text-gray-400"
|
class="text-sm text-gray-500 dark:text-gray-400"
|
||||||
>username =</span
|
>username =</span>
|
||||||
>
|
|
||||||
{$ae_loc?.username}
|
{$ae_loc?.username}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span
|
<span
|
||||||
class="text-sm text-gray-500 dark:text-gray-400"
|
class="text-sm text-gray-500 dark:text-gray-400"
|
||||||
>email =</span
|
>email =</span>
|
||||||
>
|
|
||||||
{$ae_loc?.email}
|
{$ae_loc?.email}
|
||||||
</li>
|
</li>
|
||||||
{/if}
|
{/if}
|
||||||
<li>
|
<li>
|
||||||
<span class="text-sm text-gray-500 dark:text-gray-400"
|
<span class="text-sm text-gray-500 dark:text-gray-400"
|
||||||
>API Base URL =</span
|
>API Base URL =</span>
|
||||||
>
|
|
||||||
{$ae_api.base_url}
|
{$ae_api.base_url}
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -461,13 +433,12 @@ class:to-90%={$ae_sess.show_help_tech} -->
|
|||||||
<h2 class="text-base font-semibold text-gray-800">
|
<h2 class="text-base font-semibold text-gray-800">
|
||||||
Component Info:
|
Component Info:
|
||||||
</h2>
|
</h2>
|
||||||
<ul class="list-disc list-inside text-gray-800 text-sm">
|
<ul class="list-inside list-disc text-sm text-gray-800">
|
||||||
{#each Object.entries(additional_kv) as [key, value] (key)}
|
{#each Object.entries(additional_kv) as [key, value] (key)}
|
||||||
<li>
|
<li>
|
||||||
<span
|
<span
|
||||||
class="text-sm text-gray-500 dark:text-gray-400"
|
class="text-sm text-gray-500 dark:text-gray-400"
|
||||||
>{key} =</span
|
>{key} =</span>
|
||||||
>
|
|
||||||
{value ?? '-- not set --'}
|
{value ?? '-- not set --'}
|
||||||
</li>
|
</li>
|
||||||
{/each}
|
{/each}
|
||||||
@@ -475,8 +446,7 @@ class:to-90%={$ae_sess.show_help_tech} -->
|
|||||||
{/if}
|
{/if}
|
||||||
</ul>
|
</ul>
|
||||||
<div
|
<div
|
||||||
class="text-sm text-gray-700 dark:text-gray-300 text-center italic"
|
class="text-center text-sm text-gray-700 italic dark:text-gray-300">
|
||||||
>
|
|
||||||
This information will be included in the help request to
|
This information will be included in the help request to
|
||||||
assist technical support in diagnosing the issue.
|
assist technical support in diagnosing the issue.
|
||||||
</div>
|
</div>
|
||||||
@@ -484,11 +454,10 @@ class:to-90%={$ae_sess.show_help_tech} -->
|
|||||||
|
|
||||||
<div
|
<div
|
||||||
class="
|
class="
|
||||||
flex flex-row gap-2 items-center justify-around
|
mt-2 flex w-full flex-row items-center
|
||||||
w-full
|
justify-around
|
||||||
mt-2
|
gap-2
|
||||||
"
|
">
|
||||||
>
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onclick={() => {
|
onclick={() => {
|
||||||
@@ -562,8 +531,7 @@ class:to-90%={$ae_sess.show_help_tech} -->
|
|||||||
transition-all
|
transition-all
|
||||||
{btn_class}
|
{btn_class}
|
||||||
"
|
"
|
||||||
title="Clear App Data & Settings: Clear IndexedDB and reload. If in edit mode localStorage and sessionStorage will also be cleared."
|
title="Clear App Data & Settings: Clear IndexedDB and reload. If in edit mode localStorage and sessionStorage will also be cleared.">
|
||||||
>
|
|
||||||
<!-- <span class="fas fa-eraser mx-1"></span> -->
|
<!-- <span class="fas fa-eraser mx-1"></span> -->
|
||||||
<!-- <span class="fas fa-sync mx-1"></span> -->
|
<!-- <span class="fas fa-sync mx-1"></span> -->
|
||||||
<RefreshCw size="1em" class="inline-block" />
|
<RefreshCw size="1em" class="inline-block" />
|
||||||
@@ -582,8 +550,7 @@ class:to-90%={$ae_sess.show_help_tech} -->
|
|||||||
transition-all
|
transition-all
|
||||||
{btn_class}
|
{btn_class}
|
||||||
"
|
"
|
||||||
title="Close Help Request Form"
|
title="Close Help Request Form">
|
||||||
>
|
|
||||||
<!-- <span class="fas fa-times"></span> -->
|
<!-- <span class="fas fa-times"></span> -->
|
||||||
<SquareX size="1em" class="inline-block" />
|
<SquareX size="1em" class="inline-block" />
|
||||||
<span class="">Cancel</span>
|
<span class="">Cancel</span>
|
||||||
@@ -603,10 +570,9 @@ class:to-90%={$ae_sess.show_help_tech} -->
|
|||||||
{btn_class}
|
{btn_class}
|
||||||
{show_btn_class}
|
{show_btn_class}
|
||||||
"
|
"
|
||||||
title={btn_title}
|
title={btn_title}>
|
||||||
>
|
|
||||||
{#if !hide_icon}
|
{#if !hide_icon}
|
||||||
<BadgeQuestionMark class="inline-block m-0.5" />
|
<BadgeQuestionMark class="m-0.5 inline-block" />
|
||||||
{/if}
|
{/if}
|
||||||
<span class="hidden">
|
<span class="hidden">
|
||||||
{btn_text}
|
{btn_text}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,56 +1,63 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
// *** Import Svelte specific
|
// *** Import Svelte specific
|
||||||
// import { tick } from 'svelte';
|
// import { tick } from 'svelte';
|
||||||
// import { goto, invalidateAll } from '$app/navigation';
|
// import { goto, invalidateAll } from '$app/navigation';
|
||||||
|
|
||||||
// *** Import other supporting libraries
|
// *** Import other supporting libraries
|
||||||
import {
|
import {
|
||||||
// ArrowBigRight,
|
// ArrowBigRight,
|
||||||
// Bug,
|
// Bug,
|
||||||
CircleX,
|
CircleX,
|
||||||
// Eye, EyeOff,
|
// Eye, EyeOff,
|
||||||
// Key,
|
// Key,
|
||||||
// LogIn, LogOut, LockKeyhole,
|
// LogIn, LogOut, LockKeyhole,
|
||||||
// Mail, MailCheck,
|
// Mail, MailCheck,
|
||||||
Menu,
|
Menu,
|
||||||
// RefreshCw, RefreshCcwDot,
|
// RefreshCw, RefreshCcwDot,
|
||||||
ShieldEllipsis,
|
ShieldEllipsis,
|
||||||
ShieldMinus,
|
ShieldMinus,
|
||||||
ShieldPlus,
|
ShieldPlus,
|
||||||
ShieldUser,
|
ShieldUser,
|
||||||
ToggleLeft, ToggleRight,
|
ToggleLeft,
|
||||||
User,
|
ToggleRight,
|
||||||
UserCheck,
|
User,
|
||||||
UserCog,
|
UserCheck,
|
||||||
Wand2,
|
UserCog,
|
||||||
X
|
Wand2,
|
||||||
} from '@lucide/svelte';
|
X
|
||||||
|
} from '@lucide/svelte';
|
||||||
|
|
||||||
// *** Import Aether specific variables and functions
|
// *** Import Aether specific variables and functions
|
||||||
// import { ae_util } from '$lib/ae_utils/ae_utils';
|
// import { ae_util } from '$lib/ae_utils/ae_utils';
|
||||||
import { ae_loc, ae_sess, ae_api, slct, slct_trigger } from '$lib/stores/ae_stores';
|
import {
|
||||||
|
ae_loc,
|
||||||
|
ae_sess,
|
||||||
|
ae_api,
|
||||||
|
slct,
|
||||||
|
slct_trigger
|
||||||
|
} from '$lib/stores/ae_stores';
|
||||||
|
|
||||||
import Element_access_type from '$lib/app_components/e_app_access_type.svelte';
|
import Element_access_type from '$lib/app_components/e_app_access_type.svelte';
|
||||||
import Element_app_cfg from '$lib/app_components/e_app_cfg.svelte';
|
import Element_app_cfg from '$lib/app_components/e_app_cfg.svelte';
|
||||||
import Element_sign_in_out from '$lib/app_components/e_app_sign_in_out.svelte';
|
import Element_sign_in_out from '$lib/app_components/e_app_sign_in_out.svelte';
|
||||||
import Element_theme from '$lib/app_components/e_app_theme.svelte';
|
import Element_theme from '$lib/app_components/e_app_theme.svelte';
|
||||||
|
|
||||||
// *** Setup Svelte properties
|
// *** Setup Svelte properties
|
||||||
interface Props {
|
interface Props {
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
data: any;
|
data: any;
|
||||||
hide?: null | boolean;
|
hide?: null | boolean;
|
||||||
expand?: boolean;
|
expand?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
let {
|
let {
|
||||||
log_lvl = $bindable(0),
|
log_lvl = $bindable(0),
|
||||||
data = null,
|
data = null,
|
||||||
hide = $bindable(false),
|
hide = $bindable(false),
|
||||||
expand = $bindable(false)
|
expand = $bindable(false)
|
||||||
}: Props = $props();
|
}: Props = $props();
|
||||||
|
|
||||||
let trigger_clear_access: null | boolean = $state(null);
|
let trigger_clear_access: null | boolean = $state(null);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- App System Menu -->
|
<!-- App System Menu -->
|
||||||
@@ -93,38 +100,37 @@ max-w-max -->
|
|||||||
ae_app__sys_menu
|
ae_app__sys_menu
|
||||||
|
|
||||||
hidden-print
|
hidden-print
|
||||||
|
md:text-md
|
||||||
|
lg:text-md xl:text-md absolute
|
||||||
|
|
||||||
|
right-0
|
||||||
|
bottom-6
|
||||||
|
|
||||||
z-50
|
z-50
|
||||||
absolute bottom-6 right-0
|
flex
|
||||||
|
|
||||||
opacity-90
|
w-min max-w-md flex-col-reverse
|
||||||
hover:opacity-100
|
|
||||||
|
|
||||||
w-min
|
|
||||||
max-w-md
|
|
||||||
|
|
||||||
flex flex-col-reverse gap-1
|
|
||||||
items-end justify-center
|
items-end justify-center
|
||||||
|
|
||||||
text-sm sm:text-sm md:text-md lg:text-md xl:text-md 2xl:text-lg
|
gap-1 rounded-lg border-2 border-blue-300/20 bg-blue-200/90 text-sm
|
||||||
|
|
||||||
bg-blue-200/90
|
opacity-90
|
||||||
|
|
||||||
border-2 rounded-lg
|
transition-all delay-500
|
||||||
border-blue-300/20 dark:border-blue-700/20
|
duration-500 ease-in-out
|
||||||
hover:border-blue-500/20 hover:dark:border-blue-500/20
|
hover:border-blue-500/20 hover:opacity-100
|
||||||
|
|
||||||
transition-all
|
hover:delay-200
|
||||||
delay-500 hover:delay-200
|
hover:duration-200 sm:text-sm
|
||||||
duration-500 hover:duration-200
|
2xl:text-lg dark:border-blue-700/20
|
||||||
ease-in-out
|
hover:dark:border-blue-500/20
|
||||||
"
|
"
|
||||||
class:top-0={expand && (1 as any) == 3}
|
class:top-0={expand && (1 as any) == 3}
|
||||||
class:opacity-100={expand}
|
class:opacity-100={expand}
|
||||||
class:w-full={expand}
|
class:w-full={expand}
|
||||||
class:hidden={hide}
|
class:hidden={hide}
|
||||||
class:border-transparent={!expand}
|
class:border-transparent={!expand}
|
||||||
class:bg-transparent={!expand}
|
class:bg-transparent={!expand}>
|
||||||
>
|
|
||||||
<!-- class:hidden={!expand} -->
|
<!-- class:hidden={!expand} -->
|
||||||
<!-- class:preset-filled-warning-100-900={expand} -->
|
<!-- class:preset-filled-warning-100-900={expand} -->
|
||||||
<div
|
<div
|
||||||
@@ -134,38 +140,40 @@ max-w-max -->
|
|||||||
class:dark:bg-blue-500={expand}
|
class:dark:bg-blue-500={expand}
|
||||||
class="
|
class="
|
||||||
hidden-print
|
hidden-print
|
||||||
flex flex-col items-end justify-end
|
light:bg-blue-200/10 relative flex w-full
|
||||||
|
flex-col
|
||||||
|
|
||||||
|
items-end
|
||||||
|
justify-end
|
||||||
|
|
||||||
gap-1
|
gap-1
|
||||||
|
|
||||||
overflow-y-auto
|
overflow-y-auto
|
||||||
p-1
|
p-1
|
||||||
|
|
||||||
w-full
|
|
||||||
|
|
||||||
light:bg-blue-200/10
|
|
||||||
dark:bg-blue-800/10
|
|
||||||
hover:opacity-100
|
|
||||||
|
|
||||||
relative
|
|
||||||
|
|
||||||
transition-all
|
transition-all
|
||||||
delay-1000 hover:delay-500
|
|
||||||
duration-200 hover:duration-200
|
delay-1000
|
||||||
ease-in-out
|
|
||||||
|
duration-200
|
||||||
|
ease-in-out hover:opacity-100
|
||||||
|
hover:delay-500 hover:duration-200
|
||||||
|
dark:bg-blue-800/10
|
||||||
"
|
"
|
||||||
title="
|
title="
|
||||||
ID: {$ae_loc?.person_id ?? '-- not set --'} / {$ae_loc?.user_id ?? '-- not set --'}
|
ID: {$ae_loc?.person_id ?? '-- not set --'} / {$ae_loc?.user_id ??
|
||||||
|
'-- not set --'}
|
||||||
Name: {$ae_loc?.person?.full_name ?? '-- not set --'}
|
Name: {$ae_loc?.person?.full_name ?? '-- not set --'}
|
||||||
Username: {$ae_loc?.user?.username ?? '-- not set --'}
|
Username: {$ae_loc?.user?.username ?? '-- not set --'}
|
||||||
Email: {$ae_loc?.user?.email ?? '-- not set --'}
|
Email: {$ae_loc?.user?.email ?? '-- not set --'}
|
||||||
Access Type: {$ae_loc?.access_type ?? '-- not set --'}
|
Access Type: {$ae_loc?.access_type ?? '-- not set --'}
|
||||||
"
|
">
|
||||||
>
|
|
||||||
{#if $ae_loc?.person_id}
|
{#if $ae_loc?.person_id}
|
||||||
<div class="flex flex-row gap-1 items-center justify-end transition-all w-full group">
|
<div
|
||||||
|
class="group flex w-full flex-row items-center justify-end gap-1 transition-all">
|
||||||
<User size="1em" class="mx-1 inline-block text-gray-500" />
|
<User size="1em" class="mx-1 inline-block text-gray-500" />
|
||||||
<span class:hidden={!expand} class="group-hover:inline-block">
|
<span class:hidden={!expand} class="group-hover:inline-block">
|
||||||
{$ae_loc?.person?.informal_name ?? $ae_loc?.person?.given_name}
|
{$ae_loc?.person?.informal_name ??
|
||||||
|
$ae_loc?.person?.given_name}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -174,54 +182,60 @@ max-w-max -->
|
|||||||
<!-- This is currently not set to show if not expanded. Saving space. -->
|
<!-- This is currently not set to show if not expanded. Saving space. -->
|
||||||
<div
|
<div
|
||||||
class:hidden={!expand}
|
class:hidden={!expand}
|
||||||
class="flex flex-row gap-1 items-center justify-end transition-all w-full group"
|
class="group flex w-full flex-row items-center justify-end gap-1 transition-all">
|
||||||
>
|
<ShieldUser
|
||||||
<ShieldUser size="1em" class="mx-1 inline-block text-gray-500" />
|
size="1em"
|
||||||
|
class="mx-1 inline-block text-gray-500" />
|
||||||
<span class:hidden={!expand} class="group-hover:inline-block">
|
<span class:hidden={!expand} class="group-hover:inline-block">
|
||||||
{$ae_loc?.user?.username ?? '-- not set --'}
|
{$ae_loc?.user?.username ?? '-- not set --'}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div class="flex flex-row gap-1 items-center justify-end transition-all w-full group">
|
<div
|
||||||
|
class="group flex w-full flex-row items-center justify-end gap-1 transition-all">
|
||||||
{#if $ae_loc.access_type && $ae_loc.access_type != 'anonymous'}
|
{#if $ae_loc.access_type && $ae_loc.access_type != 'anonymous'}
|
||||||
<span
|
<span
|
||||||
class="flex flex-row-reverse gap-1 group text-base"
|
class="group flex flex-row-reverse gap-1 text-base"
|
||||||
title={`Current access type/level: ${$ae_loc.access_type}`}
|
title={`Current access type/level: ${$ae_loc.access_type}`}>
|
||||||
>
|
|
||||||
<!-- <span class="fas fa-unlock mx-1"></span> -->
|
<!-- <span class="fas fa-unlock mx-1"></span> -->
|
||||||
<!-- <ShieldPlus class="inline-block" /> -->
|
<!-- <ShieldPlus class="inline-block" /> -->
|
||||||
|
|
||||||
{#if $ae_loc.access_type == 'super'}
|
{#if $ae_loc.access_type == 'super'}
|
||||||
<Wand2 size="1em" class="m-1 inline-block" />
|
<Wand2 size="1em" class="m-1 inline-block" />
|
||||||
<span class:hidden={!expand} class="hidden group-hover:inline-block"
|
<span
|
||||||
>Super</span
|
class:hidden={!expand}
|
||||||
>
|
class="hidden group-hover:inline-block">Super</span>
|
||||||
{:else if $ae_loc.access_type == 'manager'}
|
{:else if $ae_loc.access_type == 'manager'}
|
||||||
<ShieldUser size="1em" class="m-1 inline-block" />
|
<ShieldUser size="1em" class="m-1 inline-block" />
|
||||||
<span class:hidden={!expand} class="hidden group-hover:inline-block"
|
<span
|
||||||
>Manager</span
|
class:hidden={!expand}
|
||||||
>
|
class="hidden group-hover:inline-block"
|
||||||
|
>Manager</span>
|
||||||
{:else if $ae_loc.access_type == 'administrator'}
|
{:else if $ae_loc.access_type == 'administrator'}
|
||||||
<UserCog size="1em" class="m-1 inline-block" />
|
<UserCog size="1em" class="m-1 inline-block" />
|
||||||
<span class:hidden={!expand} class="hidden group-hover:inline-block"
|
<span
|
||||||
>Administrator</span
|
class:hidden={!expand}
|
||||||
>
|
class="hidden group-hover:inline-block"
|
||||||
|
>Administrator</span>
|
||||||
{:else if $ae_loc.access_type == 'trusted'}
|
{:else if $ae_loc.access_type == 'trusted'}
|
||||||
<UserCheck size="1em" class="m-1 inline-block" />
|
<UserCheck size="1em" class="m-1 inline-block" />
|
||||||
<span class:hidden={!expand} class="hidden group-hover:inline-block"
|
<span
|
||||||
>Trusted Access</span
|
class:hidden={!expand}
|
||||||
>
|
class="hidden group-hover:inline-block"
|
||||||
|
>Trusted Access</span>
|
||||||
{:else if $ae_loc.access_type == 'public'}
|
{:else if $ae_loc.access_type == 'public'}
|
||||||
Public
|
Public
|
||||||
<span class:hidden={!expand} class="hidden group-hover:inline-block"
|
<span
|
||||||
>Access</span
|
class:hidden={!expand}
|
||||||
>
|
class="hidden group-hover:inline-block"
|
||||||
|
>Access</span>
|
||||||
{:else if $ae_loc.access_type == 'authenticated'}
|
{:else if $ae_loc.access_type == 'authenticated'}
|
||||||
Authenticated
|
Authenticated
|
||||||
<span class:hidden={!expand} class="hidden group-hover:inline-block"
|
<span
|
||||||
>Access</span
|
class:hidden={!expand}
|
||||||
>
|
class="hidden group-hover:inline-block"
|
||||||
|
>Access</span>
|
||||||
{:else if $ae_loc.access_type == 'anonymous'}
|
{:else if $ae_loc.access_type == 'anonymous'}
|
||||||
Anonymous Access
|
Anonymous Access
|
||||||
{:else}
|
{:else}
|
||||||
@@ -254,13 +268,13 @@ max-w-max -->
|
|||||||
// $ae_loc.sys_menu.expand_btn = true;
|
// $ae_loc.sys_menu.expand_btn = true;
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
class="btn btn-sm text-xs variant-outline-surface hover:variant-ghost-warning transition-all group"
|
class="btn btn-sm variant-outline-surface hover:variant-ghost-warning group text-xs transition-all"
|
||||||
title={`Current user access level: "${$ae_loc.user_access_type}". Click use passcode for a different access level.`}
|
title={`Current user access level: "${$ae_loc.user_access_type}". Click use passcode for a different access level.`}>
|
||||||
>
|
|
||||||
<!-- <span class="fas fa-lock mx-1"></span> -->
|
<!-- <span class="fas fa-lock mx-1"></span> -->
|
||||||
<!-- <ShieldMinus /> -->
|
<!-- <ShieldMinus /> -->
|
||||||
<ShieldEllipsis size="2em" class="inline-block" />
|
<ShieldEllipsis size="2em" class="inline-block" />
|
||||||
<span class="hidden group-hover:inline-block">Passcode?</span>
|
<span class="hidden group-hover:inline-block"
|
||||||
|
>Passcode?</span>
|
||||||
</button>
|
</button>
|
||||||
{:else}
|
{:else}
|
||||||
<button
|
<button
|
||||||
@@ -291,16 +305,17 @@ max-w-max -->
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
class="
|
class="
|
||||||
btn btn-sm text-xs
|
btn btn-sm variant-outline-surface
|
||||||
flex-row-reverse
|
hover:variant-ghost-warning
|
||||||
variant-outline-surface hover:variant-ghost-warning
|
group flex-row-reverse
|
||||||
transition-all group
|
text-xs transition-all
|
||||||
"
|
"
|
||||||
title={`Current access level: "${$ae_loc.access_type}". Click to clear the temporary access level.`}
|
title={`Current access level: "${$ae_loc.access_type}". Click to clear the temporary access level.`}>
|
||||||
>
|
|
||||||
<!-- <span class="fas fa-lock mx-1"></span> Lock? -->
|
<!-- <span class="fas fa-lock mx-1"></span> Lock? -->
|
||||||
<ShieldMinus class="inline-block" />
|
<ShieldMinus class="inline-block" />
|
||||||
<span class="hidden group-hover:inline-block"> Clear? </span>
|
<span class="hidden group-hover:inline-block">
|
||||||
|
Clear?
|
||||||
|
</span>
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
{:else}
|
{:else}
|
||||||
@@ -320,19 +335,22 @@ max-w-max -->
|
|||||||
// $ae_loc.app_cfg.show_element__access_type = true;
|
// $ae_loc.app_cfg.show_element__access_type = true;
|
||||||
// $ae_loc.app_cfg.show_element__passcode_input = true;
|
// $ae_loc.app_cfg.show_element__passcode_input = true;
|
||||||
// await tick();
|
// await tick();
|
||||||
console.log('Layout button click: Focus on passcode input!');
|
console.log(
|
||||||
|
'Layout button click: Focus on passcode input!'
|
||||||
|
);
|
||||||
/** @type {HTMLElement | null} */
|
/** @type {HTMLElement | null} */
|
||||||
const to_focus = document.getElementById('access_passcode_input');
|
const to_focus = document.getElementById(
|
||||||
|
'access_passcode_input'
|
||||||
|
);
|
||||||
to_focus?.focus();
|
to_focus?.focus();
|
||||||
}}
|
}}
|
||||||
class="
|
class="
|
||||||
btn btn-sm text-xs
|
btn btn-sm variant-outline-surface
|
||||||
flex-row-reverse
|
hover:variant-ghost-success
|
||||||
variant-outline-surface hover:variant-ghost-success
|
group flex-row-reverse
|
||||||
transition-all group
|
text-xs transition-all
|
||||||
"
|
"
|
||||||
title="Anonymous public access is currently set. You must Sign In or use a passcode to change your access level."
|
title="Anonymous public access is currently set. You must Sign In or use a passcode to change your access level.">
|
||||||
>
|
|
||||||
<!-- <span class="fas fa-lock mx-1 lock_icon"></span> -->
|
<!-- <span class="fas fa-lock mx-1 lock_icon"></span> -->
|
||||||
<!-- <span class="">Unlock?</span> -->
|
<!-- <span class="">Unlock?</span> -->
|
||||||
<ShieldUser class="inline-block" />
|
<ShieldUser class="inline-block" />
|
||||||
@@ -349,19 +367,21 @@ max-w-max -->
|
|||||||
// dispatch_edit_mode_changed();
|
// dispatch_edit_mode_changed();
|
||||||
}}
|
}}
|
||||||
class="
|
class="
|
||||||
btn btn-base text-sm
|
btn btn-base preset-tonal-warning
|
||||||
preset-tonal-warning
|
|
||||||
preset-outlined-warning-800-200
|
preset-outlined-warning-800-200
|
||||||
hover:preset-tonal-success
|
hover:preset-tonal-success
|
||||||
transition-all group
|
group
|
||||||
min-w-22 md:min-w-30 w-full max-w-fit
|
w-full max-w-fit
|
||||||
gap-1
|
min-w-22 gap-1 text-sm transition-all
|
||||||
|
md:min-w-30
|
||||||
"
|
"
|
||||||
title="Click to turn off edit mode. Edit mode is currently on."
|
title="Click to turn off edit mode. Edit mode is currently on.">
|
||||||
>
|
|
||||||
<ToggleRight size="1em" class="m-1 inline-block" />
|
<ToggleRight size="1em" class="m-1 inline-block" />
|
||||||
<span class="text-xs">Edit</span>
|
<span class="text-xs">Edit</span>
|
||||||
<span class="hidden group-hover:inline-block group-hover:text-xs"> Off </span>
|
<span
|
||||||
|
class="hidden group-hover:inline-block group-hover:text-xs">
|
||||||
|
Off
|
||||||
|
</span>
|
||||||
</button>
|
</button>
|
||||||
{:else if $ae_loc.authenticated_access}
|
{:else if $ae_loc.authenticated_access}
|
||||||
<button
|
<button
|
||||||
@@ -371,19 +391,21 @@ max-w-max -->
|
|||||||
// dispatch_edit_mode_changed();
|
// dispatch_edit_mode_changed();
|
||||||
}}
|
}}
|
||||||
class="
|
class="
|
||||||
btn btn-base text-sm
|
btn btn-base preset-tonal-surface
|
||||||
preset-tonal-surface
|
|
||||||
preset-outlined-warning-400-600
|
preset-outlined-warning-400-600
|
||||||
hover:preset-tonal-warning
|
hover:preset-tonal-warning
|
||||||
transition-all group
|
group
|
||||||
min-w-22 md:min-w-30 w-full max-w-fit
|
w-full max-w-fit
|
||||||
gap-1
|
min-w-22 gap-1 text-sm transition-all
|
||||||
|
md:min-w-30
|
||||||
"
|
"
|
||||||
title="Click to torn on/enable edit mode. Edit mode is currently off/disabled."
|
title="Click to torn on/enable edit mode. Edit mode is currently off/disabled.">
|
||||||
>
|
|
||||||
<ToggleLeft size="1em" class="m-1 inline-block" />
|
<ToggleLeft size="1em" class="m-1 inline-block" />
|
||||||
<span class="text-xs">Edit</span>
|
<span class="text-xs">Edit</span>
|
||||||
<span class="hidden group-hover:inline-block group-hover:text-xs"> On? </span>
|
<span
|
||||||
|
class="hidden group-hover:inline-block group-hover:text-xs">
|
||||||
|
On?
|
||||||
|
</span>
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
@@ -392,12 +414,12 @@ max-w-max -->
|
|||||||
type="button"
|
type="button"
|
||||||
class:w-full={expand}
|
class:w-full={expand}
|
||||||
class="
|
class="
|
||||||
btn btn-base text-sm
|
btn btn-base preset-tonal-surface
|
||||||
preset-tonal-surface
|
|
||||||
hover:preset-tonal-primary
|
hover:preset-tonal-primary
|
||||||
px-1 py-1
|
group
|
||||||
min-w-22 md:min-w-30 w-full max-w-fit
|
w-full max-w-fit
|
||||||
transition-all group
|
min-w-22 px-1 py-1 text-sm
|
||||||
|
transition-all md:min-w-30
|
||||||
"
|
"
|
||||||
title="Cycle font size: default → larger → smaller"
|
title="Cycle font size: default → larger → smaller"
|
||||||
onclick={() => {
|
onclick={() => {
|
||||||
@@ -409,17 +431,19 @@ max-w-max -->
|
|||||||
} else {
|
} else {
|
||||||
$ae_loc.font_size_mode = 'default';
|
$ae_loc.font_size_mode = 'default';
|
||||||
}
|
}
|
||||||
}}
|
}}>
|
||||||
>
|
|
||||||
{#if !$ae_loc.font_size_mode || $ae_loc.font_size_mode === 'default'}
|
{#if !$ae_loc.font_size_mode || $ae_loc.font_size_mode === 'default'}
|
||||||
<span class="font-bold text-sm leading-none">A</span>
|
<span class="text-sm leading-none font-bold">A</span>
|
||||||
<span class="hidden group-hover:inline-block text-xs">Font: Normal</span>
|
<span class="hidden text-xs group-hover:inline-block"
|
||||||
|
>Font: Normal</span>
|
||||||
{:else if $ae_loc.font_size_mode === 'larger'}
|
{:else if $ae_loc.font_size_mode === 'larger'}
|
||||||
<span class="font-bold text-base leading-none">A+</span>
|
<span class="text-base leading-none font-bold">A+</span>
|
||||||
<span class="hidden group-hover:inline-block text-xs">Font: Larger</span>
|
<span class="hidden text-xs group-hover:inline-block"
|
||||||
|
>Font: Larger</span>
|
||||||
{:else}
|
{:else}
|
||||||
<span class="font-bold text-xs leading-none">A−</span>
|
<span class="text-xs leading-none font-bold">A−</span>
|
||||||
<span class="hidden group-hover:inline-block text-xs">Font: Smaller</span>
|
<span class="hidden text-xs group-hover:inline-block"
|
||||||
|
>Font: Smaller</span>
|
||||||
{/if}
|
{/if}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@@ -432,13 +456,13 @@ max-w-max -->
|
|||||||
type="button"
|
type="button"
|
||||||
class:w-full={expand}
|
class:w-full={expand}
|
||||||
class="
|
class="
|
||||||
btn btn-base text-sm
|
btn btn-base preset-filled-tertiary-400-600
|
||||||
preset-filled-tertiary-400-600
|
|
||||||
preset-outlined-tertiary-400-600
|
preset-outlined-tertiary-400-600
|
||||||
hover:preset-filled-success active:preset-filled-success
|
hover:preset-filled-success
|
||||||
px-1 py-1
|
active:preset-filled-success group
|
||||||
min-w-22 md:min-w-30 w-full max-w-fit
|
w-full max-w-fit
|
||||||
transition-all group
|
min-w-22 px-1 py-1 text-sm
|
||||||
|
transition-all md:min-w-30
|
||||||
"
|
"
|
||||||
title="Show/Hide the system menu"
|
title="Show/Hide the system menu"
|
||||||
onclick={async () => {
|
onclick={async () => {
|
||||||
@@ -472,15 +496,14 @@ max-w-max -->
|
|||||||
// $ae_loc.app_cfg.show_element__passcode_input = false;
|
// $ae_loc.app_cfg.show_element__passcode_input = false;
|
||||||
}
|
}
|
||||||
// $ae_loc.sys_menu.expand_btn = !expand_btn;
|
// $ae_loc.sys_menu.expand_btn = !expand_btn;
|
||||||
}}
|
}}>
|
||||||
>
|
|
||||||
<!-- <span class=""> -->
|
<!-- <span class=""> -->
|
||||||
{#if expand}
|
{#if expand}
|
||||||
<CircleX class="m-1 inline-block" />
|
<CircleX class="m-1 inline-block" />
|
||||||
{:else}
|
{:else}
|
||||||
<Menu class="m-1 inline-block" />
|
<Menu class="m-1 inline-block" />
|
||||||
{/if}
|
{/if}
|
||||||
<span class="text-xs hidden group-hover:inline-block"> Menu </span>
|
<span class="hidden text-xs group-hover:inline-block"> Menu </span>
|
||||||
<!-- </span> -->
|
<!-- </span> -->
|
||||||
</button>
|
</button>
|
||||||
<!-- </div> -->
|
<!-- </div> -->
|
||||||
@@ -499,27 +522,26 @@ max-w-max -->
|
|||||||
ae_app__sys_menu
|
ae_app__sys_menu
|
||||||
|
|
||||||
hidden-print
|
hidden-print
|
||||||
flex flex-col
|
z-20 flex
|
||||||
items-end
|
|
||||||
justify-end
|
|
||||||
gap-2
|
|
||||||
|
|
||||||
min-w-48
|
min-w-48
|
||||||
|
flex-col
|
||||||
|
items-end
|
||||||
|
|
||||||
bg-white dark:bg-gray-800
|
justify-end
|
||||||
|
|
||||||
border border-gray-200 dark:border-gray-700
|
gap-2 rounded-lg
|
||||||
rounded-lg
|
|
||||||
px-1 py-2
|
|
||||||
|
|
||||||
transition-all
|
border border-gray-200 bg-white
|
||||||
delay-1000 hover:delay-100
|
px-1
|
||||||
duration-100 hover:duration-200
|
py-2 transition-all
|
||||||
ease-in-out
|
|
||||||
|
|
||||||
z-20 hover:z-30
|
delay-1000
|
||||||
"
|
duration-100 ease-in-out
|
||||||
>
|
hover:z-30 hover:delay-100
|
||||||
|
hover:duration-200
|
||||||
|
|
||||||
|
dark:border-gray-700 dark:bg-gray-800
|
||||||
|
">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class:w-full={expand}
|
class:w-full={expand}
|
||||||
@@ -528,8 +550,8 @@ max-w-max -->
|
|||||||
preset-filled-tertiary-400-600
|
preset-filled-tertiary-400-600
|
||||||
preset-outlined-tertiary-400-600
|
preset-outlined-tertiary-400-600
|
||||||
hover:preset-filled-success active:preset-filled-success
|
hover:preset-filled-success active:preset-filled-success
|
||||||
px-6 py-1
|
group px-6
|
||||||
transition-all group
|
py-1 transition-all
|
||||||
"
|
"
|
||||||
title="Show/Hide the system menu"
|
title="Show/Hide the system menu"
|
||||||
onclick={() => {
|
onclick={() => {
|
||||||
@@ -549,8 +571,7 @@ max-w-max -->
|
|||||||
}
|
}
|
||||||
// $ae_loc.sys_menu.expand_btn = !expand_btn;
|
// $ae_loc.sys_menu.expand_btn = !expand_btn;
|
||||||
// $ae_loc.sys_menu.expand = !expand;
|
// $ae_loc.sys_menu.expand = !expand;
|
||||||
}}
|
}}>
|
||||||
>
|
|
||||||
{#if expand}
|
{#if expand}
|
||||||
<CircleX class="m-1 inline-block" />
|
<CircleX class="m-1 inline-block" />
|
||||||
<span class="hidden group-hover:inline-block"> Hide Menu </span>
|
<span class="hidden group-hover:inline-block"> Hide Menu </span>
|
||||||
@@ -564,16 +585,14 @@ max-w-max -->
|
|||||||
<span class:hidden={!$ae_loc.edit_mode}>
|
<span class:hidden={!$ae_loc.edit_mode}>
|
||||||
<Element_app_cfg
|
<Element_app_cfg
|
||||||
hide={$ae_loc.sys_menu.hide_app_cfg}
|
hide={$ae_loc.sys_menu.hide_app_cfg}
|
||||||
expand={$ae_loc.sys_menu.expand_app_cfg}
|
expand={$ae_loc.sys_menu.expand_app_cfg} />
|
||||||
/>
|
|
||||||
</span>
|
</span>
|
||||||
<span class:hidden={!$ae_loc.edit_mode}>
|
<span class:hidden={!$ae_loc.edit_mode}>
|
||||||
<Element_theme
|
<Element_theme
|
||||||
hide={$ae_loc.sys_menu.hide_app_cfg}
|
hide={$ae_loc.sys_menu.hide_app_cfg}
|
||||||
expand={$ae_loc.sys_menu.expand_app_cfg}
|
expand={$ae_loc.sys_menu.expand_app_cfg}
|
||||||
set_theme_mode={true}
|
set_theme_mode={true}
|
||||||
set_theme_name={true}
|
set_theme_name={true} />
|
||||||
/>
|
|
||||||
</span>
|
</span>
|
||||||
<!-- {/if} -->
|
<!-- {/if} -->
|
||||||
|
|
||||||
@@ -582,8 +601,8 @@ max-w-max -->
|
|||||||
<!-- expand={$ae_loc.sys_menu.expand_user} -->
|
<!-- expand={$ae_loc.sys_menu.expand_user} -->
|
||||||
<Element_sign_in_out
|
<Element_sign_in_out
|
||||||
{data}
|
{data}
|
||||||
hidden={$ae_loc.iframe || !$ae_loc.app_cfg?.show_element__sign_in_out}
|
hidden={$ae_loc.iframe ||
|
||||||
/>
|
!$ae_loc.app_cfg?.show_element__sign_in_out} />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if !$ae_loc?.sys_menu?.hide_access_type && !$ae_loc?.iframe}
|
{#if !$ae_loc?.sys_menu?.hide_access_type && !$ae_loc?.iframe}
|
||||||
@@ -592,9 +611,10 @@ max-w-max -->
|
|||||||
bind:hide={$ae_loc.sys_menu.hide_access_type}
|
bind:hide={$ae_loc.sys_menu.hide_access_type}
|
||||||
bind:focus_input={$ae_sess.sys_menu.focus_passcode_input}
|
bind:focus_input={$ae_sess.sys_menu.focus_passcode_input}
|
||||||
bind:expand={$ae_loc.sys_menu.expand_access_type}
|
bind:expand={$ae_loc.sys_menu.expand_access_type}
|
||||||
bind:show_passcode_input={$ae_sess.app_cfg.show_element__passcode_input}
|
bind:show_passcode_input={
|
||||||
bind:trigger_clear_access
|
$ae_sess.app_cfg.show_element__passcode_input
|
||||||
/>
|
}
|
||||||
|
bind:trigger_clear_access />
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -1,22 +1,28 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Minimize2, Moon, Sun } from '@lucide/svelte';
|
import { Minimize2, Moon, Sun } from '@lucide/svelte';
|
||||||
import { ae_loc, ae_sess, ae_api, slct, slct_trigger } from '$lib/stores/ae_stores';
|
import {
|
||||||
|
ae_loc,
|
||||||
|
ae_sess,
|
||||||
|
ae_api,
|
||||||
|
slct,
|
||||||
|
slct_trigger
|
||||||
|
} from '$lib/stores/ae_stores';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
hide?: null | boolean;
|
hide?: null | boolean;
|
||||||
expand?: boolean;
|
expand?: boolean;
|
||||||
set_theme_mode: any;
|
set_theme_mode: any;
|
||||||
set_theme_name: any;
|
set_theme_name: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
let {
|
let {
|
||||||
log_lvl = $bindable(0),
|
log_lvl = $bindable(0),
|
||||||
hide = $bindable(false),
|
hide = $bindable(false),
|
||||||
expand = $bindable(false),
|
expand = $bindable(false),
|
||||||
set_theme_mode,
|
set_theme_mode,
|
||||||
set_theme_name
|
set_theme_name
|
||||||
}: Props = $props();
|
}: Props = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Change light and dark mode -->
|
<!-- Change light and dark mode -->
|
||||||
@@ -37,25 +43,23 @@ if ($ae_loc.app_cfg.theme_mode == 'light') {
|
|||||||
|
|
||||||
bg-surface-100 dark:bg-surface-800
|
bg-surface-100 dark:bg-surface-800
|
||||||
text-surface-900 dark:text-surface-100
|
text-surface-900 dark:text-surface-100
|
||||||
border border-surface-200 dark:border-surface-700
|
border-surface-200 dark:border-surface-700 flex
|
||||||
|
|
||||||
flex flex-col flex-wrap gap-1
|
w-72 max-w-72 flex-col flex-wrap
|
||||||
items-end justify-center
|
items-end justify-center
|
||||||
|
|
||||||
w-72 max-w-72
|
gap-1 rounded-lg
|
||||||
|
border
|
||||||
p-1
|
p-1
|
||||||
rounded-lg
|
|
||||||
shadow-md
|
shadow-md
|
||||||
|
|
||||||
duration-300 delay-150 hover:delay-1000 hover:ease-out
|
transition-all delay-150 duration-300 hover:delay-1000
|
||||||
transition-all
|
hover:ease-out
|
||||||
"
|
"
|
||||||
class:hidden={hide}
|
class:hidden={hide}>
|
||||||
>
|
|
||||||
<div
|
<div
|
||||||
class:hidden={!expand}
|
class:hidden={!expand}
|
||||||
class="flex flex-row flex-wrap gap-2 items-center justify-between w-full"
|
class="flex w-full flex-row flex-wrap items-center justify-between gap-2">
|
||||||
>
|
|
||||||
<!-- Theme Name: -->
|
<!-- Theme Name: -->
|
||||||
<span class="text-sm font-semibold">
|
<span class="text-sm font-semibold">
|
||||||
{$ae_loc.theme_name}
|
{$ae_loc.theme_name}
|
||||||
@@ -74,7 +78,10 @@ if ($ae_loc.app_cfg.theme_mode == 'light') {
|
|||||||
// document.body.setAttribute('data-theme', $ae_loc?.theme_name);
|
// document.body.setAttribute('data-theme', $ae_loc?.theme_name);
|
||||||
|
|
||||||
// NEW for Tailwind v4: Update the html attribute named "data-theme" to the current theme name.
|
// NEW for Tailwind v4: Update the html attribute named "data-theme" to the current theme name.
|
||||||
document.documentElement.setAttribute('data-theme', new_theme_name);
|
document.documentElement.setAttribute(
|
||||||
|
'data-theme',
|
||||||
|
new_theme_name
|
||||||
|
);
|
||||||
|
|
||||||
// if ($ae_loc.theme_mode == 'light') {
|
// if ($ae_loc.theme_mode == 'light') {
|
||||||
// document.documentElement.classList.remove('dark');
|
// document.documentElement.classList.remove('dark');
|
||||||
@@ -86,8 +93,7 @@ if ($ae_loc.app_cfg.theme_mode == 'light') {
|
|||||||
}}
|
}}
|
||||||
bind:value={$ae_loc.theme_name}
|
bind:value={$ae_loc.theme_name}
|
||||||
class="select w-32"
|
class="select w-32"
|
||||||
title="Theme name"
|
title="Theme name">
|
||||||
>
|
|
||||||
<option value="">-- None --</option>
|
<option value="">-- None --</option>
|
||||||
<option value="cerberus">Cerberus</option>
|
<option value="cerberus">Cerberus</option>
|
||||||
<option value="concord">Concord</option>
|
<option value="concord">Concord</option>
|
||||||
@@ -112,41 +118,38 @@ if ($ae_loc.app_cfg.theme_mode == 'light') {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="flex flex-row flex-wrap gap-2 items-center w-full"
|
class="flex w-full flex-row flex-wrap items-center gap-2"
|
||||||
class:justify-between={expand}
|
class:justify-between={expand}
|
||||||
class:justify-end={!expand}
|
class:justify-end={!expand}>
|
||||||
>
|
|
||||||
{#if expand}
|
{#if expand}
|
||||||
<!-- Hide theme options -->
|
<!-- Hide theme options -->
|
||||||
<button
|
<button
|
||||||
class="
|
class="
|
||||||
btn btn-sm text-xs
|
btn btn-sm preset-tonal-secondary
|
||||||
preset-tonal-secondary hover:preset-filled-secondary-500
|
hover:preset-filled-secondary-500 group
|
||||||
transition-all group
|
text-xs transition-all
|
||||||
"
|
"
|
||||||
onclick={() => {
|
onclick={() => {
|
||||||
expand = !expand;
|
expand = !expand;
|
||||||
}}
|
}}
|
||||||
title="Hide Theme Options"
|
title="Hide Theme Options">
|
||||||
>
|
|
||||||
<!-- <span class="fas fa-compress-alt"></span> -->
|
<!-- <span class="fas fa-compress-alt"></span> -->
|
||||||
<Minimize2 size="1em" class="m-1" />
|
<Minimize2 size="1em" class="m-1" />
|
||||||
<span
|
<span
|
||||||
class="
|
class="
|
||||||
hidden
|
hidden
|
||||||
group-hover:inline-block
|
|
||||||
text-xs
|
text-xs
|
||||||
"
|
group-hover:inline-block
|
||||||
>
|
">
|
||||||
Hide Theme Options
|
Hide Theme Options
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="
|
class="
|
||||||
btn btn-sm text-xs
|
btn btn-sm preset-tonal-secondary
|
||||||
preset-tonal-secondary hover:preset-filled-secondary-500
|
hover:preset-filled-secondary-500 group
|
||||||
transition-all group
|
text-xs transition-all
|
||||||
"
|
"
|
||||||
onclick={() => {
|
onclick={() => {
|
||||||
if ($ae_loc.theme_mode == 'light') {
|
if ($ae_loc.theme_mode == 'light') {
|
||||||
@@ -157,23 +160,24 @@ if ($ae_loc.app_cfg.theme_mode == 'light') {
|
|||||||
|
|
||||||
// DOM sync is handled reactively by the layout effect in +layout.svelte
|
// DOM sync is handled reactively by the layout effect in +layout.svelte
|
||||||
}}
|
}}
|
||||||
title="Change light and dark mode"
|
title="Change light and dark mode">
|
||||||
>
|
|
||||||
<!-- <span class="fas fa-adjust"></span> -->
|
<!-- <span class="fas fa-adjust"></span> -->
|
||||||
{#if $ae_loc.theme_mode == 'light'}
|
{#if $ae_loc.theme_mode == 'light'}
|
||||||
<Sun class="m-1" />
|
<Sun class="m-1" />
|
||||||
<span class="hidden md:inline-block group-hover:inline-block">Light Mode</span>
|
<span
|
||||||
|
class="hidden group-hover:inline-block md:inline-block"
|
||||||
|
>Light Mode</span>
|
||||||
{:else if $ae_loc.theme_mode == 'dark'}
|
{:else if $ae_loc.theme_mode == 'dark'}
|
||||||
<Moon class="m-1" />
|
<Moon class="m-1" />
|
||||||
<span class="hidden group-hover:inline-block">Dark Mode</span>
|
<span class="hidden group-hover:inline-block"
|
||||||
|
>Dark Mode</span>
|
||||||
{/if}
|
{/if}
|
||||||
<span
|
<span
|
||||||
class="
|
class="
|
||||||
hidden
|
hidden
|
||||||
group-hover:inline-block
|
|
||||||
text-xs
|
text-xs
|
||||||
"
|
group-hover:inline-block
|
||||||
>
|
">
|
||||||
Change
|
Change
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
@@ -197,18 +201,19 @@ if ($ae_loc.app_cfg.theme_mode == 'light') {
|
|||||||
|
|
||||||
expand = !expand;
|
expand = !expand;
|
||||||
}}
|
}}
|
||||||
title="Change light and dark mode"
|
title="Change light and dark mode">
|
||||||
>
|
|
||||||
{#if $ae_loc.theme_mode == 'light'}
|
{#if $ae_loc.theme_mode == 'light'}
|
||||||
<span class="inline-block" title="Light Mode">
|
<span class="inline-block" title="Light Mode">
|
||||||
<Sun />
|
<Sun />
|
||||||
</span>
|
</span>
|
||||||
<span class="hidden group-hover:inline-block">Light Mode</span>
|
<span class="hidden group-hover:inline-block"
|
||||||
|
>Light Mode</span>
|
||||||
{:else if $ae_loc.theme_mode == 'dark'}
|
{:else if $ae_loc.theme_mode == 'dark'}
|
||||||
<span class="inline-block" title="Dark Mode">
|
<span class="inline-block" title="Dark Mode">
|
||||||
<Moon />
|
<Moon />
|
||||||
</span>
|
</span>
|
||||||
<span class="hidden group-hover:inline-block">Dark Mode</span>
|
<span class="hidden group-hover:inline-block"
|
||||||
|
>Dark Mode</span>
|
||||||
{/if}
|
{/if}
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -1,120 +1,136 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
/**
|
/**
|
||||||
* e_app_url_builder.svelte
|
* e_app_url_builder.svelte
|
||||||
* URL Param Builder — lets admins construct and copy shareable URLs
|
* URL Param Builder — lets admins construct and copy shareable URLs
|
||||||
* with any combination of the supported URL params applied.
|
* with any combination of the supported URL params applied.
|
||||||
*
|
*
|
||||||
* Core params:
|
* Core params:
|
||||||
* ?iframe=true|false — persist kiosk mode (stays in URL)
|
* ?iframe=true|false — persist kiosk mode (stays in URL)
|
||||||
* ?theme=<name> — set theme name on load (stripped after apply)
|
* ?theme=<name> — set theme name on load (stripped after apply)
|
||||||
* ?theme_mode=light|dark — set light/dark mode on load (stripped after apply)
|
* ?theme_mode=light|dark — set light/dark mode on load (stripped after apply)
|
||||||
* ?key=<access_key> — site access key
|
* ?key=<access_key> — site access key
|
||||||
*
|
*
|
||||||
* Launcher params (all stripped from URL after apply):
|
* Launcher params (all stripped from URL after apply):
|
||||||
* ?launcher_menu=hide|show
|
* ?launcher_menu=hide|show
|
||||||
* ?launcher_header=hide|show
|
* ?launcher_header=hide|show
|
||||||
* ?launcher_footer=hide|show
|
* ?launcher_footer=hide|show
|
||||||
*/
|
*/
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
import { Copy, Check, Link } from '@lucide/svelte';
|
import { Copy, Check, Link } from '@lucide/svelte';
|
||||||
|
|
||||||
// --- Per-param: include this param in the output URL?
|
// --- Per-param: include this param in the output URL?
|
||||||
let use_iframe = $state(false);
|
let use_iframe = $state(false);
|
||||||
let use_theme = $state(false);
|
let use_theme = $state(false);
|
||||||
let use_theme_mode = $state(false);
|
let use_theme_mode = $state(false);
|
||||||
let use_key = $state(false);
|
let use_key = $state(false);
|
||||||
let use_launcher_menu = $state(false);
|
let use_launcher_menu = $state(false);
|
||||||
let use_launcher_header = $state(false);
|
let use_launcher_header = $state(false);
|
||||||
let use_launcher_footer = $state(false);
|
let use_launcher_footer = $state(false);
|
||||||
|
|
||||||
// --- Param values
|
// --- Param values
|
||||||
let val_iframe = $state<'true' | 'false'>('true');
|
let val_iframe = $state<'true' | 'false'>('true');
|
||||||
let val_theme = $state('nouveau');
|
let val_theme = $state('nouveau');
|
||||||
let val_theme_mode = $state<'light' | 'dark'>('dark');
|
let val_theme_mode = $state<'light' | 'dark'>('dark');
|
||||||
let val_key = $state('');
|
let val_key = $state('');
|
||||||
let val_launcher_menu = $state<'hide' | 'show'>('hide');
|
let val_launcher_menu = $state<'hide' | 'show'>('hide');
|
||||||
let val_launcher_header = $state<'hide' | 'show'>('hide');
|
let val_launcher_header = $state<'hide' | 'show'>('hide');
|
||||||
let val_launcher_footer = $state<'hide' | 'show'>('hide');
|
let val_launcher_footer = $state<'hide' | 'show'>('hide');
|
||||||
|
|
||||||
// Build the output URL reactively
|
// Build the output URL reactively
|
||||||
let built_url = $derived.by(() => {
|
let built_url = $derived.by(() => {
|
||||||
const base = $page.url;
|
const base = $page.url;
|
||||||
const u = new URL(base.pathname + base.search + base.hash, base.origin);
|
const u = new URL(base.pathname + base.search + base.hash, base.origin);
|
||||||
|
|
||||||
// Remove all known params first so we start clean each time
|
// Remove all known params first so we start clean each time
|
||||||
u.searchParams.delete('iframe');
|
u.searchParams.delete('iframe');
|
||||||
u.searchParams.delete('theme');
|
u.searchParams.delete('theme');
|
||||||
u.searchParams.delete('theme_mode');
|
u.searchParams.delete('theme_mode');
|
||||||
u.searchParams.delete('key');
|
u.searchParams.delete('key');
|
||||||
u.searchParams.delete('launcher_menu');
|
u.searchParams.delete('launcher_menu');
|
||||||
u.searchParams.delete('launcher_header');
|
u.searchParams.delete('launcher_header');
|
||||||
u.searchParams.delete('launcher_footer');
|
u.searchParams.delete('launcher_footer');
|
||||||
|
|
||||||
if (use_iframe) u.searchParams.set('iframe', val_iframe);
|
if (use_iframe) u.searchParams.set('iframe', val_iframe);
|
||||||
if (use_theme) u.searchParams.set('theme', val_theme);
|
if (use_theme) u.searchParams.set('theme', val_theme);
|
||||||
if (use_theme_mode) u.searchParams.set('theme_mode', val_theme_mode);
|
if (use_theme_mode) u.searchParams.set('theme_mode', val_theme_mode);
|
||||||
if (use_key && val_key.trim()) u.searchParams.set('key', val_key.trim());
|
if (use_key && val_key.trim()) u.searchParams.set('key', val_key.trim());
|
||||||
if (use_launcher_menu) u.searchParams.set('launcher_menu', val_launcher_menu);
|
if (use_launcher_menu)
|
||||||
if (use_launcher_header) u.searchParams.set('launcher_header', val_launcher_header);
|
u.searchParams.set('launcher_menu', val_launcher_menu);
|
||||||
if (use_launcher_footer) u.searchParams.set('launcher_footer', val_launcher_footer);
|
if (use_launcher_header)
|
||||||
|
u.searchParams.set('launcher_header', val_launcher_header);
|
||||||
|
if (use_launcher_footer)
|
||||||
|
u.searchParams.set('launcher_footer', val_launcher_footer);
|
||||||
|
|
||||||
return u.toString();
|
return u.toString();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Output mode: full URL (default) or params-only string
|
||||||
|
let params_only = $state(false);
|
||||||
|
|
||||||
|
let output = $derived.by(() => {
|
||||||
|
if (!params_only) return built_url;
|
||||||
|
const u = new URL(built_url);
|
||||||
|
return u.search || '(no params set)';
|
||||||
|
});
|
||||||
|
|
||||||
|
let copied = $state(false);
|
||||||
|
|
||||||
|
function copy_url() {
|
||||||
|
navigator.clipboard.writeText(output).then(() => {
|
||||||
|
copied = true;
|
||||||
|
setTimeout(() => (copied = false), 2000);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Output mode: full URL (default) or params-only string
|
const theme_options = [
|
||||||
let params_only = $state(false);
|
{ value: 'cerberus', label: 'Cerberus' },
|
||||||
|
{ value: 'concord', label: 'Concord' },
|
||||||
let output = $derived.by(() => {
|
{ value: 'crimson', label: 'Crimson' },
|
||||||
if (!params_only) return built_url;
|
{ value: 'hamlindigo', label: 'Hamlindigo' },
|
||||||
const u = new URL(built_url);
|
{ value: 'modern', label: 'Modern' },
|
||||||
return u.search || '(no params set)';
|
{ value: 'nouveau', label: 'Nouveau' },
|
||||||
});
|
{ value: 'rocket', label: 'Rocket' },
|
||||||
|
{ value: 'terminus', label: 'Terminus' },
|
||||||
let copied = $state(false);
|
{ value: 'vintage', label: 'Vintage' },
|
||||||
|
{ value: 'wintry', label: 'Wintry' },
|
||||||
function copy_url() {
|
{ value: 'AE_OSIT_default', label: 'OSIT' },
|
||||||
navigator.clipboard.writeText(output).then(() => {
|
{ value: 'AE_Firefly', label: 'Firefly ✦' },
|
||||||
copied = true;
|
{ value: 'AE_Firefly_SteelBlue', label: 'Firefly SteelBlue ✦' },
|
||||||
setTimeout(() => copied = false, 2000);
|
{ value: 'AE_Firefly_Indigo', label: 'Firefly Indigo ✦' },
|
||||||
});
|
{ value: 'AE_Firefly_Rainbow', label: 'Firefly Rainbow ✨' },
|
||||||
}
|
{ value: 'AE_c_IDAA_light', label: 'IDAA – light' },
|
||||||
|
{ value: 'AE_c_LCI', label: 'LCI' }
|
||||||
const theme_options = [
|
];
|
||||||
{ value: 'cerberus', label: 'Cerberus' },
|
|
||||||
{ value: 'concord', label: 'Concord' },
|
|
||||||
{ value: 'crimson', label: 'Crimson' },
|
|
||||||
{ value: 'hamlindigo', label: 'Hamlindigo' },
|
|
||||||
{ value: 'modern', label: 'Modern' },
|
|
||||||
{ value: 'nouveau', label: 'Nouveau' },
|
|
||||||
{ value: 'rocket', label: 'Rocket' },
|
|
||||||
{ value: 'terminus', label: 'Terminus' },
|
|
||||||
{ value: 'vintage', label: 'Vintage' },
|
|
||||||
{ value: 'wintry', label: 'Wintry' },
|
|
||||||
{ value: 'AE_OSIT_default', label: 'OSIT' },
|
|
||||||
{ value: 'AE_Firefly', label: 'Firefly ✦' },
|
|
||||||
{ value: 'AE_Firefly_SteelBlue', label: 'Firefly SteelBlue ✦' },
|
|
||||||
{ value: 'AE_Firefly_Indigo', label: 'Firefly Indigo ✦' },
|
|
||||||
{ value: 'AE_Firefly_Rainbow', label: 'Firefly Rainbow ✨' },
|
|
||||||
{ value: 'AE_c_IDAA_light', label: 'IDAA – light' },
|
|
||||||
{ value: 'AE_c_LCI', label: 'LCI' },
|
|
||||||
];
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<section class="space-y-3 text-sm">
|
<section class="space-y-3 text-sm">
|
||||||
|
<h2
|
||||||
<h2 class="text-xs font-semibold uppercase tracking-widest text-surface-500 dark:text-surface-400 flex items-center gap-1">
|
class="text-surface-500 dark:text-surface-400 flex items-center gap-1 text-xs font-semibold tracking-widest uppercase">
|
||||||
<Link size="0.9em" /> URL Param Builder
|
<Link size="0.9em" /> URL Param Builder
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<!-- ── Core params ─────────────────────────────────────────────────── -->
|
<!-- ── Core params ─────────────────────────────────────────────────── -->
|
||||||
<div class="space-y-1.5">
|
<div class="space-y-1.5">
|
||||||
<p class="text-[9px] font-bold uppercase tracking-widest opacity-40 ml-0.5">Core</p>
|
<p
|
||||||
|
class="ml-0.5 text-[9px] font-bold tracking-widest uppercase opacity-40">
|
||||||
|
Core
|
||||||
|
</p>
|
||||||
|
|
||||||
<!-- iframe -->
|
<!-- iframe -->
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<input id="ubld_iframe" type="checkbox" class="checkbox checkbox-sm shrink-0" bind:checked={use_iframe} />
|
<input
|
||||||
<label for="ubld_iframe" class="w-24 text-xs font-mono cursor-pointer select-none" class:opacity-35={!use_iframe}>iframe</label>
|
id="ubld_iframe"
|
||||||
<select bind:value={val_iframe} disabled={!use_iframe} class="select select-sm text-xs flex-1 disabled:opacity-40">
|
type="checkbox"
|
||||||
|
class="checkbox checkbox-sm shrink-0"
|
||||||
|
bind:checked={use_iframe} />
|
||||||
|
<label
|
||||||
|
for="ubld_iframe"
|
||||||
|
class="w-24 cursor-pointer font-mono text-xs select-none"
|
||||||
|
class:opacity-35={!use_iframe}>iframe</label>
|
||||||
|
<select
|
||||||
|
bind:value={val_iframe}
|
||||||
|
disabled={!use_iframe}
|
||||||
|
class="select select-sm flex-1 text-xs disabled:opacity-40">
|
||||||
<option value="true">true</option>
|
<option value="true">true</option>
|
||||||
<option value="false">false</option>
|
<option value="false">false</option>
|
||||||
</select>
|
</select>
|
||||||
@@ -122,9 +138,19 @@
|
|||||||
|
|
||||||
<!-- theme -->
|
<!-- theme -->
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<input id="ubld_theme" type="checkbox" class="checkbox checkbox-sm shrink-0" bind:checked={use_theme} />
|
<input
|
||||||
<label for="ubld_theme" class="w-24 text-xs font-mono cursor-pointer select-none" class:opacity-35={!use_theme}>theme</label>
|
id="ubld_theme"
|
||||||
<select bind:value={val_theme} disabled={!use_theme} class="select select-sm text-xs flex-1 disabled:opacity-40">
|
type="checkbox"
|
||||||
|
class="checkbox checkbox-sm shrink-0"
|
||||||
|
bind:checked={use_theme} />
|
||||||
|
<label
|
||||||
|
for="ubld_theme"
|
||||||
|
class="w-24 cursor-pointer font-mono text-xs select-none"
|
||||||
|
class:opacity-35={!use_theme}>theme</label>
|
||||||
|
<select
|
||||||
|
bind:value={val_theme}
|
||||||
|
disabled={!use_theme}
|
||||||
|
class="select select-sm flex-1 text-xs disabled:opacity-40">
|
||||||
{#each theme_options as opt}
|
{#each theme_options as opt}
|
||||||
<option value={opt.value}>{opt.label}</option>
|
<option value={opt.value}>{opt.label}</option>
|
||||||
{/each}
|
{/each}
|
||||||
@@ -133,9 +159,19 @@
|
|||||||
|
|
||||||
<!-- theme_mode -->
|
<!-- theme_mode -->
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<input id="ubld_theme_mode" type="checkbox" class="checkbox checkbox-sm shrink-0" bind:checked={use_theme_mode} />
|
<input
|
||||||
<label for="ubld_theme_mode" class="w-24 text-xs font-mono cursor-pointer select-none" class:opacity-35={!use_theme_mode}>theme_mode</label>
|
id="ubld_theme_mode"
|
||||||
<select bind:value={val_theme_mode} disabled={!use_theme_mode} class="select select-sm text-xs flex-1 disabled:opacity-40">
|
type="checkbox"
|
||||||
|
class="checkbox checkbox-sm shrink-0"
|
||||||
|
bind:checked={use_theme_mode} />
|
||||||
|
<label
|
||||||
|
for="ubld_theme_mode"
|
||||||
|
class="w-24 cursor-pointer font-mono text-xs select-none"
|
||||||
|
class:opacity-35={!use_theme_mode}>theme_mode</label>
|
||||||
|
<select
|
||||||
|
bind:value={val_theme_mode}
|
||||||
|
disabled={!use_theme_mode}
|
||||||
|
class="select select-sm flex-1 text-xs disabled:opacity-40">
|
||||||
<option value="light">light</option>
|
<option value="light">light</option>
|
||||||
<option value="dark">dark</option>
|
<option value="dark">dark</option>
|
||||||
</select>
|
</select>
|
||||||
@@ -143,27 +179,46 @@
|
|||||||
|
|
||||||
<!-- key -->
|
<!-- key -->
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<input id="ubld_key" type="checkbox" class="checkbox checkbox-sm shrink-0" bind:checked={use_key} />
|
<input
|
||||||
<label for="ubld_key" class="w-24 text-xs font-mono cursor-pointer select-none" class:opacity-35={!use_key}>key</label>
|
id="ubld_key"
|
||||||
|
type="checkbox"
|
||||||
|
class="checkbox checkbox-sm shrink-0"
|
||||||
|
bind:checked={use_key} />
|
||||||
|
<label
|
||||||
|
for="ubld_key"
|
||||||
|
class="w-24 cursor-pointer font-mono text-xs select-none"
|
||||||
|
class:opacity-35={!use_key}>key</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
bind:value={val_key}
|
bind:value={val_key}
|
||||||
disabled={!use_key}
|
disabled={!use_key}
|
||||||
placeholder="access key"
|
placeholder="access key"
|
||||||
class="input input-sm text-xs font-mono flex-1 disabled:opacity-40"
|
class="input input-sm flex-1 font-mono text-xs disabled:opacity-40" />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- ── Launcher params ─────────────────────────────────────────────── -->
|
<!-- ── Launcher params ─────────────────────────────────────────────── -->
|
||||||
<div class="space-y-1.5 border-t border-surface-500/20 pt-2.5">
|
<div class="border-surface-500/20 space-y-1.5 border-t pt-2.5">
|
||||||
<p class="text-[9px] font-bold uppercase tracking-widest opacity-40 ml-0.5">Launcher</p>
|
<p
|
||||||
|
class="ml-0.5 text-[9px] font-bold tracking-widest uppercase opacity-40">
|
||||||
|
Launcher
|
||||||
|
</p>
|
||||||
|
|
||||||
<!-- launcher_menu -->
|
<!-- launcher_menu -->
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<input id="ubld_launcher_menu" type="checkbox" class="checkbox checkbox-sm shrink-0" bind:checked={use_launcher_menu} />
|
<input
|
||||||
<label for="ubld_launcher_menu" class="w-24 text-xs font-mono cursor-pointer select-none" class:opacity-35={!use_launcher_menu}>menu</label>
|
id="ubld_launcher_menu"
|
||||||
<select bind:value={val_launcher_menu} disabled={!use_launcher_menu} class="select select-sm text-xs flex-1 disabled:opacity-40">
|
type="checkbox"
|
||||||
|
class="checkbox checkbox-sm shrink-0"
|
||||||
|
bind:checked={use_launcher_menu} />
|
||||||
|
<label
|
||||||
|
for="ubld_launcher_menu"
|
||||||
|
class="w-24 cursor-pointer font-mono text-xs select-none"
|
||||||
|
class:opacity-35={!use_launcher_menu}>menu</label>
|
||||||
|
<select
|
||||||
|
bind:value={val_launcher_menu}
|
||||||
|
disabled={!use_launcher_menu}
|
||||||
|
class="select select-sm flex-1 text-xs disabled:opacity-40">
|
||||||
<option value="hide">hide</option>
|
<option value="hide">hide</option>
|
||||||
<option value="show">show</option>
|
<option value="show">show</option>
|
||||||
</select>
|
</select>
|
||||||
@@ -171,9 +226,19 @@
|
|||||||
|
|
||||||
<!-- launcher_header -->
|
<!-- launcher_header -->
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<input id="ubld_launcher_header" type="checkbox" class="checkbox checkbox-sm shrink-0" bind:checked={use_launcher_header} />
|
<input
|
||||||
<label for="ubld_launcher_header" class="w-24 text-xs font-mono cursor-pointer select-none" class:opacity-35={!use_launcher_header}>header</label>
|
id="ubld_launcher_header"
|
||||||
<select bind:value={val_launcher_header} disabled={!use_launcher_header} class="select select-sm text-xs flex-1 disabled:opacity-40">
|
type="checkbox"
|
||||||
|
class="checkbox checkbox-sm shrink-0"
|
||||||
|
bind:checked={use_launcher_header} />
|
||||||
|
<label
|
||||||
|
for="ubld_launcher_header"
|
||||||
|
class="w-24 cursor-pointer font-mono text-xs select-none"
|
||||||
|
class:opacity-35={!use_launcher_header}>header</label>
|
||||||
|
<select
|
||||||
|
bind:value={val_launcher_header}
|
||||||
|
disabled={!use_launcher_header}
|
||||||
|
class="select select-sm flex-1 text-xs disabled:opacity-40">
|
||||||
<option value="hide">hide</option>
|
<option value="hide">hide</option>
|
||||||
<option value="show">show</option>
|
<option value="show">show</option>
|
||||||
</select>
|
</select>
|
||||||
@@ -181,9 +246,19 @@
|
|||||||
|
|
||||||
<!-- launcher_footer -->
|
<!-- launcher_footer -->
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<input id="ubld_launcher_footer" type="checkbox" class="checkbox checkbox-sm shrink-0" bind:checked={use_launcher_footer} />
|
<input
|
||||||
<label for="ubld_launcher_footer" class="w-24 text-xs font-mono cursor-pointer select-none" class:opacity-35={!use_launcher_footer}>footer</label>
|
id="ubld_launcher_footer"
|
||||||
<select bind:value={val_launcher_footer} disabled={!use_launcher_footer} class="select select-sm text-xs flex-1 disabled:opacity-40">
|
type="checkbox"
|
||||||
|
class="checkbox checkbox-sm shrink-0"
|
||||||
|
bind:checked={use_launcher_footer} />
|
||||||
|
<label
|
||||||
|
for="ubld_launcher_footer"
|
||||||
|
class="w-24 cursor-pointer font-mono text-xs select-none"
|
||||||
|
class:opacity-35={!use_launcher_footer}>footer</label>
|
||||||
|
<select
|
||||||
|
bind:value={val_launcher_footer}
|
||||||
|
disabled={!use_launcher_footer}
|
||||||
|
class="select select-sm flex-1 text-xs disabled:opacity-40">
|
||||||
<option value="hide">hide</option>
|
<option value="hide">hide</option>
|
||||||
<option value="show">show</option>
|
<option value="show">show</option>
|
||||||
</select>
|
</select>
|
||||||
@@ -191,26 +266,33 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- ── Output ──────────────────────────────────────────────────────── -->
|
<!-- ── Output ──────────────────────────────────────────────────────── -->
|
||||||
<div class="border-t border-surface-500/20 pt-2.5 space-y-1.5">
|
<div class="border-surface-500/20 space-y-1.5 border-t pt-2.5">
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<input id="ubld_params_only" type="checkbox" class="checkbox checkbox-sm shrink-0" bind:checked={params_only} />
|
<input
|
||||||
<label for="ubld_params_only" class="text-xs cursor-pointer select-none" class:opacity-35={!params_only}>Params only</label>
|
id="ubld_params_only"
|
||||||
|
type="checkbox"
|
||||||
|
class="checkbox checkbox-sm shrink-0"
|
||||||
|
bind:checked={params_only} />
|
||||||
|
<label
|
||||||
|
for="ubld_params_only"
|
||||||
|
class="cursor-pointer text-xs select-none"
|
||||||
|
class:opacity-35={!params_only}>Params only</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex gap-1 items-stretch">
|
<div class="flex items-stretch gap-1">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
readonly
|
readonly
|
||||||
value={output}
|
value={output}
|
||||||
class="input input-sm text-xs font-mono flex-1 bg-surface-50/50 dark:bg-surface-700/50 cursor-text"
|
class="input input-sm bg-surface-50/50 dark:bg-surface-700/50 flex-1 cursor-text font-mono text-xs"
|
||||||
onclick={(e) => (e.target as HTMLInputElement).select()}
|
onclick={(e) => (e.target as HTMLInputElement).select()}
|
||||||
title="Click to select all"
|
title="Click to select all" />
|
||||||
/>
|
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm {copied ? 'preset-filled-success' : 'preset-tonal-primary'} shrink-0 transition-all"
|
class="btn btn-sm {copied
|
||||||
|
? 'preset-filled-success'
|
||||||
|
: 'preset-tonal-primary'} shrink-0 transition-all"
|
||||||
onclick={copy_url}
|
onclick={copy_url}
|
||||||
title="Copy URL to clipboard"
|
title="Copy URL to clipboard">
|
||||||
>
|
|
||||||
{#if copied}
|
{#if copied}
|
||||||
<Check size="1em" />
|
<Check size="1em" />
|
||||||
{:else}
|
{:else}
|
||||||
@@ -219,5 +301,4 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -1,57 +1,62 @@
|
|||||||
<script lang="ts" module>
|
<script lang="ts" module>
|
||||||
import type { WithElementRef } from 'bits-ui';
|
import type { WithElementRef } from 'bits-ui';
|
||||||
import type { HTMLAnchorAttributes, HTMLButtonAttributes } from 'svelte/elements';
|
import type {
|
||||||
import { type VariantProps, tv } from 'tailwind-variants';
|
HTMLAnchorAttributes,
|
||||||
|
HTMLButtonAttributes
|
||||||
|
} from 'svelte/elements';
|
||||||
|
import { type VariantProps, tv } from 'tailwind-variants';
|
||||||
|
|
||||||
export const buttonVariants = tv({
|
export const buttonVariants = tv({
|
||||||
base: 'ring-offset-background focus-visible:ring-ring inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
|
base: 'ring-offset-background focus-visible:ring-ring inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
|
||||||
variants: {
|
variants: {
|
||||||
variant: {
|
variant: {
|
||||||
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
|
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
|
||||||
destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',
|
destructive:
|
||||||
outline:
|
'bg-destructive text-destructive-foreground hover:bg-destructive/90',
|
||||||
'border-input bg-background hover:bg-accent hover:text-accent-foreground border',
|
outline:
|
||||||
secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
|
'border-input bg-background hover:bg-accent hover:text-accent-foreground border',
|
||||||
ghost: 'hover:bg-accent hover:text-accent-foreground',
|
secondary:
|
||||||
link: 'text-primary underline-offset-4 hover:underline'
|
'bg-secondary text-secondary-foreground hover:bg-secondary/80',
|
||||||
},
|
ghost: 'hover:bg-accent hover:text-accent-foreground',
|
||||||
size: {
|
link: 'text-primary underline-offset-4 hover:underline'
|
||||||
default: 'h-10 px-4 py-2',
|
|
||||||
sm: 'h-9 rounded-md px-3',
|
|
||||||
lg: 'h-11 rounded-md px-8',
|
|
||||||
icon: 'h-10 w-10'
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
defaultVariants: {
|
size: {
|
||||||
variant: 'default',
|
default: 'h-10 px-4 py-2',
|
||||||
size: 'default'
|
sm: 'h-9 rounded-md px-3',
|
||||||
|
lg: 'h-11 rounded-md px-8',
|
||||||
|
icon: 'h-10 w-10'
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
|
defaultVariants: {
|
||||||
|
variant: 'default',
|
||||||
|
size: 'default'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
export type ButtonVariant = VariantProps<typeof buttonVariants>['variant'];
|
export type ButtonVariant = VariantProps<typeof buttonVariants>['variant'];
|
||||||
export type ButtonSize = VariantProps<typeof buttonVariants>['size'];
|
export type ButtonSize = VariantProps<typeof buttonVariants>['size'];
|
||||||
|
|
||||||
export type ButtonProps = WithElementRef<HTMLButtonAttributes> &
|
export type ButtonProps = WithElementRef<HTMLButtonAttributes> &
|
||||||
WithElementRef<HTMLAnchorAttributes> & {
|
WithElementRef<HTMLAnchorAttributes> & {
|
||||||
variant?: ButtonVariant;
|
variant?: ButtonVariant;
|
||||||
size?: ButtonSize;
|
size?: ButtonSize;
|
||||||
class?: any;
|
class?: any;
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { cn } from '$lib/utils/utils.js';
|
import { cn } from '$lib/utils/utils.js';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
class: className,
|
class: className,
|
||||||
variant = 'default',
|
variant = 'default',
|
||||||
size = 'default',
|
size = 'default',
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
href = undefined,
|
href = undefined,
|
||||||
type = 'button',
|
type = 'button',
|
||||||
children,
|
children,
|
||||||
...restProps
|
...restProps
|
||||||
}: ButtonProps = $props();
|
}: ButtonProps = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if href}
|
{#if href}
|
||||||
@@ -59,8 +64,7 @@
|
|||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
class={cn(buttonVariants({ variant, size, className }))}
|
class={cn(buttonVariants({ variant, size, className }))}
|
||||||
{href}
|
{href}
|
||||||
{...restProps}
|
{...restProps}>
|
||||||
>
|
|
||||||
{@render children?.()}
|
{@render children?.()}
|
||||||
</a>
|
</a>
|
||||||
{:else}
|
{:else}
|
||||||
@@ -68,8 +72,7 @@
|
|||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
class={cn(buttonVariants({ variant, size, className }))}
|
class={cn(buttonVariants({ variant, size, className }))}
|
||||||
{type}
|
{type}
|
||||||
{...restProps}
|
{...restProps}>
|
||||||
>
|
|
||||||
{@render children?.()}
|
{@render children?.()}
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -1,20 +1,23 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { DropdownMenu as DropdownMenuPrimitive, type WithoutChildrenOrChild } from 'bits-ui';
|
import {
|
||||||
import Check from 'lucide-svelte/icons/check';
|
DropdownMenu as DropdownMenuPrimitive,
|
||||||
import Minus from 'lucide-svelte/icons/minus';
|
type WithoutChildrenOrChild
|
||||||
import { cn } from '$lib/utils/utils.js';
|
} from 'bits-ui';
|
||||||
import type { Snippet } from 'svelte';
|
import Check from 'lucide-svelte/icons/check';
|
||||||
|
import Minus from 'lucide-svelte/icons/minus';
|
||||||
|
import { cn } from '$lib/utils/utils.js';
|
||||||
|
import type { Snippet } from 'svelte';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
checked = $bindable(false),
|
checked = $bindable(false),
|
||||||
indeterminate = $bindable(false),
|
indeterminate = $bindable(false),
|
||||||
class: className,
|
class: className,
|
||||||
children: childrenProp,
|
children: childrenProp,
|
||||||
...restProps
|
...restProps
|
||||||
}: WithoutChildrenOrChild<DropdownMenuPrimitive.CheckboxItemProps> & {
|
}: WithoutChildrenOrChild<DropdownMenuPrimitive.CheckboxItemProps> & {
|
||||||
children?: Snippet;
|
children?: Snippet;
|
||||||
} = $props();
|
} = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<DropdownMenuPrimitive.CheckboxItem
|
<DropdownMenuPrimitive.CheckboxItem
|
||||||
@@ -22,11 +25,10 @@
|
|||||||
bind:checked
|
bind:checked
|
||||||
bind:indeterminate
|
bind:indeterminate
|
||||||
class={cn(
|
class={cn(
|
||||||
'data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-hidden data-disabled:pointer-events-none data-disabled:opacity-50',
|
'data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground relative flex cursor-default items-center rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50',
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...restProps}
|
{...restProps}>
|
||||||
>
|
|
||||||
{#snippet children({ checked, indeterminate })}
|
{#snippet children({ checked, indeterminate })}
|
||||||
<span class="absolute left-2 flex size-3.5 items-center justify-center">
|
<span class="absolute left-2 flex size-3.5 items-center justify-center">
|
||||||
{#if indeterminate}
|
{#if indeterminate}
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { cn } from '$lib/utils/utils.js';
|
import { cn } from '$lib/utils/utils.js';
|
||||||
import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui';
|
import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
sideOffset = 4,
|
sideOffset = 4,
|
||||||
portalProps,
|
portalProps,
|
||||||
class: className,
|
class: className,
|
||||||
...restProps
|
...restProps
|
||||||
}: DropdownMenuPrimitive.ContentProps & {
|
}: DropdownMenuPrimitive.ContentProps & {
|
||||||
portalProps?: DropdownMenuPrimitive.PortalProps;
|
portalProps?: DropdownMenuPrimitive.PortalProps;
|
||||||
} = $props();
|
} = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<DropdownMenuPrimitive.Portal {...portalProps}>
|
<DropdownMenuPrimitive.Portal {...portalProps}>
|
||||||
@@ -21,6 +21,5 @@
|
|||||||
'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-32 overflow-hidden rounded-md border p-1 shadow-md outline-hidden',
|
'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-32 overflow-hidden rounded-md border p-1 shadow-md outline-hidden',
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...restProps}
|
{...restProps} />
|
||||||
/>
|
|
||||||
</DropdownMenuPrimitive.Portal>
|
</DropdownMenuPrimitive.Portal>
|
||||||
|
|||||||
@@ -1,19 +1,18 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui';
|
import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui';
|
||||||
import { cn } from '$lib/utils/utils.js';
|
import { cn } from '$lib/utils/utils.js';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
class: className,
|
class: className,
|
||||||
inset,
|
inset,
|
||||||
...restProps
|
...restProps
|
||||||
}: DropdownMenuPrimitive.GroupHeadingProps & {
|
}: DropdownMenuPrimitive.GroupHeadingProps & {
|
||||||
inset?: boolean;
|
inset?: boolean;
|
||||||
} = $props();
|
} = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<DropdownMenuPrimitive.GroupHeading
|
<DropdownMenuPrimitive.GroupHeading
|
||||||
bind:ref
|
bind:ref
|
||||||
class={cn('px-2 py-1.5 text-sm font-semibold', inset && 'pl-8', className)}
|
class={cn('px-2 py-1.5 text-sm font-semibold', inset && 'pl-8', className)}
|
||||||
{...restProps}
|
{...restProps} />
|
||||||
/>
|
|
||||||
|
|||||||
@@ -1,23 +1,22 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { cn } from '$lib/utils/utils.js';
|
import { cn } from '$lib/utils/utils.js';
|
||||||
import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui';
|
import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
class: className,
|
class: className,
|
||||||
inset,
|
inset,
|
||||||
...restProps
|
...restProps
|
||||||
}: DropdownMenuPrimitive.ItemProps & {
|
}: DropdownMenuPrimitive.ItemProps & {
|
||||||
inset?: boolean;
|
inset?: boolean;
|
||||||
} = $props();
|
} = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<DropdownMenuPrimitive.Item
|
<DropdownMenuPrimitive.Item
|
||||||
bind:ref
|
bind:ref
|
||||||
class={cn(
|
class={cn(
|
||||||
'data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden transition-colors data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
|
'data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden transition-colors select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
|
||||||
inset && 'pl-8',
|
inset && 'pl-8',
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...restProps}
|
{...restProps} />
|
||||||
/>
|
|
||||||
|
|||||||
@@ -1,23 +1,22 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { cn } from '$lib/utils/utils.js';
|
import { cn } from '$lib/utils/utils.js';
|
||||||
import { type WithElementRef } from 'bits-ui';
|
import { type WithElementRef } from 'bits-ui';
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from 'svelte/elements';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
class: className,
|
class: className,
|
||||||
inset,
|
inset,
|
||||||
children,
|
children,
|
||||||
...restProps
|
...restProps
|
||||||
}: WithElementRef<HTMLAttributes<HTMLDivElement>> & {
|
}: WithElementRef<HTMLAttributes<HTMLDivElement>> & {
|
||||||
inset?: boolean;
|
inset?: boolean;
|
||||||
} = $props();
|
} = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
class={cn('px-2 py-1.5 text-sm font-semibold', inset && 'pl-8', className)}
|
class={cn('px-2 py-1.5 text-sm font-semibold', inset && 'pl-8', className)}
|
||||||
{...restProps}
|
{...restProps}>
|
||||||
>
|
|
||||||
{@render children?.()}
|
{@render children?.()}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,24 +1,26 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { DropdownMenu as DropdownMenuPrimitive, type WithoutChild } from 'bits-ui';
|
import {
|
||||||
import Circle from 'lucide-svelte/icons/circle';
|
DropdownMenu as DropdownMenuPrimitive,
|
||||||
import { cn } from '$lib/utils/utils.js';
|
type WithoutChild
|
||||||
|
} from 'bits-ui';
|
||||||
|
import Circle from 'lucide-svelte/icons/circle';
|
||||||
|
import { cn } from '$lib/utils/utils.js';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
class: className,
|
class: className,
|
||||||
children: childrenProp,
|
children: childrenProp,
|
||||||
...restProps
|
...restProps
|
||||||
}: WithoutChild<DropdownMenuPrimitive.RadioItemProps> = $props();
|
}: WithoutChild<DropdownMenuPrimitive.RadioItemProps> = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<DropdownMenuPrimitive.RadioItem
|
<DropdownMenuPrimitive.RadioItem
|
||||||
bind:ref
|
bind:ref
|
||||||
class={cn(
|
class={cn(
|
||||||
'data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-hidden data-disabled:pointer-events-none data-disabled:opacity-50',
|
'data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground relative flex cursor-default items-center rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50',
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...restProps}
|
{...restProps}>
|
||||||
>
|
|
||||||
{#snippet children({ checked })}
|
{#snippet children({ checked })}
|
||||||
<span class="absolute left-2 flex size-3.5 items-center justify-center">
|
<span class="absolute left-2 flex size-3.5 items-center justify-center">
|
||||||
{#if checked}
|
{#if checked}
|
||||||
|
|||||||
@@ -1,16 +1,15 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui';
|
import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui';
|
||||||
import { cn } from '$lib/utils/utils.js';
|
import { cn } from '$lib/utils/utils.js';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
class: className,
|
class: className,
|
||||||
...restProps
|
...restProps
|
||||||
}: DropdownMenuPrimitive.SeparatorProps = $props();
|
}: DropdownMenuPrimitive.SeparatorProps = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<DropdownMenuPrimitive.Separator
|
<DropdownMenuPrimitive.Separator
|
||||||
bind:ref
|
bind:ref
|
||||||
class={cn('bg-muted -mx-1 my-1 h-px', className)}
|
class={cn('bg-muted -mx-1 my-1 h-px', className)}
|
||||||
{...restProps}
|
{...restProps} />
|
||||||
/>
|
|
||||||
|
|||||||
@@ -1,20 +1,19 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from 'svelte/elements';
|
||||||
import { type WithElementRef } from 'bits-ui';
|
import { type WithElementRef } from 'bits-ui';
|
||||||
import { cn } from '$lib/utils/utils.js';
|
import { cn } from '$lib/utils/utils.js';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
class: className,
|
class: className,
|
||||||
children,
|
children,
|
||||||
...restProps
|
...restProps
|
||||||
}: WithElementRef<HTMLAttributes<HTMLSpanElement>> = $props();
|
}: WithElementRef<HTMLAttributes<HTMLSpanElement>> = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<span
|
<span
|
||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
class={cn('ml-auto text-xs tracking-widest opacity-60', className)}
|
class={cn('ml-auto text-xs tracking-widest opacity-60', className)}
|
||||||
{...restProps}
|
{...restProps}>
|
||||||
>
|
|
||||||
{@render children?.()}
|
{@render children?.()}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user