mirror of
https://github.com/balzack/databag.git
synced 2025-02-12 03:29:16 +00:00
added support for starting channels
This commit is contained in:
parent
e80eb49036
commit
9cad9392be
@ -3426,12 +3426,15 @@ components:
|
||||
ChannelParams:
|
||||
type: object
|
||||
required:
|
||||
- subject
|
||||
- dataType
|
||||
- data
|
||||
- groups
|
||||
- cards
|
||||
properties:
|
||||
subject:
|
||||
$ref: '#/components/schemas/Subject'
|
||||
dataType:
|
||||
type: string
|
||||
data:
|
||||
type: string
|
||||
groups:
|
||||
type: array
|
||||
items:
|
||||
|
@ -9,25 +9,26 @@ import (
|
||||
|
||||
func AddChannel(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
account, code, err := BearerAppToken(r, false)
|
||||
account, code, err := ParamAgentToken(r, false)
|
||||
if err != nil {
|
||||
ErrResponse(w, code, err)
|
||||
return
|
||||
}
|
||||
|
||||
var subject Subject
|
||||
if err := ParseRequest(r, w, &subject); err != nil {
|
||||
var params ChannelParams
|
||||
if err := ParseRequest(r, w, ¶ms); err != nil {
|
||||
ErrResponse(w, http.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
cards := []*store.Card{}
|
||||
slot := &store.ChannelSlot{}
|
||||
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
||||
|
||||
channel := &store.Channel{}
|
||||
channel.AccountID = account.ID
|
||||
channel.Data = subject.Data
|
||||
channel.DataType = subject.DataType
|
||||
channel.Data = params.Data
|
||||
channel.DataType = params.DataType
|
||||
channel.DetailRevision = account.ChannelRevision + 1
|
||||
channel.TopicRevision = account.ChannelRevision + 1
|
||||
if res := tx.Save(channel).Error; res != nil {
|
||||
@ -42,9 +43,31 @@ func AddChannel(w http.ResponseWriter, r *http.Request) {
|
||||
if res := tx.Save(slot).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
for _, cardId := range params.Cards {
|
||||
cardSlot := store.CardSlot{}
|
||||
if res := tx.Preload("Card").Where("account_id = ? AND card_slot_id = ?", account.ID, cardId).First(&cardSlot).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Model(&slot.Channel).Association("Cards").Append(cardSlot.Card); res != nil {
|
||||
return res
|
||||
}
|
||||
cards = append(cards, cardSlot.Card);
|
||||
}
|
||||
|
||||
for _, groupId := range params.Groups {
|
||||
groupSlot := store.GroupSlot{}
|
||||
if res := tx.Preload("Group").Where("account_id = ? AND group_slot_id = ?", account.ID, groupId).First(&groupSlot).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Model(&slot.Channel).Association("Groups").Append(groupSlot.Group); res != nil {
|
||||
return res
|
||||
}
|
||||
}
|
||||
|
||||
if res := tx.Model(&account).Update("channel_revision", account.ChannelRevision + 1).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
@ -53,6 +76,9 @@ func AddChannel(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
SetStatus(account)
|
||||
for _, card := range cards {
|
||||
SetContactChannelNotification(account, card);
|
||||
}
|
||||
WriteResponse(w, getChannelModel(slot, true, true))
|
||||
}
|
||||
|
||||
|
@ -200,7 +200,9 @@ type ChannelMembers struct {
|
||||
|
||||
type ChannelParams struct {
|
||||
|
||||
Subject *Subject `json:"subject"`
|
||||
DataType string `json:"dataType"`
|
||||
|
||||
Data string `json:"data"`
|
||||
|
||||
Groups []string `json:"groups"`
|
||||
|
||||
|
@ -131,10 +131,6 @@ func TestContactSync(t *testing.T) {
|
||||
¶m, nil, APP_TOKENAGENT, set.A.Token, &msg, nil))
|
||||
assert.NoError(t, ApiTestMsg(SetCloseMessage, "GET", "/contact/closeMessage",
|
||||
nil, &msg, "", "", nil, nil))
|
||||
param["cardId"] = set.D.A.CardId
|
||||
assert.NoError(t, ApiTestMsg(GetCard, "GET", "/contact/cards/{cardId}",
|
||||
¶m, nil, APP_TOKENAGENT, set.D.Token, card, nil))
|
||||
assert.Nil(t, card.Data)
|
||||
|
||||
// delete card
|
||||
param["cardId"] = set.A.C.CardId
|
||||
|
10
net/web/src/Api/addChannel.js
Normal file
10
net/web/src/Api/addChannel.js
Normal file
@ -0,0 +1,10 @@
|
||||
import { checkResponse, fetchWithTimeout } from './fetchUtil';
|
||||
|
||||
export async function addChannel(token, cards, subject, description ) {
|
||||
let data = { subject, description };
|
||||
let params = { dataType: 'superbasic', data: JSON.stringify(data), groups: [], cards };
|
||||
let channel = await fetchWithTimeout(`/content/channels?agent=${token}`, { method: 'POST', body: JSON.stringify(params)} );
|
||||
checkResponse(channel);
|
||||
return await channel.json();
|
||||
}
|
||||
|
@ -95,6 +95,13 @@ export function Contact() {
|
||||
return <></>
|
||||
}
|
||||
|
||||
const ConfirmConnect = () => {
|
||||
if (state.showButtons.confirmConnect) {
|
||||
return <ProfileButton ghost onClick={() => actions.connect()}>Save & Connect</ProfileButton>
|
||||
}
|
||||
return <></>
|
||||
}
|
||||
|
||||
const SaveRequest = () => {
|
||||
if (state.showButtons.saveRequest) {
|
||||
return <ProfileButton ghost onClick={() => actions.saveConnect()}>Save & Connect</ProfileButton>
|
||||
@ -130,6 +137,7 @@ export function Contact() {
|
||||
<Ignore />
|
||||
<Deny />
|
||||
<Save />
|
||||
<ConfirmConnect />
|
||||
<SaveRequest />
|
||||
<Connect />
|
||||
<Accept />
|
||||
|
@ -182,7 +182,7 @@ export function useContact() {
|
||||
}
|
||||
if (status === 'pending') {
|
||||
updateState({ status: 'pending' });
|
||||
updateState({ showButtons: { ignore: true, confirm: true, saveRequest: true }});
|
||||
updateState({ showButtons: { ignore: true, confirm: true, confirmConnect: true }});
|
||||
}
|
||||
if (status === 'confirmed') {
|
||||
updateState({ status: 'confirmed' });
|
||||
|
@ -18,6 +18,6 @@ export const ProfileInput = styled(Input)`
|
||||
|
||||
export const ProfileSpin = styled(Spin)`
|
||||
position: absolute;
|
||||
x-index: 10;
|
||||
z-index: 10;
|
||||
`;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import { Button, Select, Modal } from 'antd';
|
||||
import { SelectItem } from './AddChannel.styled';
|
||||
import { Button, Select, Modal, Collapse, Input } from 'antd';
|
||||
import { SelectItem, ConversationWrapper, Description, BusySpin } from './AddChannel.styled';
|
||||
import { Logo } from '../../../../../Logo/Logo';
|
||||
|
||||
export function AddChannel({ state, actions }) {
|
||||
@ -17,14 +17,24 @@ export function AddChannel({ state, actions }) {
|
||||
}, [actions]);
|
||||
|
||||
return (
|
||||
<ConversationWrapper>
|
||||
<Select
|
||||
mode="multiple"
|
||||
style={{ width: '100%' }}
|
||||
placeholder="Select Contacts"
|
||||
defaultValue={[]}
|
||||
options={options}
|
||||
onChange={(value) => console.log(value)}
|
||||
onChange={(value) => actions.setStartCards(value)}
|
||||
optionLabelProp="label"
|
||||
/>
|
||||
<Collapse ghost="true">
|
||||
<Collapse.Panel header="Conversation Details (optional)" key="1">
|
||||
<Input placeholder="Subject" onChange={(e) => actions.setStartSubject(e.target.value)} value={state.startSubject} />
|
||||
<Description placeholder="Description" autoSize={{ minRows: 2, maxRows: 6 }}
|
||||
onChange={(e) => actions.setStartDescription(e.target.value)} value={state.startDescription} />
|
||||
</Collapse.Panel>
|
||||
</Collapse>
|
||||
<BusySpin size="large" spinning={state.busy} />
|
||||
</ConversationWrapper>
|
||||
)
|
||||
}
|
||||
|
@ -1,4 +1,11 @@
|
||||
import styled from 'styled-components';
|
||||
import { Input, Spin } from 'antd';
|
||||
|
||||
export const ConversationWrapper = styled.div`
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
`;
|
||||
|
||||
export const SelectItem = styled.div`
|
||||
width: 100%;
|
||||
@ -6,3 +13,12 @@ export const SelectItem = styled.div`
|
||||
flex-direction: row;
|
||||
`;
|
||||
|
||||
export const Description = styled(Input.TextArea)`
|
||||
margin-top: 16px;
|
||||
`;
|
||||
|
||||
export const BusySpin = styled(Spin)`
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
`
|
||||
|
||||
|
@ -8,10 +8,16 @@ export function Channels({ showAdd, setShowAdd }) {
|
||||
|
||||
const { state, actions } = useChannels();
|
||||
|
||||
const onStart = async () => {
|
||||
if (await actions.addChannel()) {
|
||||
setShowAdd(false);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<ChannelsWrapper>
|
||||
<Modal title="Start Conversation" visible={showAdd} centered
|
||||
onOk={() => setShowAdd(false)} onCancel={() => setShowAdd(false)}>
|
||||
okText="Start" onOk={() => onStart()} onCancel={() => setShowAdd(false)}>
|
||||
<AddChannel state={state} actions={actions} />
|
||||
</Modal>
|
||||
</ChannelsWrapper>
|
||||
|
@ -1,11 +1,15 @@
|
||||
import { useContext, useState, useEffect } from 'react';
|
||||
import { AppContext } from '../../../../AppContext/AppContext';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { addChannel } from '../../../../Api/addChannel';
|
||||
|
||||
export function useChannels() {
|
||||
|
||||
const [state, setState] = useState({
|
||||
startCards: [],
|
||||
startSubject: '',
|
||||
startDescription: '',
|
||||
busy: false,
|
||||
});
|
||||
|
||||
const updateState = (value) => {
|
||||
@ -19,6 +23,24 @@ export function useChannels() {
|
||||
getCardImageUrl: app?.actions?.getCardImageurl,
|
||||
getCards: app?.actions?.getConnectedCards,
|
||||
setStartCards: (cards) => updateState({ startCards: cards }),
|
||||
setStartSubject: (value) => updateState({ startSubject: value }),
|
||||
setStartDescription: (value) => updateState({ startDescription: value }),
|
||||
addChannel: async () => {
|
||||
let done = false;
|
||||
if (!state.busy) {
|
||||
updateState({ busy: true });
|
||||
try {
|
||||
let channel = await addChannel(app.state.token, state.startCards, state.startSubject, state.startDescription);
|
||||
console.log(channel);
|
||||
done = true;
|
||||
}
|
||||
catch (err) {
|
||||
window.alert(err);
|
||||
}
|
||||
updateState({ busy: false });
|
||||
}
|
||||
return done;
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -46,7 +46,7 @@ export function Contacts() {
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setAddButton(addUser);
|
||||
setAddButton(addConversation);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
|
Loading…
Reference in New Issue
Block a user