@variamosple/variamos-components 0.2.3 → 0.2.5
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/Components/AuthWrapper/addressWithoutToken.d.ts +9 -0
- package/dist/Components/AuthWrapper/addressWithoutToken.js +7 -0
- package/dist/Components/AuthWrapper/index.js +18 -17
- package/dist/Components/Notifications/NotificationSettings.js +36 -44
- package/dist/Components/Notifications/mutedEventTypes.d.ts +16 -0
- package/dist/Components/Notifications/mutedEventTypes.js +22 -0
- package/package.json +9 -4
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The address without its authToken parameter, or null when it has none.
|
|
3
|
+
*
|
|
4
|
+
* The token is never read from an address: a link could otherwise force a
|
|
5
|
+
* session chosen by someone else (session fixation). The session lives in
|
|
6
|
+
* the httpOnly cookie set by the admin; a token left by an older link is
|
|
7
|
+
* only removed from the address bar and the history.
|
|
8
|
+
*/
|
|
9
|
+
export declare const addressWithoutToken: (href: string) => string | null;
|
|
@@ -1,36 +1,37 @@
|
|
|
1
|
-
import { jsx as o, Fragment as
|
|
2
|
-
import
|
|
3
|
-
import { Spinner as
|
|
1
|
+
import { jsx as o, Fragment as f } from "react/jsx-runtime";
|
|
2
|
+
import p, { useEffect as m } from "react";
|
|
3
|
+
import { Spinner as h } from "react-bootstrap";
|
|
4
4
|
import "../../Context/AnalyticsContext.js";
|
|
5
5
|
import "../../Context/MenuContext.js";
|
|
6
|
-
import { useRouter as
|
|
7
|
-
import { useSession as
|
|
6
|
+
import { useRouter as u } from "../../Context/RouterContext.js";
|
|
7
|
+
import { useSession as g } from "../../Context/SessionContext.js";
|
|
8
8
|
import "../../Context/NotificationContext.js";
|
|
9
|
-
|
|
9
|
+
import { addressWithoutToken as l } from "./addressWithoutToken.js";
|
|
10
|
+
const j = ({
|
|
10
11
|
redirectPath: i,
|
|
11
12
|
children: c
|
|
12
13
|
}) => {
|
|
13
|
-
const [
|
|
14
|
+
const [n, d] = p.useState(!1), { isAuthenticated: t, isLoading: r } = g(), { navigate: s } = u();
|
|
14
15
|
return m(() => {
|
|
15
|
-
if (!r && !t && !
|
|
16
|
-
const e = window.location.href,
|
|
17
|
-
|
|
18
|
-
() =>
|
|
16
|
+
if (!r && !t && !n) {
|
|
17
|
+
const e = window.location.href, a = new URLSearchParams();
|
|
18
|
+
a.set("redirectTo", encodeURIComponent(e)), d(!0), setTimeout(
|
|
19
|
+
() => s(`${i}?${a.toString()}`),
|
|
19
20
|
300
|
|
20
21
|
);
|
|
21
22
|
}
|
|
22
|
-
}, [t, r, i,
|
|
23
|
-
const e =
|
|
24
|
-
e
|
|
23
|
+
}, [t, r, i, s, n]), m(() => {
|
|
24
|
+
const e = l(window.location.href);
|
|
25
|
+
e && window.history.replaceState({}, "", e);
|
|
25
26
|
}, []), r || !t ? /* @__PURE__ */ o("div", { className: "d-flex justify-content-center align-items-center w-100 h-100", children: /* @__PURE__ */ o(
|
|
26
|
-
|
|
27
|
+
h,
|
|
27
28
|
{
|
|
28
29
|
animation: "border",
|
|
29
30
|
variant: "primary",
|
|
30
31
|
style: { width: "3rem", height: "3rem", borderWidth: "0.5rem" }
|
|
31
32
|
}
|
|
32
|
-
) }) : /* @__PURE__ */ o(
|
|
33
|
+
) }) : /* @__PURE__ */ o(f, { children: c });
|
|
33
34
|
};
|
|
34
35
|
export {
|
|
35
|
-
|
|
36
|
+
j as AuthWrapper
|
|
36
37
|
};
|
|
@@ -1,68 +1,60 @@
|
|
|
1
|
-
import { jsx as
|
|
2
|
-
import { Spinner as
|
|
3
|
-
import { useNotifications as
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
import { jsx as e, jsxs as o } from "react/jsx-runtime";
|
|
2
|
+
import { Spinner as m, Alert as h, Card as s, Form as a } from "react-bootstrap";
|
|
3
|
+
import { useNotifications as p } from "../../Context/NotificationContext.js";
|
|
4
|
+
import { MUTABLE_EVENT_TYPES as u, isEventMuted as b, toggleMuted as f } from "./mutedEventTypes.js";
|
|
5
|
+
const k = () => {
|
|
6
|
+
const { preferences: t, updatePreferences: i, isLoading: c } = p(), r = (n) => {
|
|
7
|
+
t && i({ [n]: !t[n] });
|
|
8
|
+
}, l = (n) => {
|
|
9
|
+
t && i({
|
|
10
|
+
mutedEventTypes: f(t.mutedEventTypes, n)
|
|
11
|
+
});
|
|
11
12
|
};
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
{ key: "review_assigned", label: "Review Assignments (Relectures)" },
|
|
18
|
-
{ key: "project_created", label: "Project Creations" },
|
|
19
|
-
{ key: "system_alert", label: "System Alerts" }
|
|
20
|
-
];
|
|
21
|
-
return /* @__PURE__ */ t(c, { className: "border-0 shadow-sm", children: /* @__PURE__ */ l(c.Body, { className: "p-3", children: [
|
|
22
|
-
/* @__PURE__ */ t("h6", { className: "mb-3 text-secondary font-weight-bold", children: "Notification Channels" }),
|
|
23
|
-
/* @__PURE__ */ l(s.Group, { className: "mb-3", children: [
|
|
24
|
-
/* @__PURE__ */ t(
|
|
25
|
-
s.Check,
|
|
13
|
+
return c && !t ? /* @__PURE__ */ e("div", { className: "text-center py-4", children: /* @__PURE__ */ e(m, { animation: "border", size: "sm" }) }) : t ? /* @__PURE__ */ e(s, { className: "border-0 shadow-sm", children: /* @__PURE__ */ o(s.Body, { className: "p-3", children: [
|
|
14
|
+
/* @__PURE__ */ e("h6", { className: "mb-3 text-secondary font-weight-bold", children: "Notification Channels" }),
|
|
15
|
+
/* @__PURE__ */ o(a.Group, { className: "mb-3", children: [
|
|
16
|
+
/* @__PURE__ */ e(
|
|
17
|
+
a.Check,
|
|
26
18
|
{
|
|
27
19
|
type: "switch",
|
|
28
20
|
id: "channel-inapp",
|
|
29
21
|
label: "In-App Notifications (Real-Time)",
|
|
30
|
-
checked:
|
|
31
|
-
onChange: () =>
|
|
22
|
+
checked: t.inAppEnabled,
|
|
23
|
+
onChange: () => r("inAppEnabled"),
|
|
32
24
|
className: "mb-2"
|
|
33
25
|
}
|
|
34
26
|
),
|
|
35
|
-
/* @__PURE__ */
|
|
36
|
-
|
|
27
|
+
/* @__PURE__ */ e(
|
|
28
|
+
a.Check,
|
|
37
29
|
{
|
|
38
30
|
type: "switch",
|
|
39
31
|
id: "channel-email",
|
|
40
32
|
label: "Email Alerts",
|
|
41
|
-
checked:
|
|
42
|
-
onChange: () =>
|
|
33
|
+
checked: t.emailEnabled,
|
|
34
|
+
onChange: () => r("emailEnabled")
|
|
43
35
|
}
|
|
44
36
|
)
|
|
45
37
|
] }),
|
|
46
|
-
/* @__PURE__ */
|
|
47
|
-
/* @__PURE__ */
|
|
48
|
-
/* @__PURE__ */
|
|
49
|
-
/* @__PURE__ */
|
|
50
|
-
const
|
|
51
|
-
return /* @__PURE__ */
|
|
52
|
-
|
|
38
|
+
/* @__PURE__ */ e("hr", {}),
|
|
39
|
+
/* @__PURE__ */ e("h6", { className: "mb-3 text-secondary font-weight-bold", children: "Mute Event Types" }),
|
|
40
|
+
/* @__PURE__ */ e("p", { className: "text-muted small mb-3", children: "Check events you do NOT want to receive notifications for." }),
|
|
41
|
+
/* @__PURE__ */ e(a.Group, { children: u.map((n) => {
|
|
42
|
+
const d = b(t.mutedEventTypes, n.key);
|
|
43
|
+
return /* @__PURE__ */ e(
|
|
44
|
+
a.Check,
|
|
53
45
|
{
|
|
54
46
|
type: "checkbox",
|
|
55
|
-
id: `mute-${
|
|
56
|
-
label:
|
|
57
|
-
checked:
|
|
58
|
-
onChange: () =>
|
|
47
|
+
id: `mute-${n.key}`,
|
|
48
|
+
label: n.label,
|
|
49
|
+
checked: d,
|
|
50
|
+
onChange: () => l(n.key),
|
|
59
51
|
className: "mb-2 text-dark"
|
|
60
52
|
},
|
|
61
|
-
|
|
53
|
+
n.key
|
|
62
54
|
);
|
|
63
55
|
}) })
|
|
64
|
-
] }) });
|
|
56
|
+
] }) }) : /* @__PURE__ */ e(h, { variant: "warning", children: "Unable to load notification preferences." });
|
|
65
57
|
};
|
|
66
58
|
export {
|
|
67
|
-
|
|
59
|
+
k as NotificationSettings
|
|
68
60
|
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The event types a user can mute, by the template key the services send.
|
|
3
|
+
* The security alerts of the administration are mandatory: the
|
|
4
|
+
* notification service delivers them whatever is muted here (EV-99).
|
|
5
|
+
*/
|
|
6
|
+
export declare const MUTABLE_EVENT_TYPES: {
|
|
7
|
+
key: string;
|
|
8
|
+
label: string;
|
|
9
|
+
}[];
|
|
10
|
+
/** True when the event type is muted, under its key or a former one. */
|
|
11
|
+
export declare function isEventMuted(muted: readonly string[], key: string): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* The muted list once the event type is toggled. Its former keys are
|
|
14
|
+
* dropped either way, so that the list keeps the current key only.
|
|
15
|
+
*/
|
|
16
|
+
export declare function toggleMuted(muted: readonly string[], key: string): string[];
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const c = [
|
|
2
|
+
{ key: "review_assigned", label: "Review Assignments (Relectures)" },
|
|
3
|
+
{ key: "project_created", label: "Project Creations" },
|
|
4
|
+
{
|
|
5
|
+
key: "admin_alert",
|
|
6
|
+
label: "System Alerts (security alerts are always delivered)"
|
|
7
|
+
}
|
|
8
|
+
], a = {
|
|
9
|
+
admin_alert: ["system_alert"]
|
|
10
|
+
}, n = (e) => [e, ...a[e] ?? []];
|
|
11
|
+
function i(e, t) {
|
|
12
|
+
return n(t).some((s) => e.includes(s));
|
|
13
|
+
}
|
|
14
|
+
function o(e, t) {
|
|
15
|
+
const s = n(t), r = e.filter((l) => !s.includes(l));
|
|
16
|
+
return i(e, t) ? r : [...r, t];
|
|
17
|
+
}
|
|
18
|
+
export {
|
|
19
|
+
c as MUTABLE_EVENT_TYPES,
|
|
20
|
+
i as isEventMuted,
|
|
21
|
+
o as toggleMuted
|
|
22
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@variamosple/variamos-components",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.5",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/main.js",
|
|
7
7
|
"types": "dist/main.d.ts",
|
|
@@ -38,16 +38,21 @@
|
|
|
38
38
|
"eslint": "^9.19.0",
|
|
39
39
|
"eslint-plugin-react-hooks": "^5.0.0",
|
|
40
40
|
"eslint-plugin-react-refresh": "^0.4.18",
|
|
41
|
-
"glob": "^
|
|
41
|
+
"glob": "^14.0.4",
|
|
42
42
|
"globals": "^15.14.0",
|
|
43
43
|
"react": "^19.2.8",
|
|
44
44
|
"react-dom": "^19.2.8",
|
|
45
45
|
"typescript": "~5.7.2",
|
|
46
46
|
"typescript-eslint": "^8.22.0",
|
|
47
|
-
"vite": "^6.
|
|
47
|
+
"vite": "^6.4.5",
|
|
48
48
|
"vite-plugin-dts": "^5.1.2",
|
|
49
49
|
"vite-plugin-lib-inject-css": "^2.2.1",
|
|
50
|
-
"vitest": "^4.1.
|
|
50
|
+
"vitest": "^4.1.12"
|
|
51
|
+
},
|
|
52
|
+
"overrides": {
|
|
53
|
+
"@typescript-eslint/typescript-estree": {
|
|
54
|
+
"minimatch": "^11.0.1"
|
|
55
|
+
}
|
|
51
56
|
},
|
|
52
57
|
"allowScripts": {
|
|
53
58
|
"esbuild@0.25.12": true
|