elbe-ui 0.2.30 → 0.2.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bit/bit.d.ts +34 -0
- package/dist/bit/bit.js +83 -0
- package/dist/bit/ctrl_bit.d.ts +30 -0
- package/dist/bit/ctrl_bit.js +89 -0
- package/dist/elbe.css.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/service/s_api.d.ts +30 -0
- package/dist/service/s_api.js +89 -0
- package/dist/ui/components/badge.d.ts +25 -0
- package/dist/ui/components/badge.js +53 -0
- package/dist/ui/components/base/box.d.ts +2564 -0
- package/dist/ui/components/base/box.js +30 -0
- package/dist/ui/components/base/card.d.ts +14 -0
- package/dist/ui/components/base/card.js +11 -0
- package/dist/ui/components/base/padded.d.ts +25 -0
- package/dist/ui/components/base/padded.js +28 -0
- package/dist/ui/components/button/button.d.ts +21 -0
- package/dist/ui/components/button/button.js +27 -0
- package/dist/ui/components/button/choose_button.d.ts +14 -0
- package/dist/ui/components/button/choose_button.js +11 -0
- package/dist/ui/components/button/icon_button.d.ts +17 -0
- package/dist/ui/components/button/icon_button.js +31 -0
- package/dist/ui/components/button/toggle_button.d.ts +10 -0
- package/dist/ui/components/button/toggle_button.js +11 -0
- package/dist/ui/components/dialog.d.ts +8 -0
- package/dist/ui/components/dialog.js +14 -0
- package/dist/ui/components/error_view.d.ts +15 -0
- package/dist/ui/components/error_view.js +26 -0
- package/dist/ui/components/input/checkbox.d.ts +6 -0
- package/dist/ui/components/input/checkbox.js +12 -0
- package/dist/ui/components/input/input_field.d.ts +22 -0
- package/dist/ui/components/input/input_field.js +31 -0
- package/dist/ui/components/input/range.d.ts +8 -0
- package/dist/ui/components/input/range.js +14 -0
- package/dist/ui/components/input/select.d.ts +10 -0
- package/dist/ui/components/input/select.js +8 -0
- package/dist/ui/components/input/text_area.d.ts +10 -0
- package/dist/ui/components/input/text_area.js +13 -0
- package/dist/ui/components/layout/flex.d.ts +11 -0
- package/dist/ui/components/layout/flex.js +23 -0
- package/dist/ui/components/layout/scaffold.d.ts +27 -0
- package/dist/ui/components/layout/scaffold.js +44 -0
- package/dist/ui/components/layout/scroll.d.ts +18 -0
- package/dist/ui/components/layout/scroll.js +20 -0
- package/dist/ui/components/layout/spaced.d.ts +3 -0
- package/dist/ui/components/layout/spaced.js +7 -0
- package/dist/ui/components/spinner.d.ts +11 -0
- package/dist/ui/components/spinner.js +48 -0
- package/dist/ui/components/text.d.ts +33 -0
- package/dist/ui/components/text.js +42 -0
- package/dist/ui/theme/color_theme.d.ts +2 -0
- package/dist/ui/theme/color_theme.js +63 -0
- package/dist/ui/theme/colors.d.ts +142 -0
- package/dist/ui/theme/colors.js +317 -0
- package/dist/ui/theme/geometry_theme.d.ts +16 -0
- package/dist/ui/theme/geometry_theme.js +38 -0
- package/dist/ui/theme/theme.d.ts +28 -0
- package/dist/ui/theme/theme.js +49 -0
- package/dist/ui/theme/type_theme.d.ts +38 -0
- package/dist/ui/theme/type_theme.js +98 -0
- package/dist/ui/util/confirm_dialog.d.ts +10 -0
- package/dist/ui/util/confirm_dialog.js +46 -0
- package/dist/ui/util/error_view.d.ts +1 -0
- package/dist/ui/util/error_view.js +8 -0
- package/dist/ui/util/toast.d.ts +5 -0
- package/dist/ui/util/toast.js +17 -0
- package/dist/ui/util/util.d.ts +21 -0
- package/dist/ui/util/util.js +39 -0
- package/package.json +2 -5
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Signal } from "@preact/signals";
|
|
2
|
+
import { type PreactContext } from "preact";
|
|
3
|
+
export interface BitUseInterface<C, T> {
|
|
4
|
+
signal: Signal<BitState<T>>;
|
|
5
|
+
ctrl: C;
|
|
6
|
+
map: <D>(m: TriMap<T, D>) => D | preact.JSX.Element;
|
|
7
|
+
onData: (f: (d: T) => any) => any;
|
|
8
|
+
}
|
|
9
|
+
interface BitData<C, T> {
|
|
10
|
+
ctrl: C;
|
|
11
|
+
state: Signal<BitState<T>>;
|
|
12
|
+
}
|
|
13
|
+
export interface BitState<T> {
|
|
14
|
+
loading?: boolean;
|
|
15
|
+
error?: any;
|
|
16
|
+
data?: T;
|
|
17
|
+
}
|
|
18
|
+
export type BitContext<T, C> = PreactContext<BitData<T, C> | null>;
|
|
19
|
+
export interface TriMap<T, D> {
|
|
20
|
+
onLoading?: () => D;
|
|
21
|
+
onError?: (e: string) => D;
|
|
22
|
+
onData?: (value: T) => D;
|
|
23
|
+
}
|
|
24
|
+
export interface TWParams<T> {
|
|
25
|
+
emit: (t: T) => void;
|
|
26
|
+
emitLoading: () => void;
|
|
27
|
+
emitError: (e: any) => void;
|
|
28
|
+
map: <D>(m: TriMap<T, D>) => D;
|
|
29
|
+
signal: Signal<BitState<T>>;
|
|
30
|
+
}
|
|
31
|
+
export declare function makeBit<C, T>(name: string): BitContext<C, T>;
|
|
32
|
+
export declare function ProvideBit<I, C, T>(context: BitContext<C, T>, parameters: I, worker: (p: I, d: TWParams<T>, ctrl: C) => void, ctrl: (p: I, d: TWParams<T>) => C, children: any): import("preact").JSX.Element;
|
|
33
|
+
export declare function useBit<C, T>(context: BitContext<C, T>): BitUseInterface<C, T>;
|
|
34
|
+
export {};
|
package/dist/bit/bit.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.makeBit = makeBit;
|
|
4
|
+
exports.ProvideBit = ProvideBit;
|
|
5
|
+
exports.useBit = useBit;
|
|
6
|
+
const jsx_runtime_1 = require("preact/jsx-runtime");
|
|
7
|
+
const signals_1 = require("@preact/signals");
|
|
8
|
+
const preact_1 = require("preact");
|
|
9
|
+
const hooks_1 = require("preact/hooks");
|
|
10
|
+
const error_view_1 = require("../ui/components/error_view");
|
|
11
|
+
const spinner_1 = require("../ui/components/spinner");
|
|
12
|
+
function makeBit(name) {
|
|
13
|
+
const c = (0, preact_1.createContext)(null);
|
|
14
|
+
c.displayName = name;
|
|
15
|
+
return c;
|
|
16
|
+
}
|
|
17
|
+
function ProvideBit(context, parameters, worker, ctrl, children) {
|
|
18
|
+
const s = (0, signals_1.useSignal)({ loading: true });
|
|
19
|
+
const _set = (n) => {
|
|
20
|
+
try {
|
|
21
|
+
if (JSON.stringify(n) === JSON.stringify(s.peek()))
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
catch (e) { }
|
|
25
|
+
s.value = n;
|
|
26
|
+
};
|
|
27
|
+
const emit = (data) => _set({ data });
|
|
28
|
+
const emitLoading = () => _set({ loading: true });
|
|
29
|
+
const emitError = (error) => {
|
|
30
|
+
console.warn(`BIT: ${context.displayName} emitted ERROR`, error);
|
|
31
|
+
return _set({ error });
|
|
32
|
+
};
|
|
33
|
+
function map(m) {
|
|
34
|
+
const st = s.value;
|
|
35
|
+
if (st.loading)
|
|
36
|
+
return m.onLoading();
|
|
37
|
+
if (st.error)
|
|
38
|
+
return m.onError(st.error);
|
|
39
|
+
return m.onData(st.data ?? null);
|
|
40
|
+
}
|
|
41
|
+
const c = ctrl(parameters, { emit, emitLoading, emitError, map, signal: s });
|
|
42
|
+
worker(parameters, { emit, emitLoading, emitError, map, signal: s }, c);
|
|
43
|
+
return ((0, jsx_runtime_1.jsx)(context.Provider, { value: { ctrl: c, state: s }, children: children }));
|
|
44
|
+
}
|
|
45
|
+
function useBit(context) {
|
|
46
|
+
try {
|
|
47
|
+
const { ctrl, state } = (0, hooks_1.useContext)(context);
|
|
48
|
+
const v = state.value;
|
|
49
|
+
function map(m) {
|
|
50
|
+
if (v.loading)
|
|
51
|
+
return (m.onLoading || (() => (0, jsx_runtime_1.jsx)(spinner_1.Spinner, {})))();
|
|
52
|
+
if (v.error)
|
|
53
|
+
return (m.onError ||
|
|
54
|
+
((e) => (0, jsx_runtime_1.jsx)(error_view_1.ErrorView, { error: e, retry: ctrl.reload ?? null })))(v.error);
|
|
55
|
+
return m.onData(v.data ?? null);
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
signal: state,
|
|
59
|
+
ctrl,
|
|
60
|
+
map,
|
|
61
|
+
/**
|
|
62
|
+
* this is a quality of life function that allows
|
|
63
|
+
* you to chain the map function with the onData function
|
|
64
|
+
* @param f the builder function
|
|
65
|
+
* @returns the built component
|
|
66
|
+
*/
|
|
67
|
+
onData: (f) => map({ onData: f }),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
catch (e) {
|
|
71
|
+
const err = `BIT ERROR: NO ${context.displayName} PROVIDED`;
|
|
72
|
+
console.error(err, e);
|
|
73
|
+
return {
|
|
74
|
+
map: (_) => (0, jsx_runtime_1.jsx)("div", { children: err }),
|
|
75
|
+
ctrl: null,
|
|
76
|
+
signal: null,
|
|
77
|
+
onData: () => (0, jsx_runtime_1.jsx)("div", { children: err }),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function BitSpinner({ name }) {
|
|
82
|
+
return (0, jsx_runtime_1.jsx)(spinner_1.Spinner, {});
|
|
83
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { JSX } from "preact/jsx-runtime";
|
|
2
|
+
import type { BitUseInterface, TWParams } from "./bit";
|
|
3
|
+
declare abstract class BitControl<I, DT> {
|
|
4
|
+
p: I;
|
|
5
|
+
bit: TWParams<DT>;
|
|
6
|
+
constructor(p: I, bit: TWParams<DT>);
|
|
7
|
+
act(fn: (b: DT) => Promise<void>): void;
|
|
8
|
+
/**
|
|
9
|
+
* Clean up resources. This is called once
|
|
10
|
+
* the element is removed from the DOM.
|
|
11
|
+
*/
|
|
12
|
+
dispose(): void;
|
|
13
|
+
}
|
|
14
|
+
export declare abstract class WorkerControl<I, DT> extends BitControl<I, DT> {
|
|
15
|
+
reload: (() => Promise<void>) | null;
|
|
16
|
+
abstract worker(): Promise<DT>;
|
|
17
|
+
}
|
|
18
|
+
export declare abstract class StreamControl<I, DT, Stream> extends BitControl<I, DT> {
|
|
19
|
+
protected stream: Stream | null;
|
|
20
|
+
abstract listen(): Stream;
|
|
21
|
+
dispose(): void;
|
|
22
|
+
abstract disposeStream(stream: Stream): void;
|
|
23
|
+
}
|
|
24
|
+
export declare function CtrlBit<I, DT, C extends BitControl<I, DT>>(ctrl: (p: I, d: TWParams<DT>) => C, name?: string): {
|
|
25
|
+
Provide: (props: I & {
|
|
26
|
+
children: React.ReactNode;
|
|
27
|
+
}) => JSX.Element;
|
|
28
|
+
use: () => BitUseInterface<C, DT>;
|
|
29
|
+
};
|
|
30
|
+
export {};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StreamControl = exports.WorkerControl = void 0;
|
|
4
|
+
exports.CtrlBit = CtrlBit;
|
|
5
|
+
const hooks_1 = require("preact/hooks");
|
|
6
|
+
const bit_1 = require("./bit");
|
|
7
|
+
class BitControl {
|
|
8
|
+
p;
|
|
9
|
+
bit;
|
|
10
|
+
constructor(p, bit) {
|
|
11
|
+
this.bit = bit;
|
|
12
|
+
this.p = p;
|
|
13
|
+
}
|
|
14
|
+
act(fn) {
|
|
15
|
+
this.bit.map({
|
|
16
|
+
onData: async (d) => {
|
|
17
|
+
try {
|
|
18
|
+
await fn(d);
|
|
19
|
+
}
|
|
20
|
+
catch (e) {
|
|
21
|
+
if (e && e.code && e.message)
|
|
22
|
+
console.error(`[BitERROR] act: ${e.code} (${e.message})`);
|
|
23
|
+
else
|
|
24
|
+
console.error("[BitERROR] act: ", e);
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Clean up resources. This is called once
|
|
31
|
+
* the element is removed from the DOM.
|
|
32
|
+
*/
|
|
33
|
+
dispose() { }
|
|
34
|
+
}
|
|
35
|
+
class WorkerControl extends BitControl {
|
|
36
|
+
reload = null;
|
|
37
|
+
}
|
|
38
|
+
exports.WorkerControl = WorkerControl;
|
|
39
|
+
class StreamControl extends BitControl {
|
|
40
|
+
stream = null;
|
|
41
|
+
dispose() {
|
|
42
|
+
if (this.stream)
|
|
43
|
+
this.disposeStream(this.stream);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
exports.StreamControl = StreamControl;
|
|
47
|
+
function make(name) {
|
|
48
|
+
return (0, bit_1.makeBit)(name);
|
|
49
|
+
}
|
|
50
|
+
function use(b) {
|
|
51
|
+
return (0, bit_1.useBit)(b);
|
|
52
|
+
}
|
|
53
|
+
function CtrlBit(ctrl, name) {
|
|
54
|
+
const context = make((name || "Unknown") + "Bit");
|
|
55
|
+
function Provide({ children, ...p }) {
|
|
56
|
+
return (0, bit_1.ProvideBit)(context, p, async (p, b, c) => {
|
|
57
|
+
b.emitLoading();
|
|
58
|
+
try {
|
|
59
|
+
if (c instanceof WorkerControl) {
|
|
60
|
+
if (c.reload)
|
|
61
|
+
await c.reload();
|
|
62
|
+
}
|
|
63
|
+
if (c instanceof StreamControl) {
|
|
64
|
+
c.stream = c.listen();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
catch (e) {
|
|
68
|
+
b.emitError(e);
|
|
69
|
+
}
|
|
70
|
+
}, (p, b) => {
|
|
71
|
+
const c = ctrl(p, b);
|
|
72
|
+
// clean up on unmount
|
|
73
|
+
(0, hooks_1.useEffect)(() => () => c.dispose(), []);
|
|
74
|
+
if (c instanceof WorkerControl) {
|
|
75
|
+
c.reload = async () => {
|
|
76
|
+
b.emitLoading();
|
|
77
|
+
try {
|
|
78
|
+
b.emit(await c.worker());
|
|
79
|
+
}
|
|
80
|
+
catch (e) {
|
|
81
|
+
b.emitError(e);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
return c;
|
|
86
|
+
}, children);
|
|
87
|
+
}
|
|
88
|
+
return { Provide: Provide, use: () => use(context) };
|
|
89
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sourceRoot":"","sources":["../style/elbe.scss","../style/_base.scss","../style/_flex.scss","../style/_components.scss"],"names":[],"mappings":"AAAA;AAAA;AAAA;AAAA;AAOQ;ACPR;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAEE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAIF;AAEA;EACE;;;AAEF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAEE;EACA;EACA;;;AAEF;EACE;;;AAGF;AAAA;EAEE;;;AAGF;EACE;;;AAEF;EACE;;;AAGF;EACE;EACA;;AACA;EACE;;;AAIJ;EACE;;;AAGF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAEE;EACA;;;AAKF;AAEA;EACE;;;AAGF;EAEE;EACA;EACA;;;AAGF;AAEA;AAAA;EAEE;;;AAEF;AAAA;AAAA;AAAA;EAEE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;EACA;;;AAGF;AAEA;EACE;EACA;EACA;EACA;;;AAGF;EACE;IACE;;EAEF;IACE;;;ACpJJ;AAAA;AAAA;AAAA;AAAA;EAGE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;AAEA;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAGF;AAEA;EACE;;;AAIA;EACE;;;AADF;EACE;;;AADF;EACE;;;AADF;EACE;;;AADF;EACE;;;AADF;EACE;;;AADF;EACE;;;AADF;EACE;;;AADF;EACE;;;AADF;EACE;;;AADF;EACE;;;AADF;EACE;;;AAIJ;AAEA;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAGF;AAEA;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAGF;AAEA;EACE;IACE;;EAEF;IACE;;;AAIJ;EACE;IACE;;;AAIJ;EACE;;;AC/GF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAIF;EAIE;EACA;EACA;EACA;EACA;EACA;EACA;AAMA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAJA;EACE;;;AAoBJ;EACE;EACA;EACA;;;AAGF;EAIE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EAGE;EACA;EACA;EACA;;;AAGF;EAKE;EAEA;EACA;EACA;EACA;EACA;EAEA;EAEA;EAEA;EAEA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;;AACA;EACE;;;AAKN;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EAGC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACC;EAGD;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;;;AAKD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAWE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EAEE;EACA;EACA;;AAGF;EAGE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAOJ;EACE;EACA;EACA;EAEA;EACA;EAEA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EAEA;EACA;EACA;;;AAIF;EACE;EACA;;AACA;EACE;EACA;;;AAMJ;EACE;EACA;;;AAGF;EACE;EACA;;;AH5PF;EACE;EACA;EACA;EACA;EAEA;EACA;EACA;EAGA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;;;AAGF;AAAA;AAAA;EAGE;EACA;EACA;EACA;EACA;;;AAGF;AAAA;EAEE;EACA;EACA;EACA","file":"elbe.css"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -29,6 +29,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
29
29
|
exports.Icons = void 0;
|
|
30
30
|
const jsx_runtime_1 = require("preact/jsx-runtime");
|
|
31
31
|
const Lucide = __importStar(require("lucide-react"));
|
|
32
|
+
require("./elbe.css");
|
|
32
33
|
// exports
|
|
33
34
|
__exportStar(require("./bit/bit"), exports);
|
|
34
35
|
__exportStar(require("./bit/ctrl_bit"), exports);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export interface PostArgs {
|
|
2
|
+
path?: {
|
|
3
|
+
[key: string]: string | number | boolean | undefined;
|
|
4
|
+
};
|
|
5
|
+
query?: {
|
|
6
|
+
[key: string]: string | number | boolean | undefined;
|
|
7
|
+
};
|
|
8
|
+
body?: any;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* ApiService is a simple wrapper around fetch that handles JSON serialization and error handling.
|
|
12
|
+
* to use it, you must first call `ApiService.init(apiURL)` with the base URL of your API.
|
|
13
|
+
*/
|
|
14
|
+
export declare class ApiService {
|
|
15
|
+
private apiURL;
|
|
16
|
+
private static _i;
|
|
17
|
+
static get i(): ApiService;
|
|
18
|
+
private constructor();
|
|
19
|
+
static init(apiURL: string): void;
|
|
20
|
+
private _fetch;
|
|
21
|
+
get(path: string, args?: PostArgs): Promise<any>;
|
|
22
|
+
post(path: string, args: PostArgs): Promise<any>;
|
|
23
|
+
delete(path: string, args: PostArgs): Promise<any>;
|
|
24
|
+
}
|
|
25
|
+
export interface ApiError {
|
|
26
|
+
code: number;
|
|
27
|
+
message: string;
|
|
28
|
+
data?: any;
|
|
29
|
+
}
|
|
30
|
+
export declare function ifApiError(e: any): ApiError | null;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ApiService = void 0;
|
|
4
|
+
exports.ifApiError = ifApiError;
|
|
5
|
+
const _noArgs = {};
|
|
6
|
+
/**
|
|
7
|
+
* ApiService is a simple wrapper around fetch that handles JSON serialization and error handling.
|
|
8
|
+
* to use it, you must first call `ApiService.init(apiURL)` with the base URL of your API.
|
|
9
|
+
*/
|
|
10
|
+
class ApiService {
|
|
11
|
+
apiURL;
|
|
12
|
+
static _i = null;
|
|
13
|
+
static get i() {
|
|
14
|
+
if (!ApiService._i)
|
|
15
|
+
throw "ApiService not initialized. Call ApiService.init(apiURL)";
|
|
16
|
+
return ApiService._i;
|
|
17
|
+
}
|
|
18
|
+
constructor(apiURL) {
|
|
19
|
+
this.apiURL = apiURL;
|
|
20
|
+
}
|
|
21
|
+
static init(apiURL) {
|
|
22
|
+
if (ApiService._i)
|
|
23
|
+
throw "ApiService already initialized";
|
|
24
|
+
ApiService._i = new ApiService(apiURL);
|
|
25
|
+
}
|
|
26
|
+
async _fetch(p, method, { path, query, body }) {
|
|
27
|
+
try {
|
|
28
|
+
p = path
|
|
29
|
+
? p.replace(/:([a-zA-Z0-9_]+)/g, (m, p1) => {
|
|
30
|
+
const v = path[p1];
|
|
31
|
+
if (v === undefined)
|
|
32
|
+
throw { code: 400, message: `missing parameter ${p1}` };
|
|
33
|
+
return v?.toString() ?? "";
|
|
34
|
+
})
|
|
35
|
+
: p;
|
|
36
|
+
const queryStr = query != null ? "?" + new URLSearchParams(query).toString() : "";
|
|
37
|
+
const response = await fetch(this.apiURL + p + queryStr, {
|
|
38
|
+
method,
|
|
39
|
+
credentials: "include",
|
|
40
|
+
headers: { "Content-Type": "application/json" },
|
|
41
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
42
|
+
});
|
|
43
|
+
if (response.ok) {
|
|
44
|
+
try {
|
|
45
|
+
return await response.json();
|
|
46
|
+
}
|
|
47
|
+
catch (e) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
let data = null;
|
|
52
|
+
try {
|
|
53
|
+
data = await response.clone().json();
|
|
54
|
+
}
|
|
55
|
+
catch (e) {
|
|
56
|
+
data = await response.text();
|
|
57
|
+
}
|
|
58
|
+
throw {
|
|
59
|
+
code: response.status,
|
|
60
|
+
message: data.message ?? "undefined error",
|
|
61
|
+
data,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
catch (e) {
|
|
65
|
+
rethrow(e, 0, "unknown error");
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
async get(path, args) {
|
|
69
|
+
return this._fetch(path, "GET", args || _noArgs);
|
|
70
|
+
}
|
|
71
|
+
async post(path, args) {
|
|
72
|
+
return this._fetch(path, "POST", args || _noArgs);
|
|
73
|
+
}
|
|
74
|
+
async delete(path, args) {
|
|
75
|
+
return this._fetch(path, "DELETE", args || _noArgs);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
exports.ApiService = ApiService;
|
|
79
|
+
function rethrow(e, code, message) {
|
|
80
|
+
// if e implements the apiError interface, rethrow it:
|
|
81
|
+
if (e && e.code !== null && e.message !== null)
|
|
82
|
+
throw e;
|
|
83
|
+
throw { code, message, data: e };
|
|
84
|
+
}
|
|
85
|
+
function ifApiError(e) {
|
|
86
|
+
if (e && e.code !== null && e.message !== null)
|
|
87
|
+
return e;
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import React from "preact/compat";
|
|
2
|
+
import type { ElbeColorKinds } from "../theme/colors";
|
|
3
|
+
import type { ElbeChild, ElbeChildren } from "../util/util";
|
|
4
|
+
import type { ElbeProps } from "./base/box";
|
|
5
|
+
export type BadgeProps = {
|
|
6
|
+
count?: number;
|
|
7
|
+
label?: string;
|
|
8
|
+
child?: ElbeChild;
|
|
9
|
+
hidden?: boolean;
|
|
10
|
+
children?: ElbeChildren;
|
|
11
|
+
} & ElbeProps;
|
|
12
|
+
export declare function TestBadge(p: BadgeProps): Badge;
|
|
13
|
+
export declare class Badge extends React.Component<BadgeProps & {
|
|
14
|
+
kind: ElbeColorKinds;
|
|
15
|
+
}> {
|
|
16
|
+
constructor(props: BadgeProps & {
|
|
17
|
+
kind: ElbeColorKinds;
|
|
18
|
+
});
|
|
19
|
+
static accent(p: BadgeProps): React.JSX.Element;
|
|
20
|
+
static error(p: BadgeProps): React.JSX.Element;
|
|
21
|
+
static warning(p: BadgeProps): React.JSX.Element;
|
|
22
|
+
static success(p: BadgeProps): React.JSX.Element;
|
|
23
|
+
static info(p: BadgeProps): React.JSX.Element;
|
|
24
|
+
render(): React.JSX.Element;
|
|
25
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.Badge = void 0;
|
|
7
|
+
exports.TestBadge = TestBadge;
|
|
8
|
+
const jsx_runtime_1 = require("preact/jsx-runtime");
|
|
9
|
+
const compat_1 = __importDefault(require("preact/compat"));
|
|
10
|
+
function TestBadge(p) {
|
|
11
|
+
return new Badge({ ...p, kind: "accent" });
|
|
12
|
+
}
|
|
13
|
+
class Badge extends compat_1.default.Component {
|
|
14
|
+
constructor(props) {
|
|
15
|
+
super(props);
|
|
16
|
+
}
|
|
17
|
+
static accent(p) {
|
|
18
|
+
return (0, jsx_runtime_1.jsx)(Badge, { ...p, kind: "accent" });
|
|
19
|
+
}
|
|
20
|
+
static error(p) {
|
|
21
|
+
return (0, jsx_runtime_1.jsx)(Badge, { ...p, kind: "error" });
|
|
22
|
+
}
|
|
23
|
+
static warning(p) {
|
|
24
|
+
return (0, jsx_runtime_1.jsx)(Badge, { ...p, kind: "warning" });
|
|
25
|
+
}
|
|
26
|
+
static success(p) {
|
|
27
|
+
return (0, jsx_runtime_1.jsx)(Badge, { ...p, kind: "success" });
|
|
28
|
+
}
|
|
29
|
+
static info(p) {
|
|
30
|
+
return (0, jsx_runtime_1.jsx)(Badge, { ...p, kind: "info" });
|
|
31
|
+
}
|
|
32
|
+
render() {
|
|
33
|
+
return ((0, jsx_runtime_1.jsxs)("div", { style: {
|
|
34
|
+
position: "relative",
|
|
35
|
+
display: "inline-block",
|
|
36
|
+
}, children: [this.props.child, this.props.children, (0, jsx_runtime_1.jsx)("div", { class: `b ${this.props.kind} major ${this.props.class ?? ""}`, style: {
|
|
37
|
+
position: "absolute",
|
|
38
|
+
top: "-0.25rem",
|
|
39
|
+
right: "-0.25rem",
|
|
40
|
+
minWidth: "1.5rem",
|
|
41
|
+
minHeight: "1.5rem",
|
|
42
|
+
padding: "0rem .4rem",
|
|
43
|
+
borderRadius: "3rem",
|
|
44
|
+
fontWeight: "bold",
|
|
45
|
+
display: "flex",
|
|
46
|
+
justifyContent: "center",
|
|
47
|
+
alignItems: "center",
|
|
48
|
+
visibility: this.props.hidden ? "hidden" : "visible",
|
|
49
|
+
...this.props.style,
|
|
50
|
+
}, children: this.props.label ?? this.props.count })] }));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
exports.Badge = Badge;
|