Merge pull request #194 from toeverything/fix/experience

Fix/experience
This commit is contained in:
DarkSky
2022-08-11 19:37:31 +08:00
committed by GitHub
11 changed files with 125 additions and 77 deletions
+1 -1
View File
@@ -2,7 +2,7 @@ FROM node:16-alpine as builder
WORKDIR /app WORKDIR /app
COPY . . COPY . .
RUN apk add g++ make python3 git libpng-dev RUN apk add g++ make python3 git libpng-dev
RUN npm i -g pnpm@7 && pnpm i --frozen-lockfile --store=node_modules/.pnpm-store && pnpm run build:local RUN npm i -g pnpm@7 && pnpm i --frozen-lockfile --store=node_modules/.pnpm-store && pnpm run build:local --skip-nx-cache
FROM node:16-alpine as relocate FROM node:16-alpine as relocate
WORKDIR /app WORKDIR /app
@@ -60,6 +60,9 @@ export const CardContext = (props: Props) => {
const StyledCardContainer = styled('div')` const StyledCardContainer = styled('div')`
cursor: pointer; cursor: pointer;
&:hover {
z-index: 1;
}
&:focus-within { &:focus-within {
z-index: 1; z-index: 1;
} }
@@ -3,6 +3,8 @@ import { styled } from '@toeverything/components/ui';
import type { AsyncBlock } from '../editor'; import type { AsyncBlock } from '../editor';
import { PendantPopover } from './pendant-popover'; import { PendantPopover } from './pendant-popover';
import { PendantRender } from './pendant-render'; import { PendantRender } from './pendant-render';
import { useRef } from 'react';
import { getRecastItemValue, useRecastBlockMeta } from '../recast-block';
/** /**
* @deprecated * @deprecated
*/ */
@@ -14,13 +16,27 @@ export const BlockPendantProvider: FC<PropsWithChildren<BlockTagProps>> = ({
block, block,
children, children,
}) => { }) => {
const triggerRef = useRef<HTMLDivElement>();
const { getProperties } = useRecastBlockMeta();
const properties = getProperties();
const { getValue } = getRecastItemValue(block);
const showTriggerLine =
properties.filter(property => getValue(property.id)).length === 0;
return ( return (
<Container> <Container>
{children} {children}
<PendantPopover block={block}> {showTriggerLine ? (
<StyledTriggerLine /> <StyledPendantContainer ref={triggerRef}>
</PendantPopover> <PendantPopover
block={block}
container={triggerRef.current}
>
<StyledTriggerLine />
</PendantPopover>
</StyledPendantContainer>
) : null}
<PendantRender block={block} /> <PendantRender block={block} />
</Container> </Container>
@@ -43,10 +59,12 @@ const StyledTriggerLine = styled('div')({
width: '100%', width: '100%',
height: '2px', height: '2px',
background: '#dadada', background: '#dadada',
display: 'none', display: 'flex',
position: 'absolute', position: 'absolute',
left: '0', left: '0',
top: '4px', top: '4px',
transition: 'opacity .2s',
opacity: '0',
}, },
'::after': { '::after': {
content: "''", content: "''",
@@ -60,18 +78,24 @@ const StyledTriggerLine = styled('div')({
transition: 'width .3s', transition: 'width .3s',
}, },
}); });
const StyledPendantContainer = styled('div')({
const Container = styled('div')({ width: '100px',
position: 'relative',
paddingBottom: `${LINE_GAP - TAG_GAP * 2}px`,
'&:hover': { '&:hover': {
[StyledTriggerLine.toString()]: { [`${StyledTriggerLine}`]: {
'&::before': {
display: 'flex',
},
'&::after': { '&::after': {
width: '100%', width: '100%',
}, },
}, },
}, },
}); });
const Container = styled('div')({
position: 'relative',
paddingBottom: `${LINE_GAP - TAG_GAP * 2}px`,
'&:hover': {
[`${StyledTriggerLine}`]: {
'&::before': {
opacity: '1',
},
},
},
});
@@ -29,6 +29,7 @@ export const PendantHistoryPanel = ({
const [history, setHistory] = useState<RecastBlockValue[]>([]); const [history, setHistory] = useState<RecastBlockValue[]>([]);
const popoverHandlerRef = useRef<{ [key: string]: PopperHandler }>({}); const popoverHandlerRef = useRef<{ [key: string]: PopperHandler }>({});
const historyPanelRef = useRef<HTMLDivElement>();
const { getValueHistory } = getRecastItemValue(block); const { getValueHistory } = getRecastItemValue(block);
useEffect(() => { useEffect(() => {
@@ -84,7 +85,7 @@ export const PendantHistoryPanel = ({
}, [block, getProperties, groupBlock, recastBlock]); }, [block, getProperties, groupBlock, recastBlock]);
return ( return (
<StyledPendantHistoryPanel> <StyledPendantHistoryPanel ref={historyPanelRef}>
{history.map(item => { {history.map(item => {
const property = getProperty(item.id); const property = getProperty(item.id);
return ( return (
@@ -116,6 +117,7 @@ export const PendantHistoryPanel = ({
/> />
} }
trigger="click" trigger="click"
container={historyPanelRef.current}
> >
<PendantTag <PendantTag
style={{ style={{
@@ -1,5 +1,11 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { Input, Option, Select, Tooltip } from '@toeverything/components/ui'; import {
Input,
message,
Option,
Select,
Tooltip,
} from '@toeverything/components/ui';
import { HelpCenterIcon } from '@toeverything/components/icons'; import { HelpCenterIcon } from '@toeverything/components/icons';
import { AsyncBlock } from '../../editor'; import { AsyncBlock } from '../../editor';
@@ -18,6 +24,7 @@ import {
generateRandomFieldName, generateRandomFieldName,
generateInitialOptions, generateInitialOptions,
getPendantConfigByType, getPendantConfigByType,
checkPendantForm,
} from '../utils'; } from '../utils';
import { useOnCreateSure } from './hooks'; import { useOnCreateSure } from './hooks';
@@ -74,7 +81,7 @@ export const CreatePendantPanel = ({
setFieldName(e.target.value); setFieldName(e.target.value);
}} }}
endAdornment={ endAdornment={
<Tooltip content="Help info here"> <Tooltip content="Help info here" placement="top">
<StyledInputEndAdornment> <StyledInputEndAdornment>
<HelpCenterIcon /> <HelpCenterIcon />
</StyledInputEndAdornment> </StyledInputEndAdornment>
@@ -98,6 +105,17 @@ export const CreatePendantPanel = ({
)} )}
iconConfig={getPendantConfigByType(selectedOption.type)} iconConfig={getPendantConfigByType(selectedOption.type)}
onSure={async (type, newPropertyItem, newValue) => { onSure={async (type, newPropertyItem, newValue) => {
const checkResult = checkPendantForm(
type,
fieldName,
newPropertyItem,
newValue
);
if (!checkResult.passed) {
await message.error(checkResult.message);
return;
}
await onCreateSure({ await onCreateSure({
type, type,
newPropertyItem, newPropertyItem,
@@ -1,5 +1,5 @@
import { useState } from 'react'; import { useState } from 'react';
import { Input, Tooltip } from '@toeverything/components/ui'; import { Input, message, Tooltip } from '@toeverything/components/ui';
import { HelpCenterIcon } from '@toeverything/components/icons'; import { HelpCenterIcon } from '@toeverything/components/icons';
import { PendantModifyPanel } from '../pendant-modify-panel'; import { PendantModifyPanel } from '../pendant-modify-panel';
import type { AsyncBlock } from '../../editor'; import type { AsyncBlock } from '../../editor';
@@ -8,7 +8,7 @@ import {
type RecastBlockValue, type RecastBlockValue,
type RecastMetaProperty, type RecastMetaProperty,
} from '../../recast-block'; } from '../../recast-block';
import { getPendantConfigByType } from '../utils'; import { checkPendantForm, getPendantConfigByType } from '../utils';
import { import {
StyledPopoverWrapper, StyledPopoverWrapper,
StyledOperationLabel, StyledOperationLabel,
@@ -70,7 +70,7 @@ export const UpdatePendantPanel = ({
setFieldName(e.target.value); setFieldName(e.target.value);
}} }}
endAdornment={ endAdornment={
<Tooltip content="Help info here"> <Tooltip content="Help info here" placement="top">
<StyledInputEndAdornment> <StyledInputEndAdornment>
<HelpCenterIcon /> <HelpCenterIcon />
</StyledInputEndAdornment> </StyledInputEndAdornment>
@@ -98,6 +98,17 @@ export const UpdatePendantPanel = ({
property={property} property={property}
type={property.type} type={property.type}
onSure={async (type, newPropertyItem, newValue) => { onSure={async (type, newPropertyItem, newValue) => {
const checkResult = checkPendantForm(
type,
fieldName,
newPropertyItem,
newValue
);
if (!checkResult.passed) {
await message.error(checkResult.message);
return;
}
await onUpdateSure({ await onUpdateSure({
type, type,
newPropertyItem, newPropertyItem,
@@ -23,12 +23,7 @@ import {
PendantTypes, PendantTypes,
type TempInformationType, type TempInformationType,
} from '../types'; } from '../types';
import { import { getOfficialSelected, getPendantConfigByType } from '../utils';
checkPendantForm,
getOfficialSelected,
getPendantConfigByType,
} from '../utils';
import { message } from '@toeverything/components/ui';
type SelectPropertyType = MultiSelectProperty | SelectProperty; type SelectPropertyType = MultiSelectProperty | SelectProperty;
type SureParams = { type SureParams = {
@@ -56,18 +51,6 @@ export const useOnCreateSure = ({ block }: { block: AsyncBlock }) => {
newPropertyItem, newPropertyItem,
newValue, newValue,
}: SureParams) => { }: SureParams) => {
const checkResult = checkPendantForm(
type,
fieldName,
newPropertyItem,
newValue
);
if (!checkResult.passed) {
await message.error(checkResult.message);
return;
}
if ( if (
type === PendantTypes.MultiSelect || type === PendantTypes.MultiSelect ||
type === PendantTypes.Select || type === PendantTypes.Select ||
@@ -181,18 +164,6 @@ export const useOnUpdateSure = ({
newPropertyItem, newPropertyItem,
newValue, newValue,
}: SureParams) => { }: SureParams) => {
const checkResult = checkPendantForm(
type,
fieldName,
newPropertyItem,
newValue
);
if (!checkResult.passed) {
await message.error(checkResult.message);
return;
}
if ( if (
type === PendantTypes.MultiSelect || type === PendantTypes.MultiSelect ||
type === PendantTypes.Select || type === PendantTypes.Select ||
@@ -26,6 +26,7 @@ export const PendantPopover: FC<
block={block} block={block}
endElement={ endElement={
<AddPendantPopover <AddPendantPopover
container={popoverProps.container}
block={block} block={block}
onSure={() => { onSure={() => {
popoverHandlerRef.current?.setVisible(false); popoverHandlerRef.current?.setVisible(false);
@@ -105,6 +105,8 @@ export const PendantRender = ({ block }: { block: AsyncBlock }) => {
<AddPendantPopover <AddPendantPopover
block={block} block={block}
iconStyle={{ marginTop: 4 }} iconStyle={{ marginTop: 4 }}
trigger="click"
// trigger={isKanbanView ? 'hover' : 'click'}
container={blockRenderContainerRef.current} container={blockRenderContainerRef.current}
/> />
</div> </div>
@@ -1,4 +1,5 @@
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { message } from '@toeverything/components/ui';
import { useSettingFlags, type SettingFlags } from './use-setting-flags'; import { useSettingFlags, type SettingFlags } from './use-setting-flags';
import { copyToClipboard } from '@toeverything/utils'; import { copyToClipboard } from '@toeverything/utils';
import { import {
@@ -91,7 +92,10 @@ export const useSettings = (): SettingItem[] => {
{ {
type: 'button', type: 'button',
name: 'Copy Page Link', name: 'Copy Page Link',
onClick: () => copyToClipboard(window.location.href), onClick: () => {
copyToClipboard(window.location.href);
message.success('Page link copied successfully');
},
}, },
{ {
type: 'separator', type: 'separator',
+38 -26
View File
@@ -12,6 +12,7 @@ import SelectUnstyled, {
} from '@mui/base/SelectUnstyled'; } from '@mui/base/SelectUnstyled';
/* eslint-disable no-restricted-imports */ /* eslint-disable no-restricted-imports */
import PopperUnstyled from '@mui/base/PopperUnstyled'; import PopperUnstyled from '@mui/base/PopperUnstyled';
import { ArrowDropDownIcon } from '@toeverything/components/icons';
import { styled } from '../styled'; import { styled } from '../styled';
type ExtendSelectProps = { type ExtendSelectProps = {
@@ -41,20 +42,29 @@ export const Select = forwardRef(function CustomSelect<TValue>(
const { width = '100%', style, listboxStyle, placeholder } = props; const { width = '100%', style, listboxStyle, placeholder } = props;
const components: SelectUnstyledProps<TValue>['components'] = { const components: SelectUnstyledProps<TValue>['components'] = {
// Root: generateStyledRoot({ width, ...style }), // Root: generateStyledRoot({ width, ...style }),
Root: forwardRef((rootProps, rootRef) => ( Root: forwardRef((rootProps, rootRef) => {
<StyledRoot const {
ref={rootRef} ownerState: { open },
{...rootProps} } = rootProps;
style={{
width, return (
...style, <StyledRoot
}} ref={rootRef}
> {...rootProps}
{rootProps.children || ( style={{
<StyledPlaceholder>{placeholder}</StyledPlaceholder> width,
)} ...style,
</StyledRoot> }}
)), >
{rootProps.children || (
<StyledPlaceholder>{placeholder}</StyledPlaceholder>
)}
<StyledSelectedArrowWrapper open={open}>
<ArrowDropDownIcon />
</StyledSelectedArrowWrapper>
</StyledRoot>
);
}),
Listbox: forwardRef((listboxProps, listboxRef) => ( Listbox: forwardRef((listboxProps, listboxRef) => (
<StyledListbox <StyledListbox
ref={listboxRef} ref={listboxRef}
@@ -73,6 +83,20 @@ export const Select = forwardRef(function CustomSelect<TValue>(
RefAttributes<HTMLUListElement> RefAttributes<HTMLUListElement>
) => JSX.Element; ) => JSX.Element;
const StyledSelectedArrowWrapper = styled('div')<{ open: boolean }>(
({ open }) => ({
position: 'absolute',
top: '0',
bottom: '0',
right: '12px',
margin: 'auto',
lineHeight: '32px',
display: 'flex',
alignItems: 'center',
transform: `rotate(${open ? '180deg' : '0'})`,
})
);
const StyledRoot = styled('div')(({ theme }) => ({ const StyledRoot = styled('div')(({ theme }) => ({
height: '32px', height: '32px',
border: `1px solid ${theme.affine.palette.borderColor}`, border: `1px solid ${theme.affine.palette.borderColor}`,
@@ -95,18 +119,6 @@ const StyledRoot = styled('div')(({ theme }) => ({
[`&.${selectUnstyledClasses.expanded}`]: { [`&.${selectUnstyledClasses.expanded}`]: {
borderColor: `${theme.affine.palette.primary}`, borderColor: `${theme.affine.palette.primary}`,
'&::after': {
content: '"▴"',
},
},
'&::after': {
content: '"▾"',
position: ' absolute',
top: '0',
bottom: '0',
right: '12px',
margin: 'auto',
lineHeight: '32px',
}, },
})); }));