@maykonpaulo/maestro-admin 0.1.2 → 0.2.0-next.1
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 +149 -7
- package/dist/index.js +869 -134
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -86,12 +86,19 @@ interface SortInput {
|
|
|
86
86
|
field: string;
|
|
87
87
|
direction: 'asc' | 'desc';
|
|
88
88
|
}
|
|
89
|
+
/** One filter clause, serialized to the server's `filter=field:operator:value` query param. */
|
|
90
|
+
interface FilterInput {
|
|
91
|
+
field: string;
|
|
92
|
+
operator: 'equals' | 'notEquals' | 'contains' | 'startsWith' | 'endsWith' | 'in' | 'notIn' | 'gt' | 'gte' | 'lt' | 'lte' | 'between' | 'isNull' | 'isNotNull' | 'isTrue' | 'isFalse';
|
|
93
|
+
value?: string;
|
|
94
|
+
}
|
|
89
95
|
interface ListQuery {
|
|
90
96
|
page?: number;
|
|
91
97
|
pageSize?: number;
|
|
92
98
|
search?: string;
|
|
93
99
|
searchFields?: string[];
|
|
94
100
|
sort?: SortInput[];
|
|
101
|
+
filters?: FilterInput[];
|
|
95
102
|
}
|
|
96
103
|
|
|
97
104
|
interface MaestroClientConfig {
|
|
@@ -128,6 +135,82 @@ declare class MaestroClient {
|
|
|
128
135
|
remove(entityId: string, id: string): Promise<void>;
|
|
129
136
|
}
|
|
130
137
|
|
|
138
|
+
type AdminLocale = 'en' | 'pt-BR';
|
|
139
|
+
/**
|
|
140
|
+
* Every user-facing string the admin chrome renders. Entity/field labels are NOT here — those come
|
|
141
|
+
* from the server metadata (optionally rewritten via `AdminLabels`); this dictionary covers only the
|
|
142
|
+
* UI around them (buttons, menus, pagination, confirmations).
|
|
143
|
+
*/
|
|
144
|
+
interface AdminStrings {
|
|
145
|
+
loading: string;
|
|
146
|
+
loadingMetadata: string;
|
|
147
|
+
records: (total: number) => string;
|
|
148
|
+
searchPlaceholder: (plural: string) => string;
|
|
149
|
+
newRecord: string;
|
|
150
|
+
view: string;
|
|
151
|
+
edit: string;
|
|
152
|
+
clone: string;
|
|
153
|
+
remove: string;
|
|
154
|
+
copyId: string;
|
|
155
|
+
copyObject: string;
|
|
156
|
+
copyValue: string;
|
|
157
|
+
copied: string;
|
|
158
|
+
addToFilter: string;
|
|
159
|
+
openRelated: (label: string) => string;
|
|
160
|
+
filters: string;
|
|
161
|
+
clearFilters: string;
|
|
162
|
+
actions: string;
|
|
163
|
+
noRecords: string;
|
|
164
|
+
tryDifferentSearch: string;
|
|
165
|
+
deleteConfirm: (singular: string) => string;
|
|
166
|
+
page: (page: number, total: number) => string;
|
|
167
|
+
previous: string;
|
|
168
|
+
next: string;
|
|
169
|
+
cancel: string;
|
|
170
|
+
save: string;
|
|
171
|
+
saving: string;
|
|
172
|
+
create: string;
|
|
173
|
+
newTitle: (singular: string) => string;
|
|
174
|
+
editTitle: (singular: string) => string;
|
|
175
|
+
cloneTitle: (singular: string) => string;
|
|
176
|
+
entitiesFooter: (count: number) => string;
|
|
177
|
+
yes: string;
|
|
178
|
+
no: string;
|
|
179
|
+
searchMenu: string;
|
|
180
|
+
recents: string;
|
|
181
|
+
menus: string;
|
|
182
|
+
noMenuResults: string;
|
|
183
|
+
}
|
|
184
|
+
declare function stringsFor(locale: AdminLocale): AdminStrings;
|
|
185
|
+
declare const I18nProvider: react.Provider<AdminStrings>;
|
|
186
|
+
/** The active UI-string dictionary (set by `<MaestroAdmin locale>`; defaults to English). */
|
|
187
|
+
declare function useT(): AdminStrings;
|
|
188
|
+
|
|
189
|
+
interface EntityLabelOverride {
|
|
190
|
+
/** Singular label ("Usuário"). */
|
|
191
|
+
singular?: string;
|
|
192
|
+
/** Plural label ("Usuários") — also the sidebar entry. */
|
|
193
|
+
plural?: string;
|
|
194
|
+
/** Sidebar folder this entity belongs to (display name). Wins over heuristic prefix grouping. */
|
|
195
|
+
group?: string;
|
|
196
|
+
/** Field labels for this entity only, by field name. Wins over the global `fields` map. */
|
|
197
|
+
fields?: Record<string, string>;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Presentation-layer label rewrites, applied on top of the metadata the server serves. This is how a
|
|
201
|
+
* deployment localizes or humanizes auto-introspected names ("recoveryactions" → "Ações de
|
|
202
|
+
* Recuperação") without touching the engine: keys match either the entity `id` or its source `table`.
|
|
203
|
+
*/
|
|
204
|
+
interface AdminLabels {
|
|
205
|
+
entities?: Record<string, EntityLabelOverride>;
|
|
206
|
+
/** Global field labels by field name (`createdAt` → "Criado em"), for every entity. */
|
|
207
|
+
fields?: Record<string, string>;
|
|
208
|
+
/** Display names for heuristic sidebar folders, by shared table-name prefix (`recovery` → "Recuperação"). */
|
|
209
|
+
groups?: Record<string, string>;
|
|
210
|
+
}
|
|
211
|
+
/** Returns a copy of `metadata` with every label override applied. No-op when `labels` is empty. */
|
|
212
|
+
declare function applyLabels(metadata: MaestroMetadata, labels: AdminLabels | undefined): MaestroMetadata;
|
|
213
|
+
|
|
131
214
|
interface MaestroAdminProps {
|
|
132
215
|
/** Base URL of the running maestro-server. Ignored when `client` is given. */
|
|
133
216
|
apiUrl?: string;
|
|
@@ -137,6 +220,10 @@ interface MaestroAdminProps {
|
|
|
137
220
|
client?: MaestroClient;
|
|
138
221
|
/** Sidebar title. Defaults to "Maestro Admin". */
|
|
139
222
|
title?: string;
|
|
223
|
+
/** UI-chrome language (buttons, menus, pagination). Defaults to `en`. */
|
|
224
|
+
locale?: AdminLocale;
|
|
225
|
+
/** Label rewrites (localization/humanization) applied over the served metadata. */
|
|
226
|
+
labels?: AdminLabels;
|
|
140
227
|
}
|
|
141
228
|
/**
|
|
142
229
|
* The whole metadata-driven admin in one component. Point it at a running maestro-server and it reads
|
|
@@ -165,44 +252,99 @@ declare function useEntityList(entityId: string, query: ListQuery): AsyncState<L
|
|
|
165
252
|
declare function useEntityRecord(entityId: string, id: string | undefined): AsyncState<globalThis.Record<string, unknown>>;
|
|
166
253
|
/** Fields shown in the list table, ordered, honoring per-field list visibility. */
|
|
167
254
|
declare function listFields(entity: EntityMetadata): FieldMetadata[];
|
|
255
|
+
/**
|
|
256
|
+
* The "principal" columns for an entity's table: instead of dumping every field, picks up to `max`
|
|
257
|
+
* of the most identifying ones — the display field first, then searchable/required texts, enums,
|
|
258
|
+
* relations, status booleans and dates — and drops blobs (`json`/`array`/`text`), sensitive values
|
|
259
|
+
* and the primary key. Everything remains visible in the detail view. When any field carries an
|
|
260
|
+
* explicit `list.order`/`list.width` (a curated schema), the curator's selection is honored as-is.
|
|
261
|
+
*/
|
|
262
|
+
declare function primaryListFields(entity: EntityMetadata, max?: number): FieldMetadata[];
|
|
168
263
|
/** Fields shown in the detail view, ordered. */
|
|
169
264
|
declare function detailFields(entity: EntityMetadata): FieldMetadata[];
|
|
170
265
|
/** Fields editable in the create/update form, ordered, per mode. */
|
|
171
266
|
declare function formFields(entity: EntityMetadata, mode: 'create' | 'edit'): FieldMetadata[];
|
|
172
267
|
|
|
173
|
-
|
|
268
|
+
interface MenuGroup {
|
|
269
|
+
/** Stable key: the explicit group name, or the heuristic table-name prefix. */
|
|
270
|
+
id: string;
|
|
271
|
+
label: string;
|
|
272
|
+
entities: EntityMetadata[];
|
|
273
|
+
}
|
|
274
|
+
interface SidebarMenu {
|
|
275
|
+
groups: MenuGroup[];
|
|
276
|
+
/** Entities that belong to no group — rendered flat after the folders. */
|
|
277
|
+
ungrouped: EntityMetadata[];
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Builds the sidebar menu structure: explicit groups first (an entity override's `group` in
|
|
281
|
+
* `AdminLabels` always wins), then heuristic clustering of what's left — collections sharing a
|
|
282
|
+
* table-name prefix (`recoveryactions`, `recoveryscores`, … → "Recovery") become a folder, since a
|
|
283
|
+
* shared prefix is how schemaless databases usually encode the module a collection belongs to.
|
|
284
|
+
* Heuristic folder names can be localized via `labels.groups` (prefix → display name). Everything
|
|
285
|
+
* else stays flat. Groups and their entities are sorted by label.
|
|
286
|
+
*/
|
|
287
|
+
declare function buildMenu(entities: EntityMetadata[], labels?: AdminLabels): SidebarMenu;
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Recently-visited entity ids, most recent first, persisted in `localStorage` so they survive
|
|
291
|
+
* reloads. `push` moves (or inserts) an id to the front, capped at 8. Pass a distinct `scope` (e.g.
|
|
292
|
+
* the API URL) when one browser origin hosts admins for several servers.
|
|
293
|
+
*/
|
|
294
|
+
declare function useRecents(scope?: string): {
|
|
295
|
+
recents: string[];
|
|
296
|
+
push: (entityId: string) => void;
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
declare function EntityList({ entity, onOpen, onCreate, onEdit, onClone, onNavigate, initialFilters, }: {
|
|
174
300
|
entity: EntityMetadata;
|
|
175
301
|
onOpen: (id: string) => void;
|
|
176
302
|
onCreate: () => void;
|
|
177
303
|
onEdit: (id: string) => void;
|
|
304
|
+
onClone: (id: string) => void;
|
|
305
|
+
onNavigate: (entityId: string, id: string) => void;
|
|
306
|
+
initialFilters?: FilterInput[];
|
|
178
307
|
}): react.JSX.Element;
|
|
179
308
|
|
|
180
|
-
declare function EntityDetail({ entity, id, onBack, onEdit, }: {
|
|
309
|
+
declare function EntityDetail({ entity, id, onBack, onEdit, onClone, onDeleted, onNavigate, }: {
|
|
181
310
|
entity: EntityMetadata;
|
|
182
311
|
id: string;
|
|
183
312
|
onBack: () => void;
|
|
184
313
|
onEdit: () => void;
|
|
314
|
+
onClone: () => void;
|
|
315
|
+
onDeleted: () => void;
|
|
316
|
+
onNavigate: (entityId: string, id: string) => void;
|
|
185
317
|
}): react.JSX.Element;
|
|
186
318
|
|
|
187
|
-
declare function EntityForm({ entity, mode, id, onCancel, onSaved, }: {
|
|
319
|
+
declare function EntityForm({ entity, mode, id, cloneFromId, onCancel, onSaved, }: {
|
|
188
320
|
entity: EntityMetadata;
|
|
189
321
|
mode: 'create' | 'edit';
|
|
190
322
|
id?: string;
|
|
323
|
+
/** In `create` mode, prefills the form from this record (minus the primary key and non-cloneable fields). */
|
|
324
|
+
cloneFromId?: string;
|
|
191
325
|
onCancel: () => void;
|
|
192
326
|
onSaved: (record: Record_) => void;
|
|
193
327
|
}): react.JSX.Element;
|
|
194
328
|
|
|
195
|
-
declare function Sidebar({ entities, activeId, onSelect, title, }: {
|
|
329
|
+
declare function Sidebar({ entities, activeId, onSelect, title, labels, recents, }: {
|
|
196
330
|
entities: EntityMetadata[];
|
|
197
331
|
activeId: string | undefined;
|
|
198
332
|
onSelect: (entityId: string) => void;
|
|
199
333
|
title: string;
|
|
334
|
+
/** Same object given to `<MaestroAdmin labels>` — supplies folder assignments and folder names. */
|
|
335
|
+
labels?: AdminLabels;
|
|
336
|
+
/** Recently-visited entity ids, most recent first. */
|
|
337
|
+
recents?: string[];
|
|
200
338
|
}): react.JSX.Element;
|
|
201
339
|
|
|
202
|
-
/**
|
|
203
|
-
|
|
340
|
+
/**
|
|
341
|
+
* Renders a single record value read-only, shaped by the field's type (for tables and detail views).
|
|
342
|
+
* `compact` is the table-cell mode: long text truncates instead of stretching the row.
|
|
343
|
+
*/
|
|
344
|
+
declare function FieldValue({ field, value, compact }: {
|
|
204
345
|
field: FieldMetadata;
|
|
205
346
|
value: unknown;
|
|
347
|
+
compact?: boolean;
|
|
206
348
|
}): react.JSX.Element;
|
|
207
349
|
|
|
208
350
|
/**
|
|
@@ -217,4 +359,4 @@ declare function FieldInput({ field, value, onChange, disabled, }: {
|
|
|
217
359
|
disabled?: boolean;
|
|
218
360
|
}): react.JSX.Element;
|
|
219
361
|
|
|
220
|
-
export { AdminClientProvider, type AsyncState, type EntityCapabilities, EntityDetail, EntityForm, EntityList, type EntityMetadata, FieldInput, type FieldMetadata, FieldValue, type ListQuery, type ListResult, MaestroAdmin, type MaestroAdminProps, MaestroApiError, MaestroClient, type MaestroClientConfig, type MaestroMetadata, Sidebar, detailFields, formFields, listFields, useAsync, useClient, useEntityList, useEntityRecord, useMetadata };
|
|
362
|
+
export { AdminClientProvider, type AdminLabels, type AdminLocale, type AdminStrings, type AsyncState, type EntityCapabilities, EntityDetail, EntityForm, type EntityLabelOverride, EntityList, type EntityMetadata, FieldInput, type FieldMetadata, FieldValue, type FilterInput, I18nProvider, type ListQuery, type ListResult, MaestroAdmin, type MaestroAdminProps, MaestroApiError, MaestroClient, type MaestroClientConfig, type MaestroMetadata, type MenuGroup, Sidebar, type SidebarMenu, applyLabels, buildMenu, detailFields, formFields, listFields, primaryListFields, stringsFor, useAsync, useClient, useEntityList, useEntityRecord, useMetadata, useRecents, useT };
|