Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Release Notes
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"coverage": "pnpm run test:unit && pnpm run test:components"
},
"dependencies": {
"@appflowyinc/editor": "^0.0.39",
"@appflowyinc/editor": "^0.0.40",
"@atlaskit/primitives": "^5.5.3",
"@emoji-mart/data": "^1.1.2",
"@emoji-mart/react": "^1.1.1",
Expand Down
8 changes: 4 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 10 additions & 3 deletions src/@types/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,7 @@
"onlyWorkspaceOwnerCanUpdateNamespace": "Only workspace owner can update the namespace",
"onlyWorkspaceOwnerCanRemoveHomepage": "Only workspace owner can remove the homepage",
"onlyWorkspaceOwnerCanChangeHomepage": "Only workspace owner can change the homepage",
"onlyProCanUpdateNamespace": "Only Pro Plan workspace owner can update the namespace",
"onlyProCanSetHomepage": "Only Pro Plan workspace owner can set the homepage",
"setHomepageFailed": "Failed to set homepage",
"namespaceTooLong": "The namespace is too long, please try another one",
Expand All @@ -522,6 +523,7 @@
"publishNameAlreadyInUse": "The path name is already in use, please try another one",
"namespaceContainsInvalidCharacters": "The namespace contains invalid character(s), please try another one",
"publishPermissionDenied": "Only the workspace owner or page publisher can manage the publish settings",
"unPublishPermissionDenied": "Only the workspace owner or page publisher can unpublish the page",
"publishNameCannotBeEmpty": "The path name cannot be empty, please try another one"
},
"success": {
Expand Down Expand Up @@ -3043,9 +3045,14 @@
"memberCount_one": "{{count}} member",
"memberCount_many": "{{count}} members",
"memberCount_other": "{{count}} members",
"aiMatch": "AI match",
"titleMatch": "Title match",
"AIsearch": "AI search",
"titleOnly": "Title only",
"namespace": "Namespace",
"manageNamespaceDescription": "Manage your namespace and homepage",
"homepage": "Homepage"
"homepage": "Homepage",
"recentPages": "Recent pages",
"searchResults": "Search results",
"noSearchResults": "No search results",
"AISearchPlaceholder": "Search or ask a question...",
"searchLabel": "Search"
}
16 changes: 12 additions & 4 deletions src/assets/published_with_changes.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 5 additions & 10 deletions src/assets/search.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 3 additions & 1 deletion src/components/_shared/outline/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ export function filterViews (views: View[], keyword: string): View[] {
for (const view of views) {
if (view.name.toLowerCase().includes(keyword.toLowerCase())) {
result.push(view);
} else if (view.children) {
}

if (view.children) {
const filteredChildren = filterAndFlatten(view.children);

result = result.concat(filteredChildren);
Expand Down
10 changes: 5 additions & 5 deletions src/components/_shared/popover/Popover.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { PopoverOrigin } from '@mui/material/Popover/Popover';
import isEqual from 'lodash-es/isEqual';
import React, { useEffect, useState } from 'react';
import React, { useCallback, useEffect, useState } from 'react';
import { Popover as PopoverComponent, PopoverProps as PopoverComponentProps } from '@mui/material';

const defaultProps: Partial<PopoverComponentProps> = {
Expand Down Expand Up @@ -33,7 +33,7 @@ const DEFAULT_ORIGINS: Origins = {
},
};

function calculateOptimalOrigins(
export function calculateOptimalOrigins (
position: Position,
popoverWidth: number,
popoverHeight: number,
Expand Down Expand Up @@ -103,7 +103,7 @@ function calculateOptimalOrigins(
};
}

export function Popover({
export function Popover ({
children,
transformOrigin = DEFAULT_ORIGINS.transformOrigin,
anchorOrigin = DEFAULT_ORIGINS.anchorOrigin,
Expand All @@ -119,7 +119,7 @@ export function Popover({
anchorOrigin,
});

const handleEntered = (element: HTMLElement) => {
const handleEntered = useCallback((element: HTMLElement) => {
const { width, height } = element.getBoundingClientRect();
let position: Position;

Expand All @@ -145,7 +145,7 @@ export function Popover({
);

setOrigins(newOrigins);
};
}, [anchorEl, anchorOrigin, anchorPosition, transformOrigin]);

useEffect(() => {
if (!adjustOrigins) {
Expand Down
12 changes: 6 additions & 6 deletions src/components/app/SideBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import React, { lazy } from 'react';
import { Workspaces } from '@/components/app/workspaces';
import Outline from 'src/components/app/outline/Outline';
import { UIVariant } from '@/application/types';
import { Search } from 'src/components/app/search';
// import { Search } from 'src/components/app/search';

const SideBarBottom = lazy(() => import('@/components/app/SideBarBottom'));

Expand All @@ -15,7 +15,7 @@ interface SideBarProps {
onResizeDrawerWidth: (width: number) => void;
}

function SideBar({
function SideBar ({
drawerWidth,
drawerOpened,
toggleOpenDrawer,
Expand All @@ -35,21 +35,21 @@ function SideBar({
open={drawerOpened}
variant={UIVariant.App}
onClose={() => toggleOpenDrawer(false)}
header={<Workspaces/>}
header={<Workspaces />}
onScroll={handleOnScroll}
>
<div
className={'flex w-full gap-1 flex-1 flex-col'}
>
<div
className={'px-[10px] bg-bg-base z-[1] flex-col gap-1.5 justify-around items-center sticky top-12'}
className={'px-[10px] bg-bg-base z-[1] flex-col gap-2 justify-around items-center sticky top-12'}
>
<Search />
{/*<Search />*/}
<div
style={{
borderColor: scrollTop > 10 ? 'var(--line-divider)' : undefined,
}}
className={'flex border-b pb-2 w-full border-transparent'}
className={'flex border-b pb-3 w-full border-transparent'}
>
<NewPage />
</div>
Expand Down
15 changes: 9 additions & 6 deletions src/components/app/app.hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {
YjsEditorKey,
YSharedRoot,
} from '@/application/types';
import { notify } from '@/components/_shared/notify';
import { findAncestors, findView, findViewByLayout } from '@/components/_shared/outline/utils';
import RequestAccess from '@/components/app/landing-pages/RequestAccess';
import { AFConfigContext, useService } from '@/components/main/app.hooks';
Expand Down Expand Up @@ -404,12 +403,14 @@ export const AppProvider = ({ children }: { children: React.ReactNode }) => {

const views = uniqBy(res, 'view_id');

setRecentViews(views);
setRecentViews(views.filter(item => {
return !item.extra?.is_space && findView(outline || [], item.view_id);
}));
return views;
} catch (e) {
console.error('Recent views not found');
}
}, [currentWorkspaceId, service]);
}, [currentWorkspaceId, service, outline]);

const loadTrash = useCallback(async (currentWorkspaceId: string) => {

Expand Down Expand Up @@ -648,18 +649,20 @@ export const AppProvider = ({ children }: { children: React.ReactNode }) => {
if (!service || !currentWorkspaceId) return;
const isDatabase = [ViewLayout.Board, ViewLayout.Grid, ViewLayout.Calendar].includes(view.layout);
const viewId = view.view_id;
const children = view.children || [];
const visibleViewIds = [view.view_id, ...(children.map((v) => v.view_id))];

await service.publishView(currentWorkspaceId, viewId, {
publish_name: publishName,
visible_database_view_ids: isDatabase ? view.children?.map((v) => v.view_id) : undefined,
visible_database_view_ids: isDatabase ? visibleViewIds : undefined,
});
void loadOutline(currentWorkspaceId, false);
await loadOutline(currentWorkspaceId, false);
}, [currentWorkspaceId, loadOutline, service]);

const unpublish = useCallback(async (viewId: string) => {
if (!service || !currentWorkspaceId) return;
await service.unpublishView(currentWorkspaceId, viewId);
void loadOutline(currentWorkspaceId, false);
await loadOutline(currentWorkspaceId, false);
}, [currentWorkspaceId, loadOutline, service]);

return <AppContext.Provider
Expand Down
4 changes: 2 additions & 2 deletions src/components/app/publish-manage/PublishManage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export function PublishManage ({
setLoading(true);
try {
const outline = await service.getPublishOutline(namespace);

setPublishViews(flattenViews(outline).filter(item => item.is_published));
// eslint-disable-next-line
} catch (e: any) {
Expand Down Expand Up @@ -241,7 +241,7 @@ export function PublishManage ({
onUpdateHomePage={handleUpdateHomePage}
/>
<Tooltip
title={isOwner ? (activeSubscription === SubscriptionPlan.Free ? t('settings.sites.error.onlyProCanSetHomepage') : undefined)
title={isOwner ? (activeSubscription === SubscriptionPlan.Free ? t('settings.sites.error.onlyProCanUpdateNamespace') : undefined)
: t('settings.sites.error.onlyWorkspaceOwnerCanUpdateNamespace')}
>
<IconButton
Expand Down
3 changes: 2 additions & 1 deletion src/components/app/publish-manage/PublishedPageItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ function PublishedPageItem ({ onClose, view, onUnPublish, onPublish }: {
value: 'unpublish',
disabled: unPublishLoading,
label: t('shareAction.unPublish'),
tooltip: !(isOwner || isPublisher) ? t('settings.sites.error.publishPermissionDenied') : undefined,
tooltip: !(isOwner || isPublisher) ? t('settings.sites.error.unPublishPermissionDenied') : undefined,
IconComponent: unPublishLoading ? CircularProgress : TrashIcon,
onClick: async () => {
if (!(isOwner || isPublisher)) {
Expand All @@ -109,6 +109,7 @@ function PublishedPageItem ({ onClose, view, onUnPublish, onPublish }: {
IconComponent: SettingIcon,
onClick: () => {
if (!(isOwner || isPublisher)) return;
setAnchorEl(null);
setOpenSetting(true);
},
},
Expand Down
32 changes: 20 additions & 12 deletions src/components/app/search/BestMatch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,24 @@ import { findView } from '@/components/_shared/outline/utils';
import { useAppOutline, useCurrentWorkspaceId } from '@/components/app/app.hooks';
import ViewList from '@/components/app/search/ViewList';
import { useService } from '@/components/main/app.hooks';
import { debounce } from 'lodash-es';
import { debounce, uniq } from 'lodash-es';
import React, { useCallback, useEffect, useMemo } from 'react';
import { useTranslation } from 'react-i18next';

function BestMatch ({
onClose,
searchValue
searchValue,
}: {
onClose: () => void;
searchValue: string;
}) {
const [views, setViews] = React.useState<View[]>([]);
const [views, setViews] = React.useState<View[] | undefined>(undefined);
const { t } = useTranslation();
const outline = useAppOutline();
const [loading, setLoading] = React.useState<boolean>(false);
const service = useService();
const currentWorkspaceId = useCurrentWorkspaceId()
const [loading, setLoading] = React.useState<boolean>(false);

const currentWorkspaceId = useCurrentWorkspaceId();
const handleSearch = useCallback(async (searchTerm: string) => {
if (!outline) return;
if (!currentWorkspaceId || !service) return;
Expand All @@ -29,34 +30,41 @@ function BestMatch ({
return;
}

setLoading(true)
setLoading(true);

try {
const res = await service.searchWorkspace(currentWorkspaceId, searchTerm);
const views = res.map(id => {
const views = uniq(res).map(id => {
return findView(outline, id);
});

setViews(views.filter(Boolean) as View[]);
setViews(views.filter(item => {
if (!item) return false;
return !item.extra?.is_space;
}) as View[]);
// eslint-disable-next-line
} catch (e: any) {
notify.error(e.message);
}

setLoading(false);

}, [currentWorkspaceId, outline, service]);

const debounceSearch = useMemo(() => {
return debounce(handleSearch, 300);
}, [handleSearch]);

useEffect(() => {
void debounceSearch(searchValue);
}, [searchValue, debounceSearch]);


return <ViewList views={views} title={t('commandPalette.bestMatches')} onClose={onClose} loading={loading} />
return <ViewList
views={views}
loading={loading}
title={t('searchResults')}
onClose={onClose}
/>;
}

export default BestMatch;
Loading
Loading