@rnaga/wp-next-admin 1.0.1 → 1.0.2

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.
@@ -39,6 +39,7 @@ export declare const Admin: {
39
39
  List: () => import("react/jsx-runtime").JSX.Element;
40
40
  Edit: (props?: {
41
41
  userId?: number;
42
+ isProfile?: boolean;
42
43
  }) => import("react/jsx-runtime").JSX.Element | null;
43
44
  Delete: () => import("react/jsx-runtime").JSX.Element | null;
44
45
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/client/components/contents/index.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAQhB,CAAC;;;;CAMF,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/client/components/contents/index.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAejB,CAAC;qBAAmB,CAAC;;;;CADrB,CAAC"}
@@ -3,5 +3,5 @@ import { Users } from "../../../components/contents/users";
3
3
  import { useUser } from "@rnaga/wp-next-core/client/hooks/use-user";
4
4
  export const Profile = () => {
5
5
  const { user } = useUser();
6
- return _jsx(Users.Edit, { userId: user?.ID });
6
+ return _jsx(Users.Edit, { userId: user?.ID, isProfile: true });
7
7
  };
@@ -0,0 +1,5 @@
1
+ import type * as wpCoreTypes from "@rnaga/wp-next-core/types";
2
+ export declare const ActionLink: (props: {
3
+ password: wpCoreTypes.actions.ApplicationPasswords[number];
4
+ }) => import("react/jsx-runtime").JSX.Element;
5
+ //# sourceMappingURL=ActionLink.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ActionLink.d.ts","sourceRoot":"","sources":["../../../../../../../src/client/components/contents/users/Edit/ApplicationPasswords/ActionLink.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,WAAW,MAAM,2BAA2B,CAAC;AAU9D,eAAO,MAAM,UAAU,GAAI,OAAO;IAChC,QAAQ,EAAE,WAAW,CAAC,OAAO,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;CAC5D,4CAwCA,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Box } from "@mui/material";
3
+ import { useServerActions } from "@rnaga/wp-next-core/client/hooks/use-server-actions";
4
+ import { useWPAdmin } from "../../../../../wp-admin";
5
+ import { useAdminNavigation } from "../../../../../hooks/use-admin-navigation";
6
+ import { AdminLink } from "../../../../../components/utils/link";
7
+ export const ActionLink = (props) => {
8
+ const { password } = props;
9
+ const { overlay } = useWPAdmin();
10
+ const { refresh } = useAdminNavigation();
11
+ const { actions, safeParse } = useServerActions();
12
+ const handleDelete = (uuid) => () => {
13
+ if (!password) {
14
+ return;
15
+ }
16
+ const message = "This action cannot be undone. This will permanently delete your item.";
17
+ const title = "Are you absolutely sure?";
18
+ overlay.confirm.open(message, async (confirm) => {
19
+ if (!confirm) {
20
+ return;
21
+ }
22
+ const result = await overlay.circular
23
+ .promise(actions.applicationPasswords.del(uuid))
24
+ .then(safeParse);
25
+ if (!result.success) {
26
+ overlay.snackbar.open("error", result.error);
27
+ return;
28
+ }
29
+ overlay.snackbar.open("success", "Item has been deleted Permanently");
30
+ refresh(["content"]);
31
+ }, title);
32
+ };
33
+ return (_jsx(Box, { sx: { display: "flex", gap: 0.5 }, children: _jsx(AdminLink, { color: "error", onClick: handleDelete(password.uuid), children: "Delete" }) }));
34
+ };
@@ -0,0 +1,6 @@
1
+ export declare const Create: (props: {
2
+ open: boolean;
3
+ onClose: () => void;
4
+ onCreate: () => void;
5
+ }) => import("react/jsx-runtime").JSX.Element;
6
+ //# sourceMappingURL=Create.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Create.d.ts","sourceRoot":"","sources":["../../../../../../../src/client/components/contents/users/Edit/ApplicationPasswords/Create.tsx"],"names":[],"mappings":"AAWA,eAAO,MAAM,MAAM,GAAI,OAAO;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB,4CAmGA,CAAC"}
@@ -0,0 +1,47 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { FormControl, FormLabel, Stack } from "@mui/material";
4
+ import { useServerActions } from "@rnaga/wp-next-core/client/hooks";
5
+ import { Button } from "@rnaga/wp-next-ui/Button";
6
+ import { useFormData } from "@rnaga/wp-next-ui/hooks/use-form-data";
7
+ import { Input } from "@rnaga/wp-next-ui/Input";
8
+ import { LinkCopy } from "@rnaga/wp-next-ui/LinkCopy";
9
+ import { Modal, ModalContent } from "@rnaga/wp-next-ui/Modal";
10
+ import { Typography } from "@rnaga/wp-next-ui/Typography";
11
+ export const Create = (props) => {
12
+ const { open, onClose, onCreate } = props;
13
+ const [loading, setLoading] = useState(false);
14
+ const { actions, safeParse } = useServerActions();
15
+ const { formData, setFormData, submit } = useFormData("application-password");
16
+ const [response, setResponse] = useState();
17
+ const handleSubmit = async (data) => {
18
+ setLoading(true);
19
+ const response = await actions.applicationPasswords
20
+ .create(data)
21
+ .then(safeParse);
22
+ if (response.success) {
23
+ setResponse({ success: true, data: response.data });
24
+ onCreate();
25
+ }
26
+ else {
27
+ setResponse({
28
+ success: false,
29
+ error: response.error || "Failed to create application password",
30
+ });
31
+ }
32
+ setLoading(false);
33
+ };
34
+ return (_jsx(Modal, { open: open, onClose: onClose, children: _jsxs(ModalContent, { sx: {
35
+ minWidth: 400,
36
+ }, children: [_jsx(Typography, { bold: true, fontSize: 18, mb: 2, children: "Create New Password" }), response?.error && (_jsx(Typography, { color: "error", mb: 2, children: response.error })), response?.success && response.data && (_jsxs(_Fragment, { children: [_jsx(Typography, { mb: 2, size: "medium", children: "Please copy your new application password." }), _jsxs(Typography, { sx: {
37
+ wordBreak: "break-all",
38
+ p: 2,
39
+ backgroundColor: (theme) => theme.palette.mode === "light"
40
+ ? "rgba(0,0,0,.05)"
41
+ : "rgba(255,255,255,.05)",
42
+ borderRadius: 1,
43
+ display: "flex",
44
+ justifyContent: "space-between",
45
+ alignItems: "center",
46
+ }, children: [response.data.password, _jsx(LinkCopy, { link: response.data.password, showIcon: true })] })] })), !response && (_jsx("form", { onSubmit: submit(handleSubmit), children: _jsxs(Stack, { spacing: 2, children: [_jsxs(FormControl, { children: [_jsx(FormLabel, { required: true, children: "Name" }), _jsx(Input, { size: "medium", name: "name", value: formData?.name, required: true })] }), _jsx(Button, { size: "medium", type: "submit", loading: loading, children: "Submit" })] }) }))] }) }));
47
+ };
@@ -0,0 +1,2 @@
1
+ export declare const ApplicationPasswords: () => import("react/jsx-runtime").JSX.Element | null;
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../src/client/components/contents/users/Edit/ApplicationPasswords/index.tsx"],"names":[],"mappings":"AAeA,eAAO,MAAM,oBAAoB,sDAyGhC,CAAC"}
@@ -0,0 +1,57 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useEffect, useMemo, useState, useTransition } from "react";
3
+ import { useWPAdmin } from "@/client/wp-admin";
4
+ import { Box } from "@mui/material";
5
+ import { useServerActions, useUser } from "@rnaga/wp-next-core/client/hooks";
6
+ import { Button } from "@rnaga/wp-next-ui/Button";
7
+ import { ActionTd, Table, Td, Th, THead, Tr } from "@rnaga/wp-next-ui/list";
8
+ import { Loading } from "@rnaga/wp-next-ui/Loading";
9
+ import { Typography } from "@rnaga/wp-next-ui/Typography";
10
+ import { ActionLink } from "./ActionLink";
11
+ import { Create } from "./Create";
12
+ export const ApplicationPasswords = () => {
13
+ const { user } = useUser();
14
+ const { overlay, wp: { error }, } = useWPAdmin();
15
+ const { actions, safeParse } = useServerActions();
16
+ const [passwords, setPasswords] = useState([]);
17
+ const [openCreate, setOpenCreate] = useState(false);
18
+ const [loading, startTransition] = useTransition();
19
+ const userId = useMemo(() => user?.ID, [user?.ID]);
20
+ const fetchPasswords = async () => {
21
+ if (!userId) {
22
+ return;
23
+ }
24
+ startTransition(async () => {
25
+ const response = await actions.applicationPasswords
26
+ .list()
27
+ .then(safeParse);
28
+ if (!response.success || !response.data) {
29
+ error.throw(response.error ?? "Failed to get user data");
30
+ }
31
+ setPasswords(response.data);
32
+ });
33
+ };
34
+ useEffect(() => {
35
+ if (!userId) {
36
+ return;
37
+ }
38
+ fetchPasswords();
39
+ }, [userId]);
40
+ if (!userId) {
41
+ return null;
42
+ }
43
+ return (_jsxs(_Fragment, { children: [_jsx(Create, { open: openCreate, onClose: () => {
44
+ setOpenCreate(false);
45
+ }, onCreate: () => {
46
+ fetchPasswords();
47
+ } }), _jsx(Box, { sx: {
48
+ display: "flex",
49
+ justifyContent: "flex-end",
50
+ }, children: _jsx(Button, { onClick: () => setOpenCreate(true), children: "Create New Password" }) }), _jsx(Loading, { loading: loading, children: _jsxs(Table, { sx: {
51
+ mt: 2,
52
+ }, children: [_jsxs(THead, { children: [_jsx(Th, { viewport: "desktop", children: "Name" }), _jsx(Th, { viewport: "desktop", children: "Created" }), _jsx(Th, { viewport: "desktop", children: "Last Used" }), _jsx(Th, { viewport: "desktop", children: "Last IP" })] }), _jsx("tbody", { children: passwords.map((password) => (_jsxs(Tr, { children: [_jsxs(ActionTd, { viewport: "desktop", style: {
53
+ minWidth: 200,
54
+ }, children: [_jsx(Typography, { size: "medium", bold: true, children: password.name }), _jsx(ActionLink, { password: password })] }), _jsx(Td, { children: new Date(password.created * 1000).toLocaleString() }), _jsx(Td, { children: password.last_used
55
+ ? new Date(password.last_used * 1000).toLocaleString()
56
+ : "Never" }), _jsx(Td, { children: password.last_ip || "Unknown" })] }, password.uuid))) })] }) })] }));
57
+ };
@@ -1,4 +1,5 @@
1
1
  export declare const Edit: (props?: {
2
2
  userId?: number;
3
+ isProfile?: boolean;
3
4
  }) => import("react/jsx-runtime").JSX.Element | null;
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/client/components/contents/users/Edit/index.tsx"],"names":[],"mappings":"AAaA,eAAO,MAAM,IAAI,GAAI,QAAQ;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,mDA6E/C,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/client/components/contents/users/Edit/index.tsx"],"names":[],"mappings":"AAcA,eAAO,MAAM,IAAI,GAAI,QAAQ;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,mDA4FpE,CAAC"}
@@ -7,11 +7,12 @@ import { useUser } from "@rnaga/wp-next-core/client/hooks/use-user";
7
7
  import { Tabs } from "@rnaga/wp-next-ui/Tabs";
8
8
  import { useAdminNavigation } from "../../../../hooks/use-admin-navigation";
9
9
  import { useWPAdmin } from "../../../../wp-admin";
10
+ import { ApplicationPasswords } from "./ApplicationPasswords";
10
11
  import { Profile } from "./Profile";
11
12
  import { Roles } from "./Roles/";
12
13
  export const Edit = (props) => {
13
- const { overlay } = useWPAdmin();
14
14
  const { user } = useUser();
15
+ const { site } = useWPAdmin();
15
16
  const { searchParams, refreshValue } = useAdminNavigation();
16
17
  const { actions, safeParse } = useServerActions();
17
18
  const [canEditUser, setCanEditUser] = useState();
@@ -37,14 +38,25 @@ export const Edit = (props) => {
37
38
  }, []);
38
39
  const canUpdateRole = useMemo(() => user?.role.capabilities.has("promote_user") ||
39
40
  user?.role.capabilities.has("remove_users"), [user?.role.capabilities]);
41
+ const canManageApplicationPasswords = useMemo(() => props?.isProfile === true &&
42
+ (user?.role.capabilities.has("edit_users") ||
43
+ (site.isMultiSite && user?.role.names.has("superadmin")) ||
44
+ (!site.isMultiSite && user?.role.names.has("administrator"))), [user?.role.capabilities, props?.isProfile]);
40
45
  if (canEditUser === undefined) {
41
46
  return null;
42
47
  }
43
- console.log("user.role.capabilities", user?.role.capabilities);
44
48
  const tabItems = [
45
49
  ...(canEditUser
46
50
  ? [{ label: "Profile", content: _jsx(Profile, { userId: userId }) }]
47
51
  : []),
52
+ ...(canManageApplicationPasswords
53
+ ? [
54
+ {
55
+ label: "Application Passwords",
56
+ content: _jsx(ApplicationPasswords, {}, `ap-${refreshContent}`),
57
+ },
58
+ ]
59
+ : []),
48
60
  ...(canUpdateRole
49
61
  ? [
50
62
  {
@@ -3,6 +3,7 @@ export declare const Users: {
3
3
  List: () => import("react/jsx-runtime").JSX.Element;
4
4
  Edit: (props?: {
5
5
  userId?: number;
6
+ isProfile?: boolean;
6
7
  }) => import("react/jsx-runtime").JSX.Element | null;
7
8
  Delete: () => import("react/jsx-runtime").JSX.Element | null;
8
9
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/client/components/contents/users/index.tsx"],"names":[],"mappings":"AAKA,eAAO,MAAM,KAAK;;;;cAM0V,CAAC;;;CAD5W,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/client/components/contents/users/index.tsx"],"names":[],"mappings":"AAKA,eAAO,MAAM,KAAK;;;;cAMyZ,CAAC;iBAAmB,CAAC;;;CAD/b,CAAC"}
@@ -2,6 +2,7 @@ import * as actionsDashboard from "../../server/actions/dashboard";
2
2
  export declare const useAdminServerActions: () => {
3
3
  actions: {
4
4
  dashboard: typeof actionsDashboard;
5
+ applicationPasswords: typeof import("@rnaga/wp-next-core/server/actions/application-passwords");
5
6
  adminUser: typeof import("@rnaga/wp-next-core/server/actions/admin-user");
6
7
  site: typeof import("@rnaga/wp-next-core/server/actions/site");
7
8
  user: typeof import("@rnaga/wp-next-core/server/actions/user");
@@ -1 +1 @@
1
- {"version":3,"file":"use-admin-server-actions.d.ts","sourceRoot":"","sources":["../../../src/client/hooks/use-admin-server-actions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,gBAAgB,MAAM,gCAAgC,CAAC;AAInE,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAYjC,CAAC"}
1
+ {"version":3,"file":"use-admin-server-actions.d.ts","sourceRoot":"","sources":["../../../src/client/hooks/use-admin-server-actions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,gBAAgB,MAAM,gCAAgC,CAAC;AAInE,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAYjC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rnaga/wp-next-admin",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "license": "MIT",
5
5
  "description": "Admin interface for WP Next",
6
6
  "author": "Ryohei Nagatsuka",