8seneca-app-launcher 0.1.3 → 0.1.4

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/index.d.ts CHANGED
@@ -2,6 +2,8 @@ import * as react from 'react';
2
2
  import { LucideIcon } from 'lucide-react';
3
3
 
4
4
  type AppId = "hrm" | "plane";
5
+ /** Deployment ring — decides which host each tile points at. */
6
+ type RingId = "prod" | "kc-test" | "sandbox";
5
7
  type AppTile = {
6
8
  id: AppId;
7
9
  name: string;
@@ -33,14 +35,20 @@ type PanelProps = {
33
35
  declare function LauncherPanel({ tiles, hostname, label, id }: PanelProps): react.JSX.Element;
34
36
 
35
37
  /**
36
- * The complete 8seneca app list. URLs live here on purpose: the apps' env
37
- * conventions diverge (NEXT_PUBLIC_* vs VITE_*), so baking them keeps every
38
- * consumer at zero configuration. Adding an app means publishing a version.
38
+ * One URL set per deployment ring. Baked in on purpose: the apps' env
39
+ * conventions diverge (NEXT_PUBLIC_* vs VITE_*), so this keeps every consumer
40
+ * at zero configuration. Adding a ring or moving a host means publishing.
39
41
  */
42
+ declare const RINGS: Record<RingId, Record<AppId, string>>;
43
+ declare function ringFor(hostname: string): RingId;
44
+ /** The production tiles, for consumers that want the list without a hostname. */
40
45
  declare const APPS: AppTile[];
41
- /** Applies per-id URL overrides. Unknown ids and empty strings are ignored. */
42
- declare function resolveApps(urls?: Partial<Record<AppId, string>>): AppTile[];
46
+ /**
47
+ * Tiles for the ring `hostname` belongs to, with per-id URL overrides applied
48
+ * last. Unknown ids and empty strings are ignored.
49
+ */
50
+ declare function resolveApps(urls?: Partial<Record<AppId, string>>, hostname?: string): AppTile[];
43
51
  /** True when the tile points at the page we are already on. */
44
52
  declare function isCurrent(app: AppTile, hostname: string): boolean;
45
53
 
46
- export { APPS, type AppId, AppLauncher, AppLauncherFab, type AppLauncherProps, type AppTile, LauncherPanel, isCurrent, resolveApps };
54
+ export { APPS, type AppId, AppLauncher, AppLauncherFab, type AppLauncherProps, type AppTile, LauncherPanel, RINGS, type RingId, isCurrent, resolveApps, ringFor };
package/dist/index.js CHANGED
@@ -5,27 +5,45 @@ import { Grip } from "lucide-react";
5
5
 
6
6
  // src/apps.ts
7
7
  import { Briefcase, FolderKanban } from "lucide-react";
8
- var APPS = [
9
- {
10
- id: "hrm",
11
- name: "8People",
12
- url: "https://people.8seneca.com",
13
- icon: Briefcase,
14
- color: "oklch(0.65 0.15 240)"
8
+ var TILES = [
9
+ { id: "hrm", name: "8People", icon: Briefcase, color: "oklch(0.65 0.15 240)" },
10
+ { id: "plane", name: "8Projects", icon: FolderKanban, color: "oklch(0.65 0.15 30)" }
11
+ ];
12
+ var RINGS = {
13
+ prod: {
14
+ hrm: "https://people.8seneca.com",
15
+ plane: "https://projects.8seneca.com"
16
+ },
17
+ // The Keycloak test ring: hrm on its kc-test environment, Plane on its
18
+ // sandbox one — the two that authenticate against the same realm.
19
+ "kc-test": {
20
+ hrm: "https://hr-systemweb-kc-test.up.railway.app",
21
+ plane: "https://hub-plane-sandbox.up.railway.app"
15
22
  },
16
- {
17
- id: "plane",
18
- name: "8Projects",
19
- url: "https://projects.8seneca.com",
20
- icon: FolderKanban,
21
- color: "oklch(0.65 0.15 30)"
23
+ // hrm's own sandbox environment. There is only one sandbox Plane, so it
24
+ // points at the same host kc-test does.
25
+ sandbox: {
26
+ hrm: "https://hr-systemweb-sandbox.up.railway.app",
27
+ plane: "https://hub-plane-sandbox.up.railway.app"
22
28
  }
23
- ];
24
- function resolveApps(urls) {
25
- if (!urls) return APPS;
26
- return APPS.map((app) => {
27
- const override = urls[app.id];
28
- return override ? { ...app, url: override } : app;
29
+ };
30
+ var HOST_RING = {
31
+ "people.8seneca.com": "prod",
32
+ "projects.8seneca.com": "prod",
33
+ "hr-systemweb-kc-test.up.railway.app": "kc-test",
34
+ // The sandbox Plane is the Keycloak-enabled one, so it pairs with kc-test hrm.
35
+ "hub-plane-sandbox.up.railway.app": "kc-test",
36
+ "hr-systemweb-sandbox.up.railway.app": "sandbox"
37
+ };
38
+ function ringFor(hostname) {
39
+ return HOST_RING[hostname] ?? "prod";
40
+ }
41
+ var APPS = TILES.map((tile) => ({ ...tile, url: RINGS.prod[tile.id] }));
42
+ function resolveApps(urls, hostname = "") {
43
+ const ring = RINGS[ringFor(hostname)];
44
+ return TILES.map((tile) => {
45
+ const override = urls?.[tile.id];
46
+ return { ...tile, url: override || ring[tile.id] };
29
47
  });
30
48
  }
31
49
  function isCurrent(app, hostname) {
@@ -129,7 +147,7 @@ var TRIGGER_BASE = "inline-flex items-center justify-center rounded-full text-la
129
147
  function AppLauncher({ urls, label = "Your apps", align = "end" } = {}) {
130
148
  const { open, toggle, rootRef, triggerRef, panelId } = useLauncher();
131
149
  const hostname = useHostname();
132
- const tiles = resolveApps(urls);
150
+ const tiles = resolveApps(urls, hostname);
133
151
  return /* @__PURE__ */ jsxs2("div", { ref: rootRef, className: "relative", children: [
134
152
  /* @__PURE__ */ jsx2(
135
153
  "button",
@@ -151,7 +169,7 @@ function AppLauncher({ urls, label = "Your apps", align = "end" } = {}) {
151
169
  function AppLauncherFab({ urls, label = "Your apps" } = {}) {
152
170
  const { open, toggle, rootRef, triggerRef, panelId } = useLauncher();
153
171
  const hostname = useHostname();
154
- const tiles = resolveApps(urls);
172
+ const tiles = resolveApps(urls, hostname);
155
173
  return /* @__PURE__ */ jsxs2("div", { ref: rootRef, className: "fixed bottom-6 right-6 z-50", children: [
156
174
  open && /* @__PURE__ */ jsx2("div", { className: "absolute bottom-16 right-0", children: /* @__PURE__ */ jsx2(LauncherPanel, { tiles, hostname, label, id: panelId }) }),
157
175
  /* @__PURE__ */ jsx2(
@@ -176,6 +194,8 @@ export {
176
194
  AppLauncher,
177
195
  AppLauncherFab,
178
196
  LauncherPanel,
197
+ RINGS,
179
198
  isCurrent,
180
- resolveApps
199
+ resolveApps,
200
+ ringFor
181
201
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "8seneca-app-launcher",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "9-dot app launcher shared across the 8seneca apps",
5
5
  "license": "MIT",
6
6
  "repository": {