pl-fe: Allow reordering profile fields

Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
marcin mikołajczak 2024-09-27 22:21:21 +02:00
parent 9227eef670
commit b016dbec2b
4 changed files with 40 additions and 3 deletions

View file

@ -31,7 +31,10 @@ const spaces = {
8: 'gap-8',
};
interface IHStack extends Pick<React.HTMLAttributes<HTMLDivElement>, 'children' | 'className' | 'onClick' | 'style' | 'title'> {
interface IHStack extends Pick<
React.HTMLAttributes<HTMLDivElement>,
'children' | 'className' | 'draggable' | 'onClick' | 'onDragEnd' | 'onDragEnter' | 'onDragStart' | 'style' | 'title'
> {
/** Vertical alignment of children. */
alignItems?: keyof typeof alignItemsOptions;
/** Horizontal alignment of children. */

View file

@ -1,4 +1,4 @@
import React from 'react';
import React, { useRef } from 'react';
import { useIntl, defineMessages } from 'react-intl';
import Button from '../button/button';
@ -39,6 +39,8 @@ interface IStreamfield {
minItems?: number;
/** Maximum number of allowed inputs. */
maxItems?: number;
/** Allow changing order of the items. */
draggable?: boolean;
}
/** List of inputs that can be added or removed. */
@ -52,9 +54,29 @@ const Streamfield: React.FC<IStreamfield> = ({
component: Component,
maxItems = Infinity,
minItems = 0,
draggable,
}) => {
const intl = useIntl();
const dragItem = useRef<number | null>();
const dragOverItem = useRef<number | null>();
const handleDragStart = (i: number) => () => {
dragItem.current = i;
};
const handleDragEnter = (i: number) => () => {
dragOverItem.current = i;
};
const handleDragEnd = () => {
const newData = [...values];
const item = newData.splice(dragItem.current!, 1)[0];
newData.splice(dragOverItem.current!, 0, item);
onChange(newData);
};
const handleChange = (i: number) => (value: any) => {
const newData = [...values];
newData[i] = value;
@ -71,7 +93,15 @@ const Streamfield: React.FC<IStreamfield> = ({
{(values.length > 0) && (
<Stack space={1}>
{values.map((value, i) => value?._destroy ? null : (
<HStack key={i} space={2} alignItems='center'>
<HStack
key={i}
space={2}
alignItems='center'
draggable={draggable}
onDragStart={handleDragStart(i)}
onDragEnter={handleDragEnter(i)}
onDragEnd={handleDragEnd}
>
<Component
key={i}
index={i}

View file

@ -452,6 +452,7 @@ const EditProfile: React.FC = () => {
onRemoveItem={handleRemoveField}
component={ProfileField}
maxItems={maxFields}
draggable
/>
)}

View file

@ -288,6 +288,7 @@ const PlFeConfig: React.FC = () => {
onChange={handleStreamItemChange(['promoPanel', 'items'])}
onAddItem={addStreamItem(['promoPanel', 'items'], templates.promoPanel)}
onRemoveItem={deleteStreamItem(['promoPanel', 'items'])}
draggable
/>
<Streamfield
@ -298,6 +299,7 @@ const PlFeConfig: React.FC = () => {
onChange={handleStreamItemChange(['navlinks', 'homeFooter'])}
onAddItem={addStreamItem(['navlinks', 'homeFooter'], templates.footerItem)}
onRemoveItem={deleteStreamItem(['navlinks', 'homeFooter'])}
draggable
/>
<FormGroup labelText={intl.formatMessage(messages.copyrightFooterLabel)}>
@ -347,6 +349,7 @@ const PlFeConfig: React.FC = () => {
onChange={handleStreamItemChange(['cryptoAddresses'])}
onAddItem={addStreamItem(['cryptoAddresses'], templates.cryptoAddress)}
onRemoveItem={deleteStreamItem(['cryptoAddresses'])}
draggable
/>
<FormGroup labelText={intl.formatMessage(messages.cryptoDonatePanelLimitLabel)}>