@yimingliao/cms 0.0.94 → 0.0.96
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.
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { clsx } from 'clsx';
|
|
2
2
|
import { twMerge } from 'tailwind-merge';
|
|
3
3
|
import { useState, useRef, useCallback, useEffect } from 'react';
|
|
4
|
+
import { usePathname } from 'next/navigation';
|
|
4
5
|
import { UAParser } from 'ua-parser-js';
|
|
5
6
|
import { Slot } from '@radix-ui/react-slot';
|
|
6
7
|
import { cva } from 'class-variance-authority';
|
|
7
8
|
import { jsx } from 'react/jsx-runtime';
|
|
8
9
|
import { Loader2Icon } from 'lucide-react';
|
|
9
10
|
import * as LabelPrimitive from '@radix-ui/react-label';
|
|
11
|
+
import * as SeparatorPrimitive from '@radix-ui/react-separator';
|
|
10
12
|
|
|
11
13
|
// src/client/applications/ui/utils.ts
|
|
12
14
|
var cn = (...inputs) => {
|
|
@@ -42,6 +44,17 @@ var useCountdown = (initialTime) => {
|
|
|
42
44
|
}, [isCounting]);
|
|
43
45
|
return { timeLeft, isCounting, startCountdown };
|
|
44
46
|
};
|
|
47
|
+
var useParentPathname = () => {
|
|
48
|
+
const pathname = usePathname();
|
|
49
|
+
if (pathname === "/") return "/";
|
|
50
|
+
const index = pathname.lastIndexOf("/");
|
|
51
|
+
return index <= 0 ? "/" : pathname.slice(0, index);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
// src/client/applications/ui/is-confirm.ts
|
|
55
|
+
var isConfirm = (t, key = "ui.dialog.confirm.text") => {
|
|
56
|
+
return confirm(t(key));
|
|
57
|
+
};
|
|
45
58
|
function useDeviceInfo() {
|
|
46
59
|
const [deviceInfo, setDeviceInfo] = useState(null);
|
|
47
60
|
useEffect(() => {
|
|
@@ -384,5 +397,25 @@ function Label({ className, ...props }) {
|
|
|
384
397
|
}
|
|
385
398
|
);
|
|
386
399
|
}
|
|
400
|
+
function Separator({
|
|
401
|
+
className,
|
|
402
|
+
orientation = "horizontal",
|
|
403
|
+
decorative = true,
|
|
404
|
+
...props
|
|
405
|
+
}) {
|
|
406
|
+
return /* @__PURE__ */ jsx(
|
|
407
|
+
SeparatorPrimitive.Root,
|
|
408
|
+
{
|
|
409
|
+
"data-slot": "separator",
|
|
410
|
+
decorative,
|
|
411
|
+
orientation,
|
|
412
|
+
className: cn(
|
|
413
|
+
"bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
|
|
414
|
+
className
|
|
415
|
+
),
|
|
416
|
+
...props
|
|
417
|
+
}
|
|
418
|
+
);
|
|
419
|
+
}
|
|
387
420
|
|
|
388
|
-
export { Button, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, Label, Spinner, Textarea, cn, useCountdown, useDeviceInfo };
|
|
421
|
+
export { Button, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, Label, Separator, Spinner, Textarea, cn, isConfirm, useCountdown, useDeviceInfo, useParentPathname };
|
package/dist/client/index.d.ts
CHANGED
|
@@ -6,9 +6,9 @@ import * as _tanstack_query_core from '@tanstack/query-core';
|
|
|
6
6
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
7
7
|
import { c as createVerifyAction, a as createSignInAction, b as createVerifyEmailAction, d as createEmailUnverifiedAction, e as createForgotPasswordAction, f as createResetPasswordAction, g as createChangePasswordAction } from '../create-reset-password-action-D6aTuuqO.js';
|
|
8
8
|
import * as React$1 from 'react';
|
|
9
|
-
import {
|
|
10
|
-
import { L as LabelProps, B as ButtonProps$1 } from '../label-BF4qxS03.js';
|
|
9
|
+
import { ReactNode, ComponentProps, HTMLAttributes } from 'react';
|
|
11
10
|
import { LucideIcon } from 'lucide-react';
|
|
11
|
+
import { B as ButtonProps$1, L as LabelProps } from '../label-BF4qxS03.js';
|
|
12
12
|
import { ClassValue } from 'clsx';
|
|
13
13
|
import 'zod';
|
|
14
14
|
import 'zod/v4/core';
|
|
@@ -26,18 +26,18 @@ import 'class-variance-authority';
|
|
|
26
26
|
import '@radix-ui/react-label';
|
|
27
27
|
|
|
28
28
|
interface UIStates {
|
|
29
|
-
isLoading?: boolean;
|
|
30
|
-
isDisabled?: boolean;
|
|
31
|
-
isError?: boolean;
|
|
29
|
+
isLoading?: boolean | undefined;
|
|
30
|
+
isDisabled?: boolean | undefined;
|
|
31
|
+
isError?: boolean | undefined;
|
|
32
32
|
}
|
|
33
33
|
interface FormContext<T> {
|
|
34
|
-
formData?: T;
|
|
35
|
-
setFormData?: React$1.Dispatch<React$1.SetStateAction<T
|
|
34
|
+
formData?: T | undefined;
|
|
35
|
+
setFormData?: React$1.Dispatch<React$1.SetStateAction<T>> | undefined;
|
|
36
36
|
}
|
|
37
37
|
interface FieldContext {
|
|
38
|
-
fieldName?: string;
|
|
39
|
-
translations?: Translation[];
|
|
40
|
-
errors?: string[];
|
|
38
|
+
fieldName?: string | undefined;
|
|
39
|
+
translations?: Translation[] | undefined;
|
|
40
|
+
errors?: string[] | undefined;
|
|
41
41
|
}
|
|
42
42
|
interface FormFieldController<T = Record<string, unknown>> extends UIStates, FormContext<T>, FieldContext {
|
|
43
43
|
}
|
|
@@ -349,6 +349,52 @@ declare function createAdminInitializer({ useAdmin, useQuery, verifyAction, }: {
|
|
|
349
349
|
verifyAction: ReturnType<typeof createVerifyAction>;
|
|
350
350
|
}): () => null;
|
|
351
351
|
|
|
352
|
+
interface PageHeaderTitleProps {
|
|
353
|
+
icon?: LucideIcon;
|
|
354
|
+
title?: ReactNode;
|
|
355
|
+
subtitle?: ReactNode;
|
|
356
|
+
children?: ReactNode;
|
|
357
|
+
leftChildren?: ReactNode;
|
|
358
|
+
className?: string;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
type Variant = "default" | "index" | "create" | "show" | "edit" | "batch" | "batch-create" | "trash";
|
|
362
|
+
|
|
363
|
+
interface ButtonProps extends ButtonProps$1, UIStates {
|
|
364
|
+
icon?: LucideIcon | undefined;
|
|
365
|
+
href?: string | undefined;
|
|
366
|
+
openNewTab?: boolean | undefined;
|
|
367
|
+
}
|
|
368
|
+
declare function Button({ icon, href, openNewTab, isDisabled, isLoading, children, ...props }: ButtonProps): react_jsx_runtime.JSX.Element;
|
|
369
|
+
|
|
370
|
+
interface InputProps<T = Record<string, unknown>> extends ComponentProps<"input">, FormFieldController<T> {
|
|
371
|
+
}
|
|
372
|
+
declare function Input<T>({ fieldName, setFormData, isLoading, isDisabled, isError, children, ...props }: InputProps<T>): react_jsx_runtime.JSX.Element;
|
|
373
|
+
|
|
374
|
+
interface PageHeaderProps {
|
|
375
|
+
titleProps?: PageHeaderTitleProps;
|
|
376
|
+
leftChildren?: ReactNode;
|
|
377
|
+
rightChildren?: ReactNode;
|
|
378
|
+
variant?: Variant;
|
|
379
|
+
returnButtonProps?: ButtonProps;
|
|
380
|
+
createButtonProps?: ButtonProps;
|
|
381
|
+
createCategoryButtonProps?: ButtonProps;
|
|
382
|
+
editButtonProps?: ButtonProps;
|
|
383
|
+
showButtonProps?: ButtonProps;
|
|
384
|
+
settingButtonProps?: ButtonProps;
|
|
385
|
+
batchButtonProps?: ButtonProps;
|
|
386
|
+
destroyButtonProps?: ButtonProps;
|
|
387
|
+
restoreButtonProps?: ButtonProps;
|
|
388
|
+
isLocked?: boolean;
|
|
389
|
+
isDisabled?: boolean;
|
|
390
|
+
isNotFound?: boolean;
|
|
391
|
+
batchCreateButtonHref?: string;
|
|
392
|
+
selectAllFn?: () => void;
|
|
393
|
+
cancelAllFn?: () => void;
|
|
394
|
+
showTopicSettingButton?: boolean;
|
|
395
|
+
}
|
|
396
|
+
declare function PageHeader(props: PageHeaderProps): react_jsx_runtime.JSX.Element;
|
|
397
|
+
|
|
352
398
|
declare function Form({ onSubmit, className, ...props }: ComponentProps<"form">): react_jsx_runtime.JSX.Element;
|
|
353
399
|
|
|
354
400
|
interface FieldProps extends LabelProps {
|
|
@@ -367,16 +413,11 @@ interface FieldBodyProps extends HTMLAttributes<HTMLDivElement>, UIStates {
|
|
|
367
413
|
}
|
|
368
414
|
declare function FieldBody({ isLoading, isDisabled, isEmpty, className, backgroundClassName, childrenClassName, children, ...props }: FieldBodyProps): react_jsx_runtime.JSX.Element;
|
|
369
415
|
|
|
370
|
-
|
|
371
|
-
icon?: LucideIcon;
|
|
372
|
-
href?: string;
|
|
373
|
-
openNewTab?: boolean;
|
|
374
|
-
}
|
|
375
|
-
declare function Button({ icon, href, openNewTab, isDisabled, isLoading, children, ...props }: ButtonProps): react_jsx_runtime.JSX.Element;
|
|
416
|
+
declare function FieldsContainer({ className, children, ...props }: ComponentProps<"div">): react_jsx_runtime.JSX.Element;
|
|
376
417
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
declare function
|
|
418
|
+
declare function MainFields({ className, children, ...props }: ComponentProps<"div">): react_jsx_runtime.JSX.Element;
|
|
419
|
+
|
|
420
|
+
declare function SideFields({ className, children, ...props }: ComponentProps<"div">): react_jsx_runtime.JSX.Element;
|
|
380
421
|
|
|
381
422
|
declare function PasswordInput<T>({ ...props }: InputProps<T>): react_jsx_runtime.JSX.Element;
|
|
382
423
|
|
|
@@ -456,4 +497,4 @@ declare const cn: (...inputs: ClassValue[]) => string;
|
|
|
456
497
|
|
|
457
498
|
declare function useDeviceInfo(): DeviceInfo | null;
|
|
458
499
|
|
|
459
|
-
export { AdminProvider, Button, type ButtonProps, Field, FieldBody, Form, Input, type InputProps, PasswordInput, type ShowToastOption, cn, createAdminInitializer, createChangePasswordPage, createEmailUnverifiedPage, createForgotPasswordPage, createRequestInterceptor, createResetPasswordPage, createResponseInterceptor, createSignInPage, createSmartFetch, createUseCommand, createUseQuery, createVerifyEmailPage, handleToast, useAdmin, useDeviceInfo };
|
|
500
|
+
export { AdminProvider, Button, type ButtonProps, Field, FieldBody, FieldsContainer, Form, Input, type InputProps, MainFields, PageHeader, PasswordInput, type ShowToastOption, SideFields, cn, createAdminInitializer, createChangePasswordPage, createEmailUnverifiedPage, createForgotPasswordPage, createRequestInterceptor, createResetPasswordPage, createResponseInterceptor, createSignInPage, createSmartFetch, createUseCommand, createUseQuery, createVerifyEmailPage, handleToast, useAdmin, useDeviceInfo };
|
package/dist/client/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { cn, useDeviceInfo } from '../chunk-
|
|
1
|
+
import { Button, Spinner, InputGroup, InputGroupAddon, InputGroupInput, cn, Separator, Label, InputGroupButton, useDeviceInfo, Card, CardHeader, CardTitle, CardContent, useCountdown, CardDescription, useParentPathname, isConfirm } from '../chunk-FLKUBNE4.js';
|
|
2
|
+
export { cn, useDeviceInfo } from '../chunk-FLKUBNE4.js';
|
|
3
3
|
import { ensureArray } from '../chunk-OAENV763.js';
|
|
4
4
|
import { toast } from 'sonner';
|
|
5
5
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
6
6
|
import { useMutation, useQuery } from '@tanstack/react-query';
|
|
7
7
|
import { createContext, useState, useContext, useEffect, createElement } from 'react';
|
|
8
|
-
import { Asterisk, Eye, EyeOff, Mail } from 'lucide-react';
|
|
9
8
|
import { useTranslator } from 'intor/react';
|
|
9
|
+
import { Files, Asterisk, Eye, EyeOff, Mail, Trash2, CopyCheck, CopyX, FileSymlink, FileX, FilePlus, FilePen, File, FileStack, FolderSearch, Lock, FolderCog, FileSpreadsheet, Undo2 } from 'lucide-react';
|
|
10
10
|
import { useRouter, useSearchParams } from 'next/navigation';
|
|
11
11
|
import Link from 'next/link';
|
|
12
12
|
|
|
@@ -240,6 +240,364 @@ function createAdminInitializer({
|
|
|
240
240
|
return null;
|
|
241
241
|
};
|
|
242
242
|
}
|
|
243
|
+
|
|
244
|
+
// src/client/interfaces/styles/constants.ts
|
|
245
|
+
var PAGE_HEADER_HEIGHT = 56;
|
|
246
|
+
var FORM_SIDE_FIELDS_WIDTH = 320;
|
|
247
|
+
var FORM_MIDDLE_GAP_WIDTH = 24;
|
|
248
|
+
function PageHeaderTitle({
|
|
249
|
+
icon,
|
|
250
|
+
title,
|
|
251
|
+
subtitle,
|
|
252
|
+
children,
|
|
253
|
+
leftChildren,
|
|
254
|
+
className
|
|
255
|
+
}) {
|
|
256
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-3", className), children: [
|
|
257
|
+
leftChildren,
|
|
258
|
+
icon && createElement(icon),
|
|
259
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-center w-fit gap-3 whitespace-nowrap", children: [
|
|
260
|
+
subtitle && /* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: subtitle }),
|
|
261
|
+
/* @__PURE__ */ jsx("p", { className: "scroll-m-20 text-xl font-semibold tracking-tight", children: title })
|
|
262
|
+
] }),
|
|
263
|
+
children
|
|
264
|
+
] });
|
|
265
|
+
}
|
|
266
|
+
function Button2({
|
|
267
|
+
icon,
|
|
268
|
+
href,
|
|
269
|
+
openNewTab = false,
|
|
270
|
+
// ui states
|
|
271
|
+
isDisabled = false,
|
|
272
|
+
isLoading = false,
|
|
273
|
+
// base
|
|
274
|
+
children,
|
|
275
|
+
...props
|
|
276
|
+
}) {
|
|
277
|
+
const router = useRouter();
|
|
278
|
+
const handleClick = () => {
|
|
279
|
+
if (!href) return;
|
|
280
|
+
if (openNewTab) {
|
|
281
|
+
window.open(href, "_blank");
|
|
282
|
+
} else {
|
|
283
|
+
router.push(href);
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
return /* @__PURE__ */ jsx(
|
|
287
|
+
Button,
|
|
288
|
+
{
|
|
289
|
+
type: props.type ?? "button",
|
|
290
|
+
disabled: isDisabled || isLoading,
|
|
291
|
+
onClick: props.onClick ?? handleClick,
|
|
292
|
+
...props,
|
|
293
|
+
children: isLoading ? /* @__PURE__ */ jsx(Spinner, {}) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
294
|
+
icon && createElement(icon),
|
|
295
|
+
children
|
|
296
|
+
] })
|
|
297
|
+
}
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
function Input({
|
|
301
|
+
// form context
|
|
302
|
+
fieldName,
|
|
303
|
+
setFormData,
|
|
304
|
+
// ui states
|
|
305
|
+
isLoading = false,
|
|
306
|
+
isDisabled = false,
|
|
307
|
+
isError = false,
|
|
308
|
+
// base
|
|
309
|
+
children,
|
|
310
|
+
...props
|
|
311
|
+
}) {
|
|
312
|
+
return /* @__PURE__ */ jsxs(InputGroup, { "data-disabled": isDisabled || isLoading, children: [
|
|
313
|
+
isLoading ? /* @__PURE__ */ jsx(InputGroupAddon, { children: /* @__PURE__ */ jsx(Spinner, {}) }) : /* @__PURE__ */ jsx(
|
|
314
|
+
InputGroupInput,
|
|
315
|
+
{
|
|
316
|
+
disabled: isDisabled || isLoading,
|
|
317
|
+
"aria-invalid": isError,
|
|
318
|
+
onChange: (e) => {
|
|
319
|
+
if (!setFormData || !fieldName) return;
|
|
320
|
+
setFormData((p) => ({ ...p, [fieldName]: e.target.value }));
|
|
321
|
+
},
|
|
322
|
+
...props
|
|
323
|
+
}
|
|
324
|
+
),
|
|
325
|
+
children
|
|
326
|
+
] });
|
|
327
|
+
}
|
|
328
|
+
function ReturnButton({
|
|
329
|
+
icon,
|
|
330
|
+
useIcon = true,
|
|
331
|
+
// use in create/edit page
|
|
332
|
+
useConfirm = false,
|
|
333
|
+
// navigation
|
|
334
|
+
href,
|
|
335
|
+
replace = false,
|
|
336
|
+
pushToParent = false,
|
|
337
|
+
replaceParent = false,
|
|
338
|
+
// base
|
|
339
|
+
className,
|
|
340
|
+
children,
|
|
341
|
+
...props
|
|
342
|
+
}) {
|
|
343
|
+
const { t } = useTranslator();
|
|
344
|
+
const router = useRouter();
|
|
345
|
+
const parentPath = useParentPathname();
|
|
346
|
+
const handelClick = () => {
|
|
347
|
+
if (useConfirm) {
|
|
348
|
+
if (!isConfirm(t)) return;
|
|
349
|
+
}
|
|
350
|
+
if (href) {
|
|
351
|
+
return replace ? router.replace(href) : router.push(href);
|
|
352
|
+
}
|
|
353
|
+
if (replaceParent) {
|
|
354
|
+
return router.replace(parentPath);
|
|
355
|
+
}
|
|
356
|
+
if (pushToParent) {
|
|
357
|
+
return router.push(parentPath);
|
|
358
|
+
}
|
|
359
|
+
router.back();
|
|
360
|
+
};
|
|
361
|
+
return /* @__PURE__ */ jsx(
|
|
362
|
+
Button2,
|
|
363
|
+
{
|
|
364
|
+
variant: "outline",
|
|
365
|
+
size: "sm",
|
|
366
|
+
icon: useIcon ? icon || Undo2 : void 0,
|
|
367
|
+
onClick: handelClick,
|
|
368
|
+
className,
|
|
369
|
+
...props,
|
|
370
|
+
children: children ?? t("ui.button.return.text")
|
|
371
|
+
}
|
|
372
|
+
);
|
|
373
|
+
}
|
|
374
|
+
function createIndexPreset(ctx) {
|
|
375
|
+
const { props, t } = ctx;
|
|
376
|
+
return {
|
|
377
|
+
left: /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(ReturnButton, { pushToParent: true, ...props.returnButtonProps }) }),
|
|
378
|
+
titleProps: {
|
|
379
|
+
icon: Files,
|
|
380
|
+
children: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
381
|
+
props.settingButtonProps && props.showTopicSettingButton && /* @__PURE__ */ jsx(
|
|
382
|
+
Button2,
|
|
383
|
+
{
|
|
384
|
+
...props.settingButtonProps,
|
|
385
|
+
variant: "outline",
|
|
386
|
+
icon: FolderCog,
|
|
387
|
+
isDisabled: props.settingButtonProps.isDisabled ?? props.isDisabled,
|
|
388
|
+
children: `${t("ui.button.setting.text")} ${t("resources.topic.text")}`
|
|
389
|
+
}
|
|
390
|
+
),
|
|
391
|
+
props.createCategoryButtonProps && /* @__PURE__ */ jsx(
|
|
392
|
+
Button2,
|
|
393
|
+
{
|
|
394
|
+
...props.createCategoryButtonProps,
|
|
395
|
+
variant: "success",
|
|
396
|
+
icon: FileSpreadsheet,
|
|
397
|
+
isDisabled: props.createCategoryButtonProps.isDisabled ?? props.isDisabled,
|
|
398
|
+
children: t("ui.button.create.text")
|
|
399
|
+
}
|
|
400
|
+
),
|
|
401
|
+
props.createButtonProps && /* @__PURE__ */ jsx(
|
|
402
|
+
Button2,
|
|
403
|
+
{
|
|
404
|
+
variant: "success",
|
|
405
|
+
icon: FilePlus,
|
|
406
|
+
...props.createButtonProps,
|
|
407
|
+
children: t("ui.button.create.text")
|
|
408
|
+
}
|
|
409
|
+
)
|
|
410
|
+
] })
|
|
411
|
+
},
|
|
412
|
+
right: props.batchButtonProps && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Button2, { variant: "outline", icon: FileStack, ...props.batchButtonProps, children: /* @__PURE__ */ jsx("span", { className: "text-sm", children: t("ui.button.batch.text") }) }) })
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
function createBatchPreset(ctx) {
|
|
416
|
+
const { props, t } = ctx;
|
|
417
|
+
return {
|
|
418
|
+
left: /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(ReturnButton, { pushToParent: true, ...props.returnButtonProps, children: t("ui.button.exit-batch-mode.text") }) }),
|
|
419
|
+
titleProps: {
|
|
420
|
+
icon: FilePen,
|
|
421
|
+
subtitle: t("ui.page-header.batch.subtitle.text"),
|
|
422
|
+
children: /* @__PURE__ */ jsx(
|
|
423
|
+
Button2,
|
|
424
|
+
{
|
|
425
|
+
variant: "success",
|
|
426
|
+
href: props.batchCreateButtonHref,
|
|
427
|
+
icon: FilePlus,
|
|
428
|
+
children: t("ui.button.batch-create.text")
|
|
429
|
+
}
|
|
430
|
+
)
|
|
431
|
+
},
|
|
432
|
+
right: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
433
|
+
/* @__PURE__ */ jsx(Button2, { size: "icon", variant: "outline", onClick: props.selectAllFn, children: /* @__PURE__ */ jsx(CopyCheck, {}) }),
|
|
434
|
+
/* @__PURE__ */ jsx(Button2, { size: "icon", variant: "outline", onClick: props.cancelAllFn, children: /* @__PURE__ */ jsx(CopyX, {}) }),
|
|
435
|
+
/* @__PURE__ */ jsx(
|
|
436
|
+
Button2,
|
|
437
|
+
{
|
|
438
|
+
...props.destroyButtonProps,
|
|
439
|
+
variant: "destructive",
|
|
440
|
+
icon: FileX,
|
|
441
|
+
children: t("ui.button.destroy.text")
|
|
442
|
+
}
|
|
443
|
+
)
|
|
444
|
+
] })
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
function createBatchCreatePreset(ctx) {
|
|
448
|
+
const { props, t } = ctx;
|
|
449
|
+
return {
|
|
450
|
+
left: /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(ReturnButton, { useConfirm: true, replaceParent: true, ...props.returnButtonProps }) }),
|
|
451
|
+
titleProps: {
|
|
452
|
+
icon: FilePlus,
|
|
453
|
+
subtitle: t("ui.page-header.batch-create.subtitle.text")
|
|
454
|
+
}
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
function createCreatePreset(ctx) {
|
|
458
|
+
const { props, t } = ctx;
|
|
459
|
+
return {
|
|
460
|
+
left: /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(ReturnButton, { useConfirm: true, replaceParent: true, ...props.returnButtonProps }) }),
|
|
461
|
+
titleProps: {
|
|
462
|
+
icon: FilePlus,
|
|
463
|
+
subtitle: t("ui.page-header.create.subtitle.text")
|
|
464
|
+
}
|
|
465
|
+
};
|
|
466
|
+
}
|
|
467
|
+
function createEditPreset(ctx) {
|
|
468
|
+
const { props, t } = ctx;
|
|
469
|
+
return {
|
|
470
|
+
left: /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(ReturnButton, { useConfirm: true, replaceParent: true, ...props.returnButtonProps }) }),
|
|
471
|
+
titleProps: {
|
|
472
|
+
icon: FilePen,
|
|
473
|
+
subtitle: t("ui.page-header.edit.subtitle.text")
|
|
474
|
+
}
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
function createShowPreset(ctx) {
|
|
478
|
+
const { props, t } = ctx;
|
|
479
|
+
return {
|
|
480
|
+
left: /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(ReturnButton, { pushToParent: true, ...props.returnButtonProps }) }),
|
|
481
|
+
titleProps: {
|
|
482
|
+
icon: File,
|
|
483
|
+
children: !props.isNotFound && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
484
|
+
props.showButtonProps && /* @__PURE__ */ jsx(
|
|
485
|
+
Button2,
|
|
486
|
+
{
|
|
487
|
+
...props.showButtonProps,
|
|
488
|
+
variant: "outline",
|
|
489
|
+
icon: FolderSearch,
|
|
490
|
+
isDisabled: props.showButtonProps.isDisabled || props.isDisabled,
|
|
491
|
+
children: `${t("ui.button.show.text")} ${t("resources.related.text")}`
|
|
492
|
+
}
|
|
493
|
+
),
|
|
494
|
+
props.editButtonProps && /* @__PURE__ */ jsx(
|
|
495
|
+
Button2,
|
|
496
|
+
{
|
|
497
|
+
...props.editButtonProps,
|
|
498
|
+
variant: "warning",
|
|
499
|
+
icon: FilePen,
|
|
500
|
+
isDisabled: props.editButtonProps.isDisabled || props.isDisabled,
|
|
501
|
+
children: t("ui.button.edit.text")
|
|
502
|
+
}
|
|
503
|
+
),
|
|
504
|
+
props.destroyButtonProps && /* @__PURE__ */ jsx(
|
|
505
|
+
Button2,
|
|
506
|
+
{
|
|
507
|
+
...props.destroyButtonProps,
|
|
508
|
+
variant: "destructive",
|
|
509
|
+
icon: FileX,
|
|
510
|
+
isDisabled: props.destroyButtonProps.isDisabled || props.isDisabled,
|
|
511
|
+
children: t("ui.button.destroy.text")
|
|
512
|
+
}
|
|
513
|
+
),
|
|
514
|
+
/* @__PURE__ */ jsx(
|
|
515
|
+
Lock,
|
|
516
|
+
{
|
|
517
|
+
className: cn(
|
|
518
|
+
props.isLocked && !props.isDisabled ? "opacity-100" : "opacity-0"
|
|
519
|
+
)
|
|
520
|
+
}
|
|
521
|
+
)
|
|
522
|
+
] })
|
|
523
|
+
},
|
|
524
|
+
right: props.batchButtonProps && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Button2, { variant: "outline", icon: FileStack, ...props.batchButtonProps, children: /* @__PURE__ */ jsx("span", { className: "text-sm", children: t("ui.button.batch.text") }) }) })
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
function createTrashPreset(ctx) {
|
|
528
|
+
const { props, t } = ctx;
|
|
529
|
+
return {
|
|
530
|
+
left: /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(ReturnButton, { pushToParent: true, ...props.returnButtonProps }) }),
|
|
531
|
+
titleProps: {
|
|
532
|
+
icon: Trash2,
|
|
533
|
+
title: t("main.trash.text")
|
|
534
|
+
},
|
|
535
|
+
right: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
536
|
+
/* @__PURE__ */ jsx(Button2, { size: "icon", variant: "outline", onClick: props.selectAllFn, children: /* @__PURE__ */ jsx(CopyCheck, {}) }),
|
|
537
|
+
/* @__PURE__ */ jsx(Button2, { size: "icon", variant: "outline", onClick: props.cancelAllFn, children: /* @__PURE__ */ jsx(CopyX, {}) }),
|
|
538
|
+
/* @__PURE__ */ jsx(
|
|
539
|
+
Button2,
|
|
540
|
+
{
|
|
541
|
+
...props.restoreButtonProps,
|
|
542
|
+
variant: "success",
|
|
543
|
+
icon: FileSymlink,
|
|
544
|
+
children: t("ui.button.restore.text")
|
|
545
|
+
}
|
|
546
|
+
),
|
|
547
|
+
/* @__PURE__ */ jsx(
|
|
548
|
+
Button2,
|
|
549
|
+
{
|
|
550
|
+
...props.destroyButtonProps,
|
|
551
|
+
variant: "destructive",
|
|
552
|
+
icon: FileX,
|
|
553
|
+
children: t("ui.button.destroy.text")
|
|
554
|
+
}
|
|
555
|
+
)
|
|
556
|
+
] })
|
|
557
|
+
};
|
|
558
|
+
}
|
|
559
|
+
var PRESET_BUILDERS = {
|
|
560
|
+
default: () => ({ titleProps: { icon: Files } }),
|
|
561
|
+
index: createIndexPreset,
|
|
562
|
+
create: createCreatePreset,
|
|
563
|
+
show: createShowPreset,
|
|
564
|
+
edit: createEditPreset,
|
|
565
|
+
batch: createBatchPreset,
|
|
566
|
+
"batch-create": createBatchCreatePreset,
|
|
567
|
+
trash: createTrashPreset
|
|
568
|
+
};
|
|
569
|
+
function PageHeader(props) {
|
|
570
|
+
const { t } = useTranslator();
|
|
571
|
+
const variant = props.variant ?? "default";
|
|
572
|
+
const isDefault = variant === "default";
|
|
573
|
+
const preset = PRESET_BUILDERS[variant]({ props, t });
|
|
574
|
+
const left = props.leftChildren ?? preset.left;
|
|
575
|
+
const resolvedTitleProps = { ...preset.titleProps, ...props.titleProps };
|
|
576
|
+
const right = props.rightChildren ?? preset.right;
|
|
577
|
+
return /* @__PURE__ */ jsxs("div", { style: { height: PAGE_HEADER_HEIGHT }, children: [
|
|
578
|
+
/* @__PURE__ */ jsxs(
|
|
579
|
+
"div",
|
|
580
|
+
{
|
|
581
|
+
className: cn(
|
|
582
|
+
"relative h-full px-6",
|
|
583
|
+
"flex items-center justify-between gap-3"
|
|
584
|
+
),
|
|
585
|
+
children: [
|
|
586
|
+
!isDefault && left && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-3", children: left }),
|
|
587
|
+
/* @__PURE__ */ jsx(
|
|
588
|
+
PageHeaderTitle,
|
|
589
|
+
{
|
|
590
|
+
className: cn(!isDefault && "absolute left-1/2 -translate-x-1/2"),
|
|
591
|
+
...resolvedTitleProps
|
|
592
|
+
}
|
|
593
|
+
),
|
|
594
|
+
right && /* @__PURE__ */ jsx("div", { className: "ml-auto flex items-center gap-3", children: right })
|
|
595
|
+
]
|
|
596
|
+
}
|
|
597
|
+
),
|
|
598
|
+
/* @__PURE__ */ jsx(Separator, {})
|
|
599
|
+
] });
|
|
600
|
+
}
|
|
243
601
|
function Form({
|
|
244
602
|
onSubmit,
|
|
245
603
|
className,
|
|
@@ -327,67 +685,51 @@ function FieldBody({
|
|
|
327
685
|
}
|
|
328
686
|
);
|
|
329
687
|
}
|
|
330
|
-
function
|
|
331
|
-
|
|
332
|
-
href,
|
|
333
|
-
openNewTab = false,
|
|
334
|
-
// ui states
|
|
335
|
-
isDisabled = false,
|
|
336
|
-
isLoading = false,
|
|
337
|
-
// base
|
|
688
|
+
function FieldsContainer({
|
|
689
|
+
className = "",
|
|
338
690
|
children,
|
|
339
691
|
...props
|
|
340
692
|
}) {
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
693
|
+
return /* @__PURE__ */ jsx(
|
|
694
|
+
"div",
|
|
695
|
+
{
|
|
696
|
+
className: cn("relative flex w-full", className),
|
|
697
|
+
style: { gap: FORM_MIDDLE_GAP_WIDTH },
|
|
698
|
+
...props,
|
|
699
|
+
children
|
|
348
700
|
}
|
|
349
|
-
|
|
701
|
+
);
|
|
702
|
+
}
|
|
703
|
+
function MainFields({
|
|
704
|
+
className,
|
|
705
|
+
children,
|
|
706
|
+
...props
|
|
707
|
+
}) {
|
|
708
|
+
const sideWidth = FORM_SIDE_FIELDS_WIDTH + FORM_MIDDLE_GAP_WIDTH;
|
|
350
709
|
return /* @__PURE__ */ jsx(
|
|
351
|
-
|
|
710
|
+
"div",
|
|
352
711
|
{
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
onClick: props.onClick ?? handleClick,
|
|
712
|
+
className: cn("relative", "flex flex-1 flex-col gap-6", className),
|
|
713
|
+
style: { maxWidth: `calc(100% - ${sideWidth}px)` },
|
|
356
714
|
...props,
|
|
357
|
-
children
|
|
358
|
-
icon && createElement(icon),
|
|
359
|
-
children
|
|
360
|
-
] })
|
|
715
|
+
children
|
|
361
716
|
}
|
|
362
717
|
);
|
|
363
718
|
}
|
|
364
|
-
function
|
|
365
|
-
|
|
366
|
-
fieldName,
|
|
367
|
-
setFormData,
|
|
368
|
-
// ui states
|
|
369
|
-
isLoading = false,
|
|
370
|
-
isDisabled = false,
|
|
371
|
-
isError = false,
|
|
372
|
-
// base
|
|
719
|
+
function SideFields({
|
|
720
|
+
className,
|
|
373
721
|
children,
|
|
374
722
|
...props
|
|
375
723
|
}) {
|
|
376
|
-
return /* @__PURE__ */
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
},
|
|
386
|
-
...props
|
|
387
|
-
}
|
|
388
|
-
),
|
|
389
|
-
children
|
|
390
|
-
] });
|
|
724
|
+
return /* @__PURE__ */ jsx(
|
|
725
|
+
"div",
|
|
726
|
+
{
|
|
727
|
+
className: cn("relative", "min-h-full", className),
|
|
728
|
+
style: { width: `${FORM_SIDE_FIELDS_WIDTH}px` },
|
|
729
|
+
...props,
|
|
730
|
+
children: /* @__PURE__ */ jsx("div", { className: cn("sticky top-24", "flex flex-col gap-6"), children })
|
|
731
|
+
}
|
|
732
|
+
);
|
|
391
733
|
}
|
|
392
734
|
function PasswordInput({ ...props }) {
|
|
393
735
|
const [showPassword, setShowPassword] = useState(false);
|
|
@@ -879,4 +1221,4 @@ function createChangePasswordPage({
|
|
|
879
1221
|
};
|
|
880
1222
|
}
|
|
881
1223
|
|
|
882
|
-
export { AdminProvider, Button2 as Button, Field, FieldBody, Form, Input, PasswordInput, createAdminInitializer, createChangePasswordPage, createEmailUnverifiedPage, createForgotPasswordPage, createRequestInterceptor, createResetPasswordPage, createResponseInterceptor, createSignInPage, createSmartFetch, createUseCommand, createUseQuery, createVerifyEmailPage, handleToast, useAdmin };
|
|
1224
|
+
export { AdminProvider, Button2 as Button, Field, FieldBody, FieldsContainer, Form, Input, MainFields, PageHeader, PasswordInput, SideFields, createAdminInitializer, createChangePasswordPage, createEmailUnverifiedPage, createForgotPasswordPage, createRequestInterceptor, createResetPasswordPage, createResponseInterceptor, createSignInPage, createSmartFetch, createUseCommand, createUseQuery, createVerifyEmailPage, handleToast, useAdmin };
|
|
@@ -5,6 +5,7 @@ import * as React from 'react';
|
|
|
5
5
|
import { ComponentProps } from 'react';
|
|
6
6
|
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
7
7
|
import { VariantProps } from 'class-variance-authority';
|
|
8
|
+
import * as SeparatorPrimitive from '@radix-ui/react-separator';
|
|
8
9
|
import '@radix-ui/react-label';
|
|
9
10
|
|
|
10
11
|
declare function Card({ className, ...props }: React.ComponentProps<"div">): react_jsx_runtime.JSX.Element;
|
|
@@ -34,4 +35,6 @@ declare function Spinner({ className, ...props }: ComponentProps<"svg">): react_
|
|
|
34
35
|
|
|
35
36
|
declare function Textarea({ className, ...props }: React.ComponentProps<"textarea">): react_jsx_runtime.JSX.Element;
|
|
36
37
|
|
|
37
|
-
|
|
38
|
+
declare function Separator({ className, orientation, decorative, ...props }: React.ComponentProps<typeof SeparatorPrimitive.Root>): react_jsx_runtime.JSX.Element;
|
|
39
|
+
|
|
40
|
+
export { Button, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, Separator, Spinner, Textarea };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { Button, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, Label, Spinner, Textarea } from '../../chunk-
|
|
1
|
+
export { Button, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, Label, Separator, Spinner, Textarea } from '../../chunk-FLKUBNE4.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yimingliao/cms",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.96",
|
|
4
4
|
"author": "Yiming Liao",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
"dependencies": {
|
|
51
51
|
"@keyv/redis": "^5.1.6",
|
|
52
52
|
"@radix-ui/react-label": "^2.1.8",
|
|
53
|
+
"@radix-ui/react-separator": "^1.1.8",
|
|
53
54
|
"@radix-ui/react-slot": "^1.2.4",
|
|
54
55
|
"argon2": "^0.44.0",
|
|
55
56
|
"class-variance-authority": "^0.7.1",
|