mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-10 04:30:25 +02:00
remove animations and various smart playlist adjustments
This commit is contained in:
@@ -1,4 +1,3 @@
|
|||||||
import { AnimatePresence, motion } from 'motion/react';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import { QueryBuilderOption } from '/@/renderer/components/query-builder/query-builder-option';
|
import { QueryBuilderOption } from '/@/renderer/components/query-builder/query-builder-option';
|
||||||
@@ -187,41 +186,27 @@ export const QueryBuilder = ({
|
|||||||
</Group>
|
</Group>
|
||||||
{level === 0 && saveActions}
|
{level === 0 && saveActions}
|
||||||
</Group>
|
</Group>
|
||||||
<AnimatePresence initial={false}>
|
{data?.rules?.map((rule: QueryBuilderRule) => (
|
||||||
{data?.rules?.map((rule: QueryBuilderRule) => (
|
<div key={rule.uniqueId}>
|
||||||
<motion.div
|
<QueryBuilderOption
|
||||||
animate={{ opacity: 1, x: 0 }}
|
data={rule}
|
||||||
exit={{ opacity: 0, x: -25 }}
|
filters={filters}
|
||||||
initial={{ opacity: 0, x: -25 }}
|
groupIndex={groupIndex || []}
|
||||||
key={rule.uniqueId}
|
level={level}
|
||||||
transition={{ duration: 0.2, ease: 'easeInOut' }}
|
noRemove={data?.rules?.length === 1}
|
||||||
>
|
onChangeField={onChangeField}
|
||||||
<QueryBuilderOption
|
onChangeOperator={onChangeOperator}
|
||||||
data={rule}
|
onChangeValue={onChangeValue}
|
||||||
filters={filters}
|
onDeleteRule={onDeleteRule}
|
||||||
groupIndex={groupIndex || []}
|
operators={operators}
|
||||||
level={level}
|
selectData={playlists}
|
||||||
noRemove={data?.rules?.length === 1}
|
/>
|
||||||
onChangeField={onChangeField}
|
</div>
|
||||||
onChangeOperator={onChangeOperator}
|
))}
|
||||||
onChangeValue={onChangeValue}
|
|
||||||
onDeleteRule={onDeleteRule}
|
|
||||||
operators={operators}
|
|
||||||
selectData={playlists}
|
|
||||||
/>
|
|
||||||
</motion.div>
|
|
||||||
))}
|
|
||||||
</AnimatePresence>
|
|
||||||
{data?.group && (
|
{data?.group && (
|
||||||
<AnimatePresence initial={false}>
|
<>
|
||||||
{data.group?.map((group: QueryBuilderGroup, index: number) => (
|
{data.group?.map((group: QueryBuilderGroup, index: number) => (
|
||||||
<motion.div
|
<div key={group.uniqueId}>
|
||||||
animate={{ opacity: 1, x: 0 }}
|
|
||||||
exit={{ opacity: 0, x: -25 }}
|
|
||||||
initial={{ opacity: 0, x: -25 }}
|
|
||||||
key={group.uniqueId}
|
|
||||||
transition={{ duration: 0.2, ease: 'easeInOut' }}
|
|
||||||
>
|
|
||||||
<QueryBuilder
|
<QueryBuilder
|
||||||
data={group}
|
data={group}
|
||||||
filters={filters}
|
filters={filters}
|
||||||
@@ -241,9 +226,9 @@ export const QueryBuilder = ({
|
|||||||
playlists={playlists}
|
playlists={playlists}
|
||||||
uniqueId={group.uniqueId}
|
uniqueId={group.uniqueId}
|
||||||
/>
|
/>
|
||||||
</motion.div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</AnimatePresence>
|
</>
|
||||||
)}
|
)}
|
||||||
</Stack>
|
</Stack>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -34,7 +34,15 @@ interface QueryOptionProps {
|
|||||||
selectData?: { label: string; value: string }[];
|
selectData?: { label: string; value: string }[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const QueryValueInput = ({ data, defaultValue, onChange, operator, type, ...props }: any) => {
|
const QueryValueInput = ({
|
||||||
|
data,
|
||||||
|
defaultValue,
|
||||||
|
onChange,
|
||||||
|
operator,
|
||||||
|
type,
|
||||||
|
value: valueProp,
|
||||||
|
...props
|
||||||
|
}: any) => {
|
||||||
const [numberRange, setNumberRange] = useState<number[]>([0, 0]);
|
const [numberRange, setNumberRange] = useState<number[]>([0, 0]);
|
||||||
|
|
||||||
// Parse date value helper - converts date string (YYYY-MM-DD) to Date for display
|
// Parse date value helper - converts date string (YYYY-MM-DD) to Date for display
|
||||||
@@ -50,26 +58,45 @@ const QueryValueInput = ({ data, defaultValue, onChange, operator, type, ...prop
|
|||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const value = valueProp !== undefined ? valueProp : defaultValue;
|
||||||
|
|
||||||
// Store date range as strings for state management
|
// Store date range as strings for state management
|
||||||
const [dateRange, setDateRange] = useState<[null | string, null | string]>(() => {
|
const [dateRange, setDateRange] = useState<[null | string, null | string]>(() => {
|
||||||
if (defaultValue && Array.isArray(defaultValue)) {
|
const currentValue = value !== undefined ? value : defaultValue;
|
||||||
|
if (currentValue && Array.isArray(currentValue)) {
|
||||||
return [
|
return [
|
||||||
typeof defaultValue[0] === 'string' ? defaultValue[0] : null,
|
typeof currentValue[0] === 'string' ? currentValue[0] : null,
|
||||||
typeof defaultValue[1] === 'string' ? defaultValue[1] : null,
|
typeof currentValue[1] === 'string' ? currentValue[1] : null,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
return [null, null];
|
return [null, null];
|
||||||
});
|
});
|
||||||
|
|
||||||
// Sync dateRange state when defaultValue changes
|
// Sync dateRange state when value changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (operator === 'inTheRangeDate' && defaultValue && Array.isArray(defaultValue)) {
|
const currentValue = value !== undefined ? value : defaultValue;
|
||||||
|
if (operator === 'inTheRangeDate' && currentValue && Array.isArray(currentValue)) {
|
||||||
setDateRange([
|
setDateRange([
|
||||||
typeof defaultValue[0] === 'string' ? defaultValue[0] : null,
|
typeof currentValue[0] === 'string' ? currentValue[0] : null,
|
||||||
typeof defaultValue[1] === 'string' ? defaultValue[1] : null,
|
typeof currentValue[1] === 'string' ? currentValue[1] : null,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}, [defaultValue, operator]);
|
}, [value, defaultValue, operator]);
|
||||||
|
|
||||||
|
// Sync numberRange state when value changes
|
||||||
|
useEffect(() => {
|
||||||
|
const currentValue = value !== undefined ? value : defaultValue;
|
||||||
|
if (operator === 'inTheRange' && currentValue && Array.isArray(currentValue)) {
|
||||||
|
setNumberRange([
|
||||||
|
typeof currentValue[0] === 'number'
|
||||||
|
? currentValue[0]
|
||||||
|
: Number(currentValue[0]) || 0,
|
||||||
|
typeof currentValue[1] === 'number'
|
||||||
|
? currentValue[1]
|
||||||
|
: Number(currentValue[1]) || 0,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}, [value, defaultValue, operator]);
|
||||||
|
|
||||||
// Check if operator requires DatePicker
|
// Check if operator requires DatePicker
|
||||||
const isDatePickerOperator =
|
const isDatePickerOperator =
|
||||||
@@ -84,12 +111,13 @@ const QueryValueInput = ({ data, defaultValue, onChange, operator, type, ...prop
|
|||||||
{ label: 'false', value: 'false' },
|
{ label: 'false', value: 'false' },
|
||||||
]}
|
]}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
|
value={value}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
case 'date':
|
case 'date':
|
||||||
if (isDatePickerOperator && operator !== 'inTheRangeDate') {
|
if (isDatePickerOperator && operator !== 'inTheRangeDate') {
|
||||||
const dateValue = defaultValue ? parseDateValue(defaultValue) : null;
|
const dateValue = value ? parseDateValue(value) : null;
|
||||||
return (
|
return (
|
||||||
<DateInput
|
<DateInput
|
||||||
clearable
|
clearable
|
||||||
@@ -107,7 +135,7 @@ const QueryValueInput = ({ data, defaultValue, onChange, operator, type, ...prop
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return <TextInput onChange={onChange} size="sm" {...props} />;
|
return <TextInput onChange={onChange} size="sm" value={value} {...props} />;
|
||||||
case 'dateRange':
|
case 'dateRange':
|
||||||
if (operator === 'inTheRangeDate') {
|
if (operator === 'inTheRangeDate') {
|
||||||
return (
|
return (
|
||||||
@@ -158,24 +186,24 @@ const QueryValueInput = ({ data, defaultValue, onChange, operator, type, ...prop
|
|||||||
<>
|
<>
|
||||||
<NumberInput
|
<NumberInput
|
||||||
{...props}
|
{...props}
|
||||||
defaultValue={props.defaultValue && Number(props.defaultValue?.[0])}
|
|
||||||
maxWidth={81}
|
maxWidth={81}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
const newRange = [Number(e) || 0, numberRange[1]];
|
const newRange = [Number(e) || 0, numberRange[1]];
|
||||||
setNumberRange(newRange);
|
setNumberRange(newRange);
|
||||||
onChange(newRange);
|
onChange(newRange);
|
||||||
}}
|
}}
|
||||||
|
value={numberRange[0] || undefined}
|
||||||
width="10%"
|
width="10%"
|
||||||
/>
|
/>
|
||||||
<NumberInput
|
<NumberInput
|
||||||
{...props}
|
{...props}
|
||||||
defaultValue={props.defaultValue && Number(props.defaultValue?.[1])}
|
|
||||||
maxWidth={81}
|
maxWidth={81}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
const newRange = [numberRange[0], Number(e) || 0];
|
const newRange = [numberRange[0], Number(e) || 0];
|
||||||
setNumberRange(newRange);
|
setNumberRange(newRange);
|
||||||
onChange(newRange);
|
onChange(newRange);
|
||||||
}}
|
}}
|
||||||
|
value={numberRange[1] || undefined}
|
||||||
width="10%"
|
width="10%"
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
@@ -185,14 +213,14 @@ const QueryValueInput = ({ data, defaultValue, onChange, operator, type, ...prop
|
|||||||
<NumberInput
|
<NumberInput
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
size="sm"
|
size="sm"
|
||||||
|
value={value !== undefined && value !== null ? Number(value) : undefined}
|
||||||
{...props}
|
{...props}
|
||||||
defaultValue={props.defaultValue && Number(props.defaultValue)}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
case 'playlist':
|
case 'playlist':
|
||||||
return <Select data={data} onChange={onChange} {...props} />;
|
return <Select data={data} onChange={onChange} value={value} {...props} />;
|
||||||
case 'string':
|
case 'string':
|
||||||
return <TextInput onChange={onChange} size="sm" {...props} />;
|
return <TextInput onChange={onChange} size="sm" value={value || ''} {...props} />;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return <></>;
|
return <></>;
|
||||||
@@ -301,7 +329,6 @@ export const QueryBuilderOption = ({
|
|||||||
{field ? (
|
{field ? (
|
||||||
<QueryValueInput
|
<QueryValueInput
|
||||||
data={selectData || []}
|
data={selectData || []}
|
||||||
defaultValue={value}
|
|
||||||
maxWidth={170}
|
maxWidth={170}
|
||||||
onChange={handleChangeValue}
|
onChange={handleChangeValue}
|
||||||
operator={operator}
|
operator={operator}
|
||||||
@@ -311,15 +338,16 @@ export const QueryBuilderOption = ({
|
|||||||
? 'dateRange'
|
? 'dateRange'
|
||||||
: fieldType
|
: fieldType
|
||||||
}
|
}
|
||||||
|
value={value}
|
||||||
width="25%"
|
width="25%"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<TextInput
|
<TextInput
|
||||||
defaultValue={value}
|
|
||||||
disabled
|
disabled
|
||||||
maxWidth={170}
|
maxWidth={170}
|
||||||
onChange={handleChangeValue}
|
onChange={handleChangeValue}
|
||||||
size="sm"
|
size="sm"
|
||||||
|
value={value || ''}
|
||||||
width="25%"
|
width="25%"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -276,10 +276,13 @@ export const PlaylistQueryBuilder = forwardRef(
|
|||||||
|
|
||||||
const handleDeleteRuleGroup = useCallback((args: DeleteArgs) => {
|
const handleDeleteRuleGroup = useCallback((args: DeleteArgs) => {
|
||||||
const { groupIndex, level, uniqueId } = args;
|
const { groupIndex, level, uniqueId } = args;
|
||||||
const path = level === 0 ? 'group' : getTypePath(groupIndex);
|
const path = level === 0 ? 'group' : getGroupPath(level - 1, groupIndex.slice(0, -1));
|
||||||
|
|
||||||
setFilters((prev) => {
|
setFilters((prev) => {
|
||||||
const currentGroups = get(prev, path) || [];
|
const currentGroups = get(prev, path);
|
||||||
|
if (!Array.isArray(currentGroups)) {
|
||||||
|
return prev;
|
||||||
|
}
|
||||||
return setWith(
|
return setWith(
|
||||||
clone(prev),
|
clone(prev),
|
||||||
path,
|
path,
|
||||||
|
|||||||
Reference in New Issue
Block a user