mirror of
https://github.com/toeverything/AFFiNE.git
synced 2024-12-22 10:21:37 +03:00
fix: resolve cycle imports and prevent it by oxlint (#5103)
This commit is contained in:
parent
b73e87e4ad
commit
a843dcd851
@ -205,6 +205,7 @@ const config = {
|
||||
},
|
||||
],
|
||||
'unicorn/no-unnecessary-await': 'error',
|
||||
'unicorn/no-useless-fallback-in-spread': 'error',
|
||||
'sonarjs/no-all-duplicated-branches': 'error',
|
||||
'sonarjs/no-element-overwrite': 'error',
|
||||
'sonarjs/no-empty-collection': 'error',
|
||||
|
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@ -44,7 +44,7 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Run oxlint
|
||||
# oxlint is fast, so wrong code will fail quickly
|
||||
run: yarn dlx oxlint@latest .
|
||||
run: yarn dlx $(node -e "console.log(require('./package.json').scripts['lint:ox'])")
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
@ -58,8 +58,6 @@ jobs:
|
||||
run: |
|
||||
git checkout .yarnrc.yml
|
||||
yarn lint:prettier
|
||||
- name: Run circular
|
||||
run: yarn circular
|
||||
- name: Run Type Check
|
||||
run: yarn typecheck
|
||||
|
||||
|
@ -1,23 +1,4 @@
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
# check lockfile is up to date
|
||||
yarn install --mode=skip-build --inline-builds --immutable
|
||||
|
||||
# build infra code
|
||||
yarn -T run build:infra
|
||||
|
||||
# generate prisma client type
|
||||
yarn workspace @affine/server prisma generate
|
||||
|
||||
# generate i18n
|
||||
yarn i18n-codegen gen
|
||||
|
||||
# lint staged files
|
||||
yarn exec lint-staged
|
||||
|
||||
# type check
|
||||
yarn typecheck
|
||||
|
||||
# circular dependency check
|
||||
yarn circular
|
||||
yarn lint:ox
|
||||
|
@ -33,6 +33,7 @@
|
||||
"lint:eslint:fix": "yarn lint:eslint --fix",
|
||||
"lint:prettier": "prettier --ignore-unknown --cache --check .",
|
||||
"lint:prettier:fix": "prettier --ignore-unknown --cache --write .",
|
||||
"lint:ox": "oxlint --deny-warnings --import-plugin -D correctness -D nursery -A no-undef -A consistent-type-exports -A default -A named -A ban-ts-comment",
|
||||
"lint": "yarn lint:eslint && yarn lint:prettier",
|
||||
"lint:fix": "yarn lint:eslint:fix && yarn lint:prettier:fix",
|
||||
"test": "vitest --run",
|
||||
@ -49,7 +50,6 @@
|
||||
"eslint --cache --fix"
|
||||
],
|
||||
"*.toml": [
|
||||
"prettier --ignore-unknown --write",
|
||||
"taplo format"
|
||||
]
|
||||
},
|
||||
@ -93,12 +93,12 @@
|
||||
"happy-dom": "^12.10.3",
|
||||
"husky": "^8.0.3",
|
||||
"lint-staged": "^15.1.0",
|
||||
"madge": "^6.1.0",
|
||||
"msw": "^2.0.8",
|
||||
"nanoid": "^5.0.3",
|
||||
"nx": "^17.1.3",
|
||||
"nx-cloud": "^16.5.2",
|
||||
"nyc": "^15.1.0",
|
||||
"oxlint": "^0.0.18",
|
||||
"prettier": "^3.1.0",
|
||||
"semver": "^7.5.4",
|
||||
"serve": "^14.2.1",
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { Field, ObjectType, Query } from '@nestjs/graphql';
|
||||
|
||||
import { SERVER_FLAVOR } from '../modules';
|
||||
export const { SERVER_FLAVOR } = process.env;
|
||||
|
||||
@ObjectType()
|
||||
export class ServerConfigType {
|
||||
|
@ -3,7 +3,7 @@ import { EventEmitterModule } from '@nestjs/event-emitter';
|
||||
import { ScheduleModule } from '@nestjs/schedule';
|
||||
|
||||
import { GqlModule } from '../graphql.module';
|
||||
import { ServerConfigModule } from './config';
|
||||
import { SERVER_FLAVOR, ServerConfigModule } from './config';
|
||||
import { DocModule } from './doc';
|
||||
import { PaymentModule } from './payment';
|
||||
import { SelfHostedModule } from './self-hosted';
|
||||
@ -11,8 +11,6 @@ import { SyncModule } from './sync';
|
||||
import { UsersModule } from './users';
|
||||
import { WorkspaceModule } from './workspaces';
|
||||
|
||||
const { SERVER_FLAVOR } = process.env;
|
||||
|
||||
const BusinessModules: (Type | DynamicModule)[] = [
|
||||
EventEmitterModule.forRoot({
|
||||
global: true,
|
||||
|
@ -1,5 +1,4 @@
|
||||
import type { Tag } from '@affine/env/filter';
|
||||
import { Trans } from '@affine/i18n';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { assertExists } from '@blocksuite/global/utils';
|
||||
import { EdgelessIcon, PageIcon, ToggleCollapseIcon } from '@blocksuite/icons';
|
||||
@ -19,93 +18,8 @@ import {
|
||||
useAtom,
|
||||
useAtomValue,
|
||||
} from './scoped-atoms';
|
||||
import type {
|
||||
PageGroupDefinition,
|
||||
PageGroupProps,
|
||||
PageListItemProps,
|
||||
PageListProps,
|
||||
} from './types';
|
||||
import { type DateKey } from './types';
|
||||
import { betweenDaysAgo, shallowEqual, withinDaysAgo } from './utils';
|
||||
|
||||
// todo: optimize date matchers
|
||||
const getDateGroupDefinitions = (key: DateKey): PageGroupDefinition[] => [
|
||||
{
|
||||
id: 'today',
|
||||
label: <Trans i18nKey="com.affine.today" />,
|
||||
match: item => withinDaysAgo(new Date(item[key] ?? item.createDate), 1),
|
||||
},
|
||||
{
|
||||
id: 'yesterday',
|
||||
label: <Trans i18nKey="com.affine.yesterday" />,
|
||||
match: item => betweenDaysAgo(new Date(item[key] ?? item.createDate), 1, 2),
|
||||
},
|
||||
{
|
||||
id: 'last7Days',
|
||||
label: <Trans i18nKey="com.affine.last7Days" />,
|
||||
match: item => betweenDaysAgo(new Date(item[key] ?? item.createDate), 2, 7),
|
||||
},
|
||||
{
|
||||
id: 'last30Days',
|
||||
label: <Trans i18nKey="com.affine.last30Days" />,
|
||||
match: item =>
|
||||
betweenDaysAgo(new Date(item[key] ?? item.createDate), 7, 30),
|
||||
},
|
||||
{
|
||||
id: 'moreThan30Days',
|
||||
label: <Trans i18nKey="com.affine.moreThan30Days" />,
|
||||
match: item => !withinDaysAgo(new Date(item[key] ?? item.createDate), 30),
|
||||
},
|
||||
];
|
||||
|
||||
const pageGroupDefinitions = {
|
||||
createDate: getDateGroupDefinitions('createDate'),
|
||||
updatedDate: getDateGroupDefinitions('updatedDate'),
|
||||
// add more here later
|
||||
// todo: some page group definitions maybe dynamic
|
||||
};
|
||||
|
||||
export function pagesToPageGroups(
|
||||
pages: PageMeta[],
|
||||
key?: DateKey
|
||||
): PageGroupProps[] {
|
||||
if (!key) {
|
||||
return [
|
||||
{
|
||||
id: 'all',
|
||||
items: pages,
|
||||
allItems: pages,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
// assume pages are already sorted, we will use the page order to determine the group order
|
||||
const groupDefs = pageGroupDefinitions[key];
|
||||
const groups: PageGroupProps[] = [];
|
||||
|
||||
for (const page of pages) {
|
||||
// for a single page, there could be multiple groups that it belongs to
|
||||
const matchedGroups = groupDefs.filter(def => def.match(page));
|
||||
for (const groupDef of matchedGroups) {
|
||||
const group = groups.find(g => g.id === groupDef.id);
|
||||
if (group) {
|
||||
group.items.push(page);
|
||||
} else {
|
||||
const label =
|
||||
typeof groupDef.label === 'function'
|
||||
? groupDef.label()
|
||||
: groupDef.label;
|
||||
groups.push({
|
||||
id: groupDef.id,
|
||||
label: label,
|
||||
items: [page],
|
||||
allItems: pages,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return groups;
|
||||
}
|
||||
import type { PageGroupProps, PageListItemProps, PageListProps } from './types';
|
||||
import { shallowEqual } from './utils';
|
||||
|
||||
export const PageGroupHeader = ({ id, items, label }: PageGroupProps) => {
|
||||
const [collapseState, setCollapseState] = useAtom(pageGroupCollapseStateAtom);
|
||||
|
@ -0,0 +1,85 @@
|
||||
import { Trans } from '@affine/i18n';
|
||||
import type { PageMeta } from '@blocksuite/store';
|
||||
|
||||
import type { PageGroupDefinition, PageGroupProps } from './types';
|
||||
import { type DateKey } from './types';
|
||||
import { betweenDaysAgo, withinDaysAgo } from './utils';
|
||||
|
||||
// todo: optimize date matchers
|
||||
const getDateGroupDefinitions = (key: DateKey): PageGroupDefinition[] => [
|
||||
{
|
||||
id: 'today',
|
||||
label: <Trans i18nKey="com.affine.today" />,
|
||||
match: item => withinDaysAgo(new Date(item[key] ?? item.createDate), 1),
|
||||
},
|
||||
{
|
||||
id: 'yesterday',
|
||||
label: <Trans i18nKey="com.affine.yesterday" />,
|
||||
match: item => betweenDaysAgo(new Date(item[key] ?? item.createDate), 1, 2),
|
||||
},
|
||||
{
|
||||
id: 'last7Days',
|
||||
label: <Trans i18nKey="com.affine.last7Days" />,
|
||||
match: item => betweenDaysAgo(new Date(item[key] ?? item.createDate), 2, 7),
|
||||
},
|
||||
{
|
||||
id: 'last30Days',
|
||||
label: <Trans i18nKey="com.affine.last30Days" />,
|
||||
match: item =>
|
||||
betweenDaysAgo(new Date(item[key] ?? item.createDate), 7, 30),
|
||||
},
|
||||
{
|
||||
id: 'moreThan30Days',
|
||||
label: <Trans i18nKey="com.affine.moreThan30Days" />,
|
||||
match: item => !withinDaysAgo(new Date(item[key] ?? item.createDate), 30),
|
||||
},
|
||||
];
|
||||
|
||||
const pageGroupDefinitions = {
|
||||
createDate: getDateGroupDefinitions('createDate'),
|
||||
updatedDate: getDateGroupDefinitions('updatedDate'),
|
||||
// add more here later
|
||||
// todo: some page group definitions maybe dynamic
|
||||
};
|
||||
|
||||
export function pagesToPageGroups(
|
||||
pages: PageMeta[],
|
||||
key?: DateKey
|
||||
): PageGroupProps[] {
|
||||
if (!key) {
|
||||
return [
|
||||
{
|
||||
id: 'all',
|
||||
items: pages,
|
||||
allItems: pages,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
// assume pages are already sorted, we will use the page order to determine the group order
|
||||
const groupDefs = pageGroupDefinitions[key];
|
||||
const groups: PageGroupProps[] = [];
|
||||
|
||||
for (const page of pages) {
|
||||
// for a single page, there could be multiple groups that it belongs to
|
||||
const matchedGroups = groupDefs.filter(def => def.match(page));
|
||||
for (const groupDef of matchedGroups) {
|
||||
const group = groups.find(g => g.id === groupDef.id);
|
||||
if (group) {
|
||||
group.items.push(page);
|
||||
} else {
|
||||
const label =
|
||||
typeof groupDef.label === 'function'
|
||||
? groupDef.label()
|
||||
: groupDef.label;
|
||||
groups.push({
|
||||
id: groupDef.id,
|
||||
label: label,
|
||||
items: [page],
|
||||
allItems: pages,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return groups;
|
||||
}
|
@ -4,7 +4,7 @@ import { atom } from 'jotai';
|
||||
import { selectAtom } from 'jotai/utils';
|
||||
import { createIsolation } from 'jotai-scope';
|
||||
|
||||
import { pagesToPageGroups } from './page-group';
|
||||
import { pagesToPageGroups } from './pages-to-page-group';
|
||||
import type {
|
||||
PageListProps,
|
||||
PageMetaRecord,
|
||||
|
@ -1,13 +1,6 @@
|
||||
import {
|
||||
createEmptyCollection,
|
||||
useEditCollectionName,
|
||||
} from '@affine/component/page-list';
|
||||
import type { Collection } from '@affine/env/filter';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { SaveIcon } from '@blocksuite/icons';
|
||||
import { Button } from '@toeverything/components/button';
|
||||
import { Modal } from '@toeverything/components/modal';
|
||||
import { nanoid } from 'nanoid';
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
|
||||
import Input from '../../../ui/input';
|
||||
@ -127,40 +120,3 @@ export const CreateCollection = ({
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
interface SaveAsCollectionButtonProps {
|
||||
onConfirm: (collection: Collection) => Promise<void>;
|
||||
}
|
||||
|
||||
export const SaveAsCollectionButton = ({
|
||||
onConfirm,
|
||||
}: SaveAsCollectionButtonProps) => {
|
||||
const t = useAFFiNEI18N();
|
||||
const { open, node } = useEditCollectionName({
|
||||
title: t['com.affine.editCollection.saveCollection'](),
|
||||
showTips: true,
|
||||
});
|
||||
const handleClick = useCallback(() => {
|
||||
open('')
|
||||
.then(name => {
|
||||
return onConfirm(createEmptyCollection(nanoid(), { name }));
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
}, [open, onConfirm]);
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
onClick={handleClick}
|
||||
data-testid="save-as-collection"
|
||||
icon={<SaveIcon />}
|
||||
size="large"
|
||||
style={{ padding: '7px 8px' }}
|
||||
>
|
||||
{t['com.affine.editCollection.saveCollection']()}
|
||||
</Button>
|
||||
{node}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -6,7 +6,7 @@ import { Button } from '@toeverything/components/button';
|
||||
import { Modal } from '@toeverything/components/modal';
|
||||
import { type ReactNode, useCallback, useMemo, useState } from 'react';
|
||||
|
||||
import { RadioButton, RadioButtonGroup } from '../../../../index';
|
||||
import { RadioButton, RadioButtonGroup } from '../../../../ui/button';
|
||||
import * as styles from './edit-collection.css';
|
||||
import { PagesMode } from './pages-mode';
|
||||
import { RulesMode } from './rules-mode';
|
||||
|
@ -1,12 +1,7 @@
|
||||
import {
|
||||
type AllPageListConfig,
|
||||
filterPageByRules,
|
||||
} from '@affine/component/page-list';
|
||||
import type { Filter } from '@affine/env/filter';
|
||||
import type { PageMeta } from '@blocksuite/store';
|
||||
import { Modal } from '@toeverything/components/modal';
|
||||
import { type MouseEvent, useCallback, useState } from 'react';
|
||||
import { useCallback, useState } from 'react';
|
||||
|
||||
import type { AllPageListConfig } from './edit-collection';
|
||||
import { SelectPage } from './select-page';
|
||||
export const useSelectPage = ({
|
||||
allPageListConfig,
|
||||
@ -60,47 +55,3 @@ export const useSelectPage = ({
|
||||
}),
|
||||
};
|
||||
};
|
||||
export const useFilter = (list: PageMeta[]) => {
|
||||
const [filters, changeFilters] = useState<Filter[]>([]);
|
||||
const [showFilter, setShowFilter] = useState(false);
|
||||
const clickFilter = useCallback(
|
||||
(e: MouseEvent) => {
|
||||
if (showFilter || filters.length !== 0) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
setShowFilter(!showFilter);
|
||||
}
|
||||
},
|
||||
[filters.length, showFilter]
|
||||
);
|
||||
const onCreateFilter = useCallback(
|
||||
(filter: Filter) => {
|
||||
changeFilters([...filters, filter]);
|
||||
setShowFilter(true);
|
||||
},
|
||||
[filters]
|
||||
);
|
||||
return {
|
||||
showFilter,
|
||||
filters,
|
||||
updateFilters: changeFilters,
|
||||
clickFilter,
|
||||
createFilter: onCreateFilter,
|
||||
filteredList: list.filter(v => {
|
||||
if (v.trash) {
|
||||
return false;
|
||||
}
|
||||
return filterPageByRules(filters, [], v);
|
||||
}),
|
||||
};
|
||||
};
|
||||
export const useSearch = (list: PageMeta[]) => {
|
||||
const [value, onChange] = useState('');
|
||||
return {
|
||||
searchText: value,
|
||||
updateSearchText: onChange,
|
||||
searchedList: value
|
||||
? list.filter(v => v.title.toLowerCase().includes(value.toLowerCase()))
|
||||
: list,
|
||||
};
|
||||
};
|
||||
|
@ -1,8 +1,3 @@
|
||||
import {
|
||||
type AllPageListConfig,
|
||||
FilterList,
|
||||
VirtualizedPageList,
|
||||
} from '@affine/component/page-list';
|
||||
import type { Collection } from '@affine/env/filter';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { FilterIcon } from '@blocksuite/icons';
|
||||
@ -11,10 +6,14 @@ import { Menu } from '@toeverything/components/menu';
|
||||
import clsx from 'clsx';
|
||||
import { type ReactNode, useCallback } from 'react';
|
||||
|
||||
import { FilterList } from '../../filter/filter-list';
|
||||
import { VariableSelect } from '../../filter/vars';
|
||||
import { VirtualizedPageList } from '../../virtualized-page-list';
|
||||
import type { AllPageListConfig } from './edit-collection';
|
||||
import * as styles from './edit-collection.css';
|
||||
import { useFilter, useSearch } from './hooks';
|
||||
import { EmptyList } from './select-page';
|
||||
import { useFilter } from './use-filter';
|
||||
import { useSearch } from './use-search';
|
||||
|
||||
export const PagesMode = ({
|
||||
switchMode,
|
||||
|
@ -6,13 +6,15 @@ import { Menu } from '@toeverything/components/menu';
|
||||
import clsx from 'clsx';
|
||||
import { useCallback, useState } from 'react';
|
||||
|
||||
import { VirtualizedPageList } from '../..';
|
||||
import { FilterList } from '../../filter';
|
||||
import { VariableSelect } from '../../filter/vars';
|
||||
import { VirtualizedPageList } from '../../virtualized-page-list';
|
||||
import { AffineShapeIcon } from '../affine-shape';
|
||||
import type { AllPageListConfig } from './edit-collection';
|
||||
import * as styles from './edit-collection.css';
|
||||
import { useFilter, useSearch } from './hooks';
|
||||
import { useFilter } from './use-filter';
|
||||
import { useSearch } from './use-search';
|
||||
|
||||
export const SelectPage = ({
|
||||
allPageListConfig,
|
||||
init,
|
||||
|
@ -0,0 +1,40 @@
|
||||
import type { Filter } from '@affine/env/filter';
|
||||
import type { PageMeta } from '@blocksuite/store';
|
||||
import { type MouseEvent, useCallback, useState } from 'react';
|
||||
|
||||
import { filterPageByRules } from '../../use-collection-manager';
|
||||
|
||||
export const useFilter = (list: PageMeta[]) => {
|
||||
const [filters, changeFilters] = useState<Filter[]>([]);
|
||||
const [showFilter, setShowFilter] = useState(false);
|
||||
const clickFilter = useCallback(
|
||||
(e: MouseEvent) => {
|
||||
if (showFilter || filters.length !== 0) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
setShowFilter(!showFilter);
|
||||
}
|
||||
},
|
||||
[filters.length, showFilter]
|
||||
);
|
||||
const onCreateFilter = useCallback(
|
||||
(filter: Filter) => {
|
||||
changeFilters([...filters, filter]);
|
||||
setShowFilter(true);
|
||||
},
|
||||
[filters]
|
||||
);
|
||||
return {
|
||||
showFilter,
|
||||
filters,
|
||||
updateFilters: changeFilters,
|
||||
clickFilter,
|
||||
createFilter: onCreateFilter,
|
||||
filteredList: list.filter(v => {
|
||||
if (v.trash) {
|
||||
return false;
|
||||
}
|
||||
return filterPageByRules(filters, [], v);
|
||||
}),
|
||||
};
|
||||
};
|
@ -0,0 +1,13 @@
|
||||
import type { PageMeta } from '@blocksuite/store';
|
||||
import { useState } from 'react';
|
||||
|
||||
export const useSearch = (list: PageMeta[]) => {
|
||||
const [value, onChange] = useState('');
|
||||
return {
|
||||
searchText: value,
|
||||
updateSearchText: onChange,
|
||||
searchedList: value
|
||||
? list.filter(v => v.title.toLowerCase().includes(value.toLowerCase()))
|
||||
: list,
|
||||
};
|
||||
};
|
@ -4,4 +4,5 @@ export * from './collection-list';
|
||||
export * from './collection-operations';
|
||||
export * from './create-collection';
|
||||
export * from './edit-collection/edit-collection';
|
||||
export * from './save-as-collection-button';
|
||||
export * from './use-edit-collection';
|
||||
|
@ -0,0 +1,46 @@
|
||||
import type { Collection } from '@affine/env/filter';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { SaveIcon } from '@blocksuite/icons';
|
||||
import { Button } from '@toeverything/components/button';
|
||||
import { nanoid } from 'nanoid';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { createEmptyCollection } from '../use-collection-manager';
|
||||
import { useEditCollectionName } from './use-edit-collection';
|
||||
|
||||
interface SaveAsCollectionButtonProps {
|
||||
onConfirm: (collection: Collection) => Promise<void>;
|
||||
}
|
||||
|
||||
export const SaveAsCollectionButton = ({
|
||||
onConfirm,
|
||||
}: SaveAsCollectionButtonProps) => {
|
||||
const t = useAFFiNEI18N();
|
||||
const { open, node } = useEditCollectionName({
|
||||
title: t['com.affine.editCollection.saveCollection'](),
|
||||
showTips: true,
|
||||
});
|
||||
const handleClick = useCallback(() => {
|
||||
open('')
|
||||
.then(name => {
|
||||
return onConfirm(createEmptyCollection(nanoid(), { name }));
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
}, [open, onConfirm]);
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
onClick={handleClick}
|
||||
data-testid="save-as-collection"
|
||||
icon={<SaveIcon />}
|
||||
size="large"
|
||||
style={{ padding: '7px 8px' }}
|
||||
>
|
||||
{t['com.affine.editCollection.saveCollection']()}
|
||||
</Button>
|
||||
{node}
|
||||
</>
|
||||
);
|
||||
};
|
@ -1,12 +1,13 @@
|
||||
import {
|
||||
type AllPageListConfig,
|
||||
CreateCollectionModal,
|
||||
EditCollectionModal,
|
||||
type EditCollectionMode,
|
||||
} from '@affine/component/page-list';
|
||||
import type { Collection } from '@affine/env/filter';
|
||||
import { useCallback, useState } from 'react';
|
||||
|
||||
import { CreateCollectionModal } from './create-collection';
|
||||
import {
|
||||
type AllPageListConfig,
|
||||
EditCollectionModal,
|
||||
type EditCollectionMode,
|
||||
} from './edit-collection/edit-collection';
|
||||
|
||||
export const useEditCollection = (config: AllPageListConfig) => {
|
||||
const [data, setData] = useState<{
|
||||
collection: Collection;
|
||||
|
@ -29,7 +29,7 @@ export const Skeleton = ({
|
||||
const style = {
|
||||
width,
|
||||
height,
|
||||
...(_style || {}),
|
||||
..._style,
|
||||
};
|
||||
|
||||
return (
|
||||
|
7
packages/frontend/workspace/src/providers/sync/consts.ts
Normal file
7
packages/frontend/workspace/src/providers/sync/consts.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export const MANUALLY_STOP = 'manually-stop';
|
||||
|
||||
export enum SyncEngineStep {
|
||||
Stopped = 0,
|
||||
Syncing = 1,
|
||||
Synced = 2,
|
||||
}
|
@ -3,16 +3,9 @@ import { Slot } from '@blocksuite/global/utils';
|
||||
import type { Doc } from 'yjs';
|
||||
|
||||
import type { Storage } from '../storage';
|
||||
import { MANUALLY_STOP, SyncEngineStep } from './consts';
|
||||
import { SyncPeer, type SyncPeerStatus, SyncPeerStep } from './peer';
|
||||
|
||||
export const MANUALLY_STOP = 'manually-stop';
|
||||
|
||||
export enum SyncEngineStep {
|
||||
Stopped = 0,
|
||||
Syncing = 1,
|
||||
Synced = 2,
|
||||
}
|
||||
|
||||
export interface SyncEngineStatus {
|
||||
step: SyncEngineStep;
|
||||
local: SyncPeerStatus | null;
|
||||
|
@ -14,5 +14,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
export * from './consts';
|
||||
export * from './engine';
|
||||
export * from './peer';
|
||||
|
@ -7,7 +7,7 @@ import { applyUpdate, encodeStateAsUpdate, encodeStateVector } from 'yjs';
|
||||
import { mergeUpdates, type Storage } from '../storage';
|
||||
import { AsyncQueue } from '../utils/async-queue';
|
||||
import { throwIfAborted } from '../utils/throw-if-aborted';
|
||||
import { MANUALLY_STOP } from './engine';
|
||||
import { MANUALLY_STOP } from './consts';
|
||||
|
||||
export enum SyncPeerStep {
|
||||
Stopped = 0,
|
||||
|
Loading…
Reference in New Issue
Block a user