@abpjs/setting-management 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,191 @@
1
+ import { SettingTab } from '@abpjs/theme-shared';
2
+ export { SettingTab } from '@abpjs/theme-shared';
3
+ import { ABP } from '@abpjs/core';
4
+ import React from 'react';
5
+
6
+ /**
7
+ * Setting Management Routes
8
+ * Translated from @abp/ng.setting-management v0.9.0
9
+ */
10
+
11
+ /**
12
+ * Default routes for setting management module
13
+ */
14
+ declare const SETTING_MANAGEMENT_ROUTES: {
15
+ routes: ABP.FullRoute[];
16
+ };
17
+
18
+ /**
19
+ * Setting Management Service
20
+ * Translated from @abp/ng.setting-management v0.9.0
21
+ */
22
+
23
+ /**
24
+ * Service for managing settings tabs and selection.
25
+ * This service maintains the list of registered setting tabs
26
+ * and tracks the currently selected tab.
27
+ */
28
+ declare class SettingManagementService {
29
+ private _settings;
30
+ private _selected;
31
+ private _subscribers;
32
+ /**
33
+ * Get all registered settings tabs sorted by order
34
+ */
35
+ get settings(): SettingTab[];
36
+ /**
37
+ * Get the currently selected setting tab
38
+ */
39
+ get selected(): SettingTab | null;
40
+ /**
41
+ * Register a new setting tab
42
+ * @param tab The setting tab to register
43
+ */
44
+ addSetting(tab: SettingTab): void;
45
+ /**
46
+ * Register multiple setting tabs at once
47
+ * @param tabs Array of setting tabs to register
48
+ */
49
+ addSettings(tabs: SettingTab[]): void;
50
+ /**
51
+ * Remove a setting tab by name
52
+ * @param name The name of the setting tab to remove
53
+ */
54
+ removeSetting(name: string): void;
55
+ /**
56
+ * Set the currently selected setting tab
57
+ * @param tab The tab to select (or null to clear selection)
58
+ */
59
+ setSelected(tab: SettingTab | null): void;
60
+ /**
61
+ * Select a setting tab by name
62
+ * @param name The name of the tab to select
63
+ */
64
+ selectByName(name: string): void;
65
+ /**
66
+ * Select a setting tab by URL
67
+ * @param url The URL of the tab to select
68
+ */
69
+ selectByUrl(url: string): void;
70
+ /**
71
+ * Clear all registered settings
72
+ */
73
+ clearSettings(): void;
74
+ /**
75
+ * Subscribe to changes in settings or selection
76
+ * @param callback Function to call when changes occur
77
+ * @returns Unsubscribe function
78
+ */
79
+ subscribe(callback: () => void): () => void;
80
+ private notifySubscribers;
81
+ }
82
+ /**
83
+ * Get the singleton instance of SettingManagementService
84
+ */
85
+ declare function getSettingManagementService(): SettingManagementService;
86
+
87
+ /**
88
+ * Return type for useSettingManagement hook
89
+ */
90
+ interface UseSettingManagementReturn {
91
+ /** All registered setting tabs sorted by order */
92
+ settings: SettingTab[];
93
+ /** Currently selected setting tab */
94
+ selected: SettingTab | null;
95
+ /** Add a new setting tab */
96
+ addSetting: (tab: SettingTab) => void;
97
+ /** Add multiple setting tabs */
98
+ addSettings: (tabs: SettingTab[]) => void;
99
+ /** Remove a setting tab by name */
100
+ removeSetting: (name: string) => void;
101
+ /** Set the selected setting tab */
102
+ setSelected: (tab: SettingTab | null) => void;
103
+ /** Select a setting tab by name */
104
+ selectByName: (name: string) => void;
105
+ /** Select a setting tab by URL */
106
+ selectByUrl: (url: string) => void;
107
+ /** Clear all registered settings */
108
+ clearSettings: () => void;
109
+ }
110
+ /**
111
+ * Hook for managing settings tabs
112
+ *
113
+ * This hook provides access to the setting management service state
114
+ * and methods for managing setting tabs in a React application.
115
+ *
116
+ * @example
117
+ * ```tsx
118
+ * function SettingsPage() {
119
+ * const {
120
+ * settings,
121
+ * selected,
122
+ * setSelected,
123
+ * addSetting,
124
+ * } = useSettingManagement();
125
+ *
126
+ * useEffect(() => {
127
+ * addSetting({
128
+ * name: 'My Settings',
129
+ * order: 1,
130
+ * url: '/settings/my',
131
+ * });
132
+ * }, []);
133
+ *
134
+ * return (
135
+ * <div>
136
+ * {settings.map(tab => (
137
+ * <button
138
+ * key={tab.name}
139
+ * onClick={() => setSelected(tab)}
140
+ * className={selected?.name === tab.name ? 'active' : ''}
141
+ * >
142
+ * {tab.name}
143
+ * </button>
144
+ * ))}
145
+ * </div>
146
+ * );
147
+ * }
148
+ * ```
149
+ */
150
+ declare function useSettingManagement(): UseSettingManagementReturn;
151
+
152
+ /**
153
+ * Setting Layout Component
154
+ * Translated from @abp/ng.setting-management v0.9.0
155
+ */
156
+
157
+ interface SettingLayoutProps {
158
+ /** Optional children to render in the content area */
159
+ children?: React.ReactNode;
160
+ /** Optional callback when tab is selected */
161
+ onTabSelect?: (tab: SettingTab) => void;
162
+ /** Optional CSS class for the container */
163
+ className?: string;
164
+ }
165
+ /**
166
+ * Layout component for the settings management page.
167
+ * Displays a list of setting tabs on the left and content on the right.
168
+ *
169
+ * @example
170
+ * ```tsx
171
+ * function SettingsPage() {
172
+ * const { addSettings } = useSettingManagement();
173
+ *
174
+ * useEffect(() => {
175
+ * addSettings([
176
+ * { name: 'Account', order: 1, url: '/settings/account' },
177
+ * { name: 'Tenant', order: 2, url: '/settings/tenant' },
178
+ * ]);
179
+ * }, []);
180
+ *
181
+ * return (
182
+ * <SettingLayout>
183
+ * <Outlet />
184
+ * </SettingLayout>
185
+ * );
186
+ * }
187
+ * ```
188
+ */
189
+ declare function SettingLayout({ children, onTabSelect, className, }: SettingLayoutProps): React.ReactElement;
190
+
191
+ export { SETTING_MANAGEMENT_ROUTES, SettingLayout, type SettingLayoutProps, SettingManagementService, type UseSettingManagementReturn, getSettingManagementService, useSettingManagement };
package/dist/index.js ADDED
@@ -0,0 +1,318 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ SETTING_MANAGEMENT_ROUTES: () => SETTING_MANAGEMENT_ROUTES,
24
+ SettingLayout: () => SettingLayout,
25
+ SettingManagementService: () => SettingManagementService,
26
+ getSettingManagementService: () => getSettingManagementService,
27
+ useSettingManagement: () => useSettingManagement
28
+ });
29
+ module.exports = __toCommonJS(index_exports);
30
+
31
+ // src/constants/routes.ts
32
+ var SETTING_MANAGEMENT_ROUTES = {
33
+ routes: [
34
+ {
35
+ name: "Settings",
36
+ path: "setting-management",
37
+ layout: "application",
38
+ order: 100
39
+ }
40
+ ]
41
+ };
42
+
43
+ // src/services/setting-management.service.ts
44
+ var SettingManagementService = class {
45
+ constructor() {
46
+ this._settings = [];
47
+ this._selected = null;
48
+ this._subscribers = /* @__PURE__ */ new Set();
49
+ }
50
+ /**
51
+ * Get all registered settings tabs sorted by order
52
+ */
53
+ get settings() {
54
+ return [...this._settings].sort((a, b) => a.order - b.order);
55
+ }
56
+ /**
57
+ * Get the currently selected setting tab
58
+ */
59
+ get selected() {
60
+ return this._selected;
61
+ }
62
+ /**
63
+ * Register a new setting tab
64
+ * @param tab The setting tab to register
65
+ */
66
+ addSetting(tab) {
67
+ const exists = this._settings.some((s) => s.name === tab.name);
68
+ if (!exists) {
69
+ this._settings.push(tab);
70
+ this.notifySubscribers();
71
+ }
72
+ }
73
+ /**
74
+ * Register multiple setting tabs at once
75
+ * @param tabs Array of setting tabs to register
76
+ */
77
+ addSettings(tabs) {
78
+ let changed = false;
79
+ for (const tab of tabs) {
80
+ const exists = this._settings.some((s) => s.name === tab.name);
81
+ if (!exists) {
82
+ this._settings.push(tab);
83
+ changed = true;
84
+ }
85
+ }
86
+ if (changed) {
87
+ this.notifySubscribers();
88
+ }
89
+ }
90
+ /**
91
+ * Remove a setting tab by name
92
+ * @param name The name of the setting tab to remove
93
+ */
94
+ removeSetting(name) {
95
+ const index = this._settings.findIndex((s) => s.name === name);
96
+ if (index !== -1) {
97
+ this._settings.splice(index, 1);
98
+ if (this._selected?.name === name) {
99
+ this._selected = null;
100
+ }
101
+ this.notifySubscribers();
102
+ }
103
+ }
104
+ /**
105
+ * Set the currently selected setting tab
106
+ * @param tab The tab to select (or null to clear selection)
107
+ */
108
+ setSelected(tab) {
109
+ this._selected = tab;
110
+ this.notifySubscribers();
111
+ }
112
+ /**
113
+ * Select a setting tab by name
114
+ * @param name The name of the tab to select
115
+ */
116
+ selectByName(name) {
117
+ const tab = this._settings.find((s) => s.name === name);
118
+ if (tab) {
119
+ this.setSelected(tab);
120
+ }
121
+ }
122
+ /**
123
+ * Select a setting tab by URL
124
+ * @param url The URL of the tab to select
125
+ */
126
+ selectByUrl(url) {
127
+ const tab = this._settings.find((s) => s.url === url);
128
+ if (tab) {
129
+ this.setSelected(tab);
130
+ }
131
+ }
132
+ /**
133
+ * Clear all registered settings
134
+ */
135
+ clearSettings() {
136
+ this._settings = [];
137
+ this._selected = null;
138
+ this.notifySubscribers();
139
+ }
140
+ /**
141
+ * Subscribe to changes in settings or selection
142
+ * @param callback Function to call when changes occur
143
+ * @returns Unsubscribe function
144
+ */
145
+ subscribe(callback) {
146
+ this._subscribers.add(callback);
147
+ return () => {
148
+ this._subscribers.delete(callback);
149
+ };
150
+ }
151
+ notifySubscribers() {
152
+ this._subscribers.forEach((callback) => callback());
153
+ }
154
+ };
155
+ var _instance = null;
156
+ function getSettingManagementService() {
157
+ if (!_instance) {
158
+ _instance = new SettingManagementService();
159
+ }
160
+ return _instance;
161
+ }
162
+
163
+ // src/hooks/useSettingManagement.ts
164
+ var import_react = require("react");
165
+ function useSettingManagement() {
166
+ const service = (0, import_react.useMemo)(() => getSettingManagementService(), []);
167
+ const [, forceUpdate] = (0, import_react.useState)({});
168
+ (0, import_react.useEffect)(() => {
169
+ const unsubscribe = service.subscribe(() => {
170
+ forceUpdate({});
171
+ });
172
+ return unsubscribe;
173
+ }, [service]);
174
+ const addSetting = (0, import_react.useCallback)(
175
+ (tab) => {
176
+ service.addSetting(tab);
177
+ },
178
+ [service]
179
+ );
180
+ const addSettings = (0, import_react.useCallback)(
181
+ (tabs) => {
182
+ service.addSettings(tabs);
183
+ },
184
+ [service]
185
+ );
186
+ const removeSetting = (0, import_react.useCallback)(
187
+ (name) => {
188
+ service.removeSetting(name);
189
+ },
190
+ [service]
191
+ );
192
+ const setSelected = (0, import_react.useCallback)(
193
+ (tab) => {
194
+ service.setSelected(tab);
195
+ },
196
+ [service]
197
+ );
198
+ const selectByName = (0, import_react.useCallback)(
199
+ (name) => {
200
+ service.selectByName(name);
201
+ },
202
+ [service]
203
+ );
204
+ const selectByUrl = (0, import_react.useCallback)(
205
+ (url) => {
206
+ service.selectByUrl(url);
207
+ },
208
+ [service]
209
+ );
210
+ const clearSettings = (0, import_react.useCallback)(() => {
211
+ service.clearSettings();
212
+ }, [service]);
213
+ return {
214
+ settings: service.settings,
215
+ selected: service.selected,
216
+ addSetting,
217
+ addSettings,
218
+ removeSetting,
219
+ setSelected,
220
+ selectByName,
221
+ selectByUrl,
222
+ clearSettings
223
+ };
224
+ }
225
+
226
+ // src/components/SettingLayout/SettingLayout.tsx
227
+ var import_react2 = require("react");
228
+ var import_react_router_dom = require("react-router-dom");
229
+ var import_jsx_runtime = require("react/jsx-runtime");
230
+ function SettingLayout({
231
+ children,
232
+ onTabSelect,
233
+ className = ""
234
+ }) {
235
+ const { settings, selected, setSelected } = useSettingManagement();
236
+ const location = (0, import_react_router_dom.useLocation)();
237
+ const navigate = (0, import_react_router_dom.useNavigate)();
238
+ (0, import_react2.useEffect)(() => {
239
+ if (settings.length > 0) {
240
+ const matchingTab = settings.find((tab) => tab.url && location.pathname.startsWith(tab.url));
241
+ if (matchingTab) {
242
+ setSelected(matchingTab);
243
+ } else if (!selected && settings.length > 0) {
244
+ setSelected(settings[0]);
245
+ }
246
+ }
247
+ }, [location.pathname, settings, selected, setSelected]);
248
+ const handleTabClick = (tab) => {
249
+ setSelected(tab);
250
+ onTabSelect?.(tab);
251
+ if (tab.url) {
252
+ navigate(tab.url);
253
+ }
254
+ };
255
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: `setting-layout ${className}`, style: styles.container, children: [
256
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "setting-layout-sidebar", style: styles.sidebar, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("nav", { className: "setting-tabs", style: styles.nav, children: settings.map((tab) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
257
+ "button",
258
+ {
259
+ type: "button",
260
+ onClick: () => handleTabClick(tab),
261
+ className: `setting-tab ${selected?.name === tab.name ? "active" : ""}`,
262
+ style: {
263
+ ...styles.tabButton,
264
+ ...selected?.name === tab.name ? styles.tabButtonActive : {}
265
+ },
266
+ children: tab.name
267
+ },
268
+ tab.name
269
+ )) }) }),
270
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "setting-layout-content", style: styles.content, children })
271
+ ] });
272
+ }
273
+ var styles = {
274
+ container: {
275
+ display: "flex",
276
+ minHeight: "400px",
277
+ gap: "24px"
278
+ },
279
+ sidebar: {
280
+ width: "240px",
281
+ flexShrink: 0
282
+ },
283
+ nav: {
284
+ display: "flex",
285
+ flexDirection: "column",
286
+ gap: "4px"
287
+ },
288
+ tabButton: {
289
+ display: "block",
290
+ width: "100%",
291
+ padding: "12px 16px",
292
+ textAlign: "left",
293
+ border: "none",
294
+ borderRadius: "6px",
295
+ background: "transparent",
296
+ cursor: "pointer",
297
+ fontSize: "14px",
298
+ color: "inherit",
299
+ transition: "background-color 0.2s"
300
+ },
301
+ tabButtonActive: {
302
+ backgroundColor: "rgba(59, 130, 246, 0.1)",
303
+ color: "#3b82f6",
304
+ fontWeight: 500
305
+ },
306
+ content: {
307
+ flex: 1,
308
+ minWidth: 0
309
+ }
310
+ };
311
+ // Annotate the CommonJS export names for ESM import in node:
312
+ 0 && (module.exports = {
313
+ SETTING_MANAGEMENT_ROUTES,
314
+ SettingLayout,
315
+ SettingManagementService,
316
+ getSettingManagementService,
317
+ useSettingManagement
318
+ });