mirror of
https://github.com/balzack/databag.git
synced 2025-04-24 02:25:26 +00:00
modal for new topic in webapp
This commit is contained in:
parent
fef6c7b1dd
commit
aa49b1ef19
@ -26,11 +26,12 @@ export function Content({select}: {select: (focus: Focus) => void}) {
|
||||
action: () => setAlert(false),
|
||||
},
|
||||
});
|
||||
const cards = (state.sealSet && sealed) ? state.sealable : state.connected;
|
||||
|
||||
const addTopic = async () => {
|
||||
setAdding(true);
|
||||
try {
|
||||
await actions.addTopic(sealed, subject, members);
|
||||
await actions.addTopic(sealed, subject, members.filter(id => Boolean(cards.find(card => card.cardId === id))));
|
||||
setAdd(false);
|
||||
setSubject('');
|
||||
setMembers([]);
|
||||
@ -43,8 +44,6 @@ export function Content({select}: {select: (focus: Focus) => void}) {
|
||||
setAdding(false);
|
||||
};
|
||||
|
||||
const cards = sealed ? state.sealable : state.connected;
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<SafeAreaView style={styles.header}>
|
||||
|
@ -25,12 +25,12 @@ export function useContent() {
|
||||
layout: null,
|
||||
guid: '',
|
||||
connected: [] as Card[],
|
||||
connectedAndSealable: [] as Cards[],
|
||||
sealable: [] as Cards[],
|
||||
sorted: [] as Channel[],
|
||||
filtered: [] as ChannelParams[],
|
||||
filter: '',
|
||||
topic: '',
|
||||
sealable: false,
|
||||
sealSet: false,
|
||||
});
|
||||
|
||||
const compare = (a: Card, b: Card) => {
|
||||
|
@ -82,9 +82,52 @@
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
|
||||
.members {
|
||||
padding-left: 4px;
|
||||
font-size: 12px;
|
||||
color: var(--mantine-color-text-6);
|
||||
}
|
||||
|
||||
.addMembers {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
min-height: 128px;
|
||||
max-height: 256px;
|
||||
background: var(--mantine-color-surface-0);
|
||||
overflow: scroll;
|
||||
border: 1px solid var(--mantine-color-text-8);
|
||||
border-radius: 2px;
|
||||
|
||||
.noContacts {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 128px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.noContactsLabel {
|
||||
color: var(--mantine-color-text-6);
|
||||
}
|
||||
}
|
||||
|
||||
.card {
|
||||
width: 100%;
|
||||
height: 48px;
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8px;
|
||||
padding-right: 16px;
|
||||
padding-left: 16px;
|
||||
border-bottom: 1px solid var(--mantine-color-text-8);
|
||||
}
|
||||
}
|
||||
|
||||
.addControls {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
|
||||
.addSealed {
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,65 @@
|
||||
import React, {useState} from 'react';
|
||||
import { useContent } from './useContent.hook'
|
||||
import { Modal, TextInput, Button } from '@mantine/core'
|
||||
import { Modal, Text, Switch, TextInput, Button } from '@mantine/core'
|
||||
import { IconSearch, IconMessagePlus, IconLabel } from '@tabler/icons-react'
|
||||
import classes from './Content.module.css'
|
||||
import { Channel } from '../channel/Channel'
|
||||
import { Focus } from 'databag-client-sdk'
|
||||
import { Card } from '../card/Card';
|
||||
import { modals } from '@mantine/modals'
|
||||
|
||||
export function Content({ select }: { select: (focus: Focus) => void }) {
|
||||
const { state, actions } = useContent()
|
||||
const [add, setAdd] = useState(false);
|
||||
const [adding, setAdding] = useState(false);
|
||||
const [sealed, setSealed] = useState(false);
|
||||
const [subject, setSubject] = useState('');
|
||||
const [added, setAdded] = useState([]);
|
||||
const cards = (state.sealSet && sealed) ? state.sealable : state.connected;
|
||||
|
||||
const addTopic = async () => {
|
||||
setAdding(true);
|
||||
try {
|
||||
await actions.addTopic(sealed, subject, added.filter(id => Boolean(cards.find(card => card.cardId === id))))
|
||||
setAdd(false);
|
||||
setSealed(false);
|
||||
setAdded([]);
|
||||
setSubject('');
|
||||
}
|
||||
catch (err) {
|
||||
console.log(err);
|
||||
showError();
|
||||
}
|
||||
setAdding(false);
|
||||
}
|
||||
|
||||
const showError = () => {
|
||||
modals.openConfirmModal({
|
||||
title: state.strings.operationFailed,
|
||||
withCloseButton: true,
|
||||
overlayProps: {
|
||||
backgroundOpacity: 0.55,
|
||||
blur: 3,
|
||||
},
|
||||
children: <Text>{state.strings.tryAgain}</Text>,
|
||||
cancelProps: { display: 'none' },
|
||||
confirmProps: { display: 'none' },
|
||||
})
|
||||
}
|
||||
|
||||
const contacts = cards.map((card, idx) => {
|
||||
const enable = (<Switch key="add" className={classes.addMember} size="sm" checked={Boolean(added.find(id => id === card.cardId))} onChange={(ev) => {
|
||||
if (ev.currentTarget.checked) {
|
||||
setAdded([ ...added, card.cardId ]);
|
||||
} else {
|
||||
setAdded(added.filter(id => id !== card.cardId))
|
||||
}
|
||||
}} />)
|
||||
return (
|
||||
<Card key={idx} className={classes.card} imageUrl={card.imageUrl} name={card.name} handle={card.handle} node={card.node} placeholder={state.strings.name} actions={[enable]} />
|
||||
)
|
||||
});
|
||||
|
||||
const channels = state.filtered.map((channel, idx) => {
|
||||
return (
|
||||
<Channel
|
||||
@ -59,7 +106,7 @@ export function Content({ select }: { select: (focus: Focus) => void }) {
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
<Modal title={state.strings.newTopic} opened={add} onClose={() => setAdd(false)} overlayProps={{ backgroundOpacity: 0.55, blur: 3 }} centered>
|
||||
<Modal title={state.strings.newTopic} opened={add} onClose={() => setAdd(false)} overlayProps={{ backgroundOpacity: 0.65, blur: 3 }} centered>
|
||||
<div className={classes.addContainer}>
|
||||
<TextInput
|
||||
className={classes.input}
|
||||
@ -67,11 +114,32 @@ export function Content({ select }: { select: (focus: Focus) => void }) {
|
||||
leftSectionPointerEvents="none"
|
||||
leftSection={<IconLabel size={20} />}
|
||||
placeholder={state.strings.subjectOptional}
|
||||
value={state.filter}
|
||||
onChange={(event) => actions.setFilter(event.currentTarget.value)}
|
||||
value={subject}
|
||||
onChange={(event) => setSubject(event.currentTarget.value)}
|
||||
/>
|
||||
<div className={classes.addMembers}>
|
||||
|
||||
<div>
|
||||
<Text className={classes.members}>{ state.strings.members }</Text>
|
||||
<div className={classes.addMembers}>
|
||||
{ cards.length === 0 && (
|
||||
<div className={classes.noContacts}>
|
||||
<Text className={classes.noContactsLabel}>{ state.strings.noContacts }</Text>
|
||||
</div>
|
||||
)}
|
||||
{ contacts }
|
||||
</div>
|
||||
</div>
|
||||
<div className={classes.addControls}>
|
||||
<div className={classes.addSealed}>
|
||||
{ state.sealSet && (
|
||||
<Switch label={state.strings.sealedTopic} size="md" labelPosition="left" onChange={(ev) => setSealed(ev.currentTarget.checked)} />
|
||||
)}
|
||||
</div>
|
||||
<Button variant="default" onClick={() => setAdd(false)}>
|
||||
{state.strings.cancel}
|
||||
</Button>
|
||||
<Button variant="filled" onClick={addTopic} loading={adding}>
|
||||
{state.strings.create}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
|
@ -25,12 +25,12 @@ export function useContent() {
|
||||
layout: null,
|
||||
guid: '',
|
||||
connected: [] as Card[],
|
||||
connectedAndSealable: [] as Cards[],
|
||||
sealable: [] as Cards[],
|
||||
sorted: [] as Channel[],
|
||||
filtered: [] as ChannelParams[],
|
||||
filter: '',
|
||||
topic: '',
|
||||
sealable: false,
|
||||
sealSet: false,
|
||||
});
|
||||
|
||||
const compare = (a: Card, b: Card) => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user