mirror of
https://github.com/logto-io/logto.git
synced 2024-12-30 20:33:54 -05:00
feat(console): support searching for organization roles (#5646)
This commit is contained in:
parent
bf471e1451
commit
756c2f472c
2 changed files with 46 additions and 24 deletions
|
@ -8,6 +8,6 @@
|
||||||
|
|
||||||
.filter {
|
.filter {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row-reverse;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import { type OrganizationRoleWithScopes } from '@logto/schemas';
|
import { type OrganizationRoleWithScopes } from '@logto/schemas';
|
||||||
|
import { cond } from '@silverhand/essentials';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
import useSWR from 'swr';
|
import useSWR from 'swr';
|
||||||
|
|
||||||
import Plus from '@/assets/icons/plus.svg';
|
import Plus from '@/assets/icons/plus.svg';
|
||||||
|
@ -7,11 +9,13 @@ import OrgRoleIcon from '@/assets/icons/role-feature.svg';
|
||||||
import RolesEmptyDark from '@/assets/images/roles-empty-dark.svg';
|
import RolesEmptyDark from '@/assets/images/roles-empty-dark.svg';
|
||||||
import RolesEmpty from '@/assets/images/roles-empty.svg';
|
import RolesEmpty from '@/assets/images/roles-empty.svg';
|
||||||
import Breakable from '@/components/Breakable';
|
import Breakable from '@/components/Breakable';
|
||||||
|
import EmptyDataPlaceholder from '@/components/EmptyDataPlaceholder';
|
||||||
import ItemPreview from '@/components/ItemPreview';
|
import ItemPreview from '@/components/ItemPreview';
|
||||||
import ThemedIcon from '@/components/ThemedIcon';
|
import ThemedIcon from '@/components/ThemedIcon';
|
||||||
import { defaultPageSize, organizationRoleLink } from '@/consts';
|
import { defaultPageSize, organizationRoleLink } from '@/consts';
|
||||||
import Button from '@/ds-components/Button';
|
import Button from '@/ds-components/Button';
|
||||||
import DynamicT from '@/ds-components/DynamicT';
|
import DynamicT from '@/ds-components/DynamicT';
|
||||||
|
import Search from '@/ds-components/Search';
|
||||||
import Table from '@/ds-components/Table';
|
import Table from '@/ds-components/Table';
|
||||||
import TablePlaceholder from '@/ds-components/Table/TablePlaceholder';
|
import TablePlaceholder from '@/ds-components/Table/TablePlaceholder';
|
||||||
import Tag from '@/ds-components/Tag';
|
import Tag from '@/ds-components/Tag';
|
||||||
|
@ -19,16 +23,18 @@ import { type RequestError } from '@/hooks/use-api';
|
||||||
import useDocumentationUrl from '@/hooks/use-documentation-url';
|
import useDocumentationUrl from '@/hooks/use-documentation-url';
|
||||||
import useSearchParametersWatcher from '@/hooks/use-search-parameters-watcher';
|
import useSearchParametersWatcher from '@/hooks/use-search-parameters-watcher';
|
||||||
import useTenantPathname from '@/hooks/use-tenant-pathname';
|
import useTenantPathname from '@/hooks/use-tenant-pathname';
|
||||||
import { buildUrl } from '@/utils/url';
|
import { buildUrl, formatSearchKeyword } from '@/utils/url';
|
||||||
|
|
||||||
import CreateOrganizationRoleModal from './CreateOrganizationRoleModal';
|
import CreateOrganizationRoleModal from './CreateOrganizationRoleModal';
|
||||||
import * as styles from './index.module.scss';
|
import * as styles from './index.module.scss';
|
||||||
|
|
||||||
function OrganizationRoles() {
|
function OrganizationRoles() {
|
||||||
|
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||||
const { getDocumentationUrl } = useDocumentationUrl();
|
const { getDocumentationUrl } = useDocumentationUrl();
|
||||||
const { navigate } = useTenantPathname();
|
const { navigate } = useTenantPathname();
|
||||||
const [{ page }, updateSearchParameters] = useSearchParametersWatcher({
|
const [{ page, keyword }, updateSearchParameters] = useSearchParametersWatcher({
|
||||||
page: 1,
|
page: 1,
|
||||||
|
keyword: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
const { data, error, mutate, isLoading } = useSWR<
|
const { data, error, mutate, isLoading } = useSWR<
|
||||||
|
@ -38,6 +44,7 @@ function OrganizationRoles() {
|
||||||
buildUrl('api/organization-roles', {
|
buildUrl('api/organization-roles', {
|
||||||
page: String(page),
|
page: String(page),
|
||||||
page_size: String(defaultPageSize),
|
page_size: String(defaultPageSize),
|
||||||
|
...cond(keyword && { q: formatSearchKeyword(keyword) }),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -83,6 +90,17 @@ function OrganizationRoles() {
|
||||||
}}
|
}}
|
||||||
filter={
|
filter={
|
||||||
<div className={styles.filter}>
|
<div className={styles.filter}>
|
||||||
|
<Search
|
||||||
|
placeholder={t('organization_template.roles.search_placeholder')}
|
||||||
|
defaultValue={keyword}
|
||||||
|
isClearable={Boolean(keyword)}
|
||||||
|
onSearch={(keyword) => {
|
||||||
|
updateSearchParameters({ keyword });
|
||||||
|
}}
|
||||||
|
onClearSearch={() => {
|
||||||
|
updateSearchParameters({ keyword: '' });
|
||||||
|
}}
|
||||||
|
/>
|
||||||
<Button
|
<Button
|
||||||
title="organization_template.roles.create_title"
|
title="organization_template.roles.create_title"
|
||||||
type="primary"
|
type="primary"
|
||||||
|
@ -94,27 +112,31 @@ function OrganizationRoles() {
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
placeholder={
|
placeholder={
|
||||||
<TablePlaceholder
|
keyword ? (
|
||||||
image={<RolesEmpty />}
|
<EmptyDataPlaceholder />
|
||||||
imageDark={<RolesEmptyDark />}
|
) : (
|
||||||
title="organization_template.roles.placeholder_title"
|
<TablePlaceholder
|
||||||
description="organization_template.roles.placeholder_description"
|
image={<RolesEmpty />}
|
||||||
learnMoreLink={{
|
imageDark={<RolesEmptyDark />}
|
||||||
href: getDocumentationUrl(organizationRoleLink),
|
title="organization_template.roles.placeholder_title"
|
||||||
targetBlank: 'noopener',
|
description="organization_template.roles.placeholder_description"
|
||||||
}}
|
learnMoreLink={{
|
||||||
action={
|
href: getDocumentationUrl(organizationRoleLink),
|
||||||
<Button
|
targetBlank: 'noopener',
|
||||||
title="organization_template.roles.create_title"
|
}}
|
||||||
type="primary"
|
action={
|
||||||
size="large"
|
<Button
|
||||||
icon={<Plus />}
|
title="organization_template.roles.create_title"
|
||||||
onClick={() => {
|
type="primary"
|
||||||
setIsCreateModalOpen(true);
|
size="large"
|
||||||
}}
|
icon={<Plus />}
|
||||||
/>
|
onClick={() => {
|
||||||
}
|
setIsCreateModalOpen(true);
|
||||||
/>
|
}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
pagination={{
|
pagination={{
|
||||||
page,
|
page,
|
||||||
|
|
Loading…
Reference in a new issue