Comments (8)
Hi, try to run the ONLY Board component no menu or other screens, if it does fix the problem its probably caused by wrong styles of Board parent container (try to add height/ flex it )
same issue here. i think its not solved.
from react-native-draganddrop-board.
same issues with u @@
from react-native-draganddrop-board.
same issue here. Have you fix it?
from react-native-draganddrop-board.
Hi, try to run the ONLY Board component no menu or other screens, if it does fix the problem its probably caused by wrong styles of Board parent container (try to add height/ flex it )
from react-native-draganddrop-board.
same issue here. Have you fix it?
Solved?
from react-native-draganddrop-board.
Hi, try to run the ONLY Board component no menu or other screens, if it does fix the problem its probably caused by wrong styles of Board parent container (try to add height/ flex it )
same issue here. i think its not solved.
I agree with u.
from react-native-draganddrop-board.
In my end its works great, If one of you guys can upload his project or at least his tech stack with the board code it will be great.
from react-native-draganddrop-board.
@TacticCoder
`// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {intlShape} from 'react-intl';
import {Alert, Animated, Keyboard, StyleSheet, TouchableOpacity, View, Text, Dimensions} from 'react-native';
import {General} from '@mm-redux/constants';
import EventEmitter from '@mm-redux/utils/event_emitter';
import {goToThreadScreen, showModal, showModalOverCurrentContext} from '@actions/navigation';
import LocalConfig from '@assets/config';
import {UPDATE_NATIVE_SCROLLVIEW, TYPING_VISIBLE} from '@constants/post_draft';
import CompassIcon from '@components/compass_icon';
import EphemeralStore from '@store/ephemeral_store';
import {unsupportedServer} from '@utils/supported_server';
import {preventDoubleTap} from '@utils/tap';
import {setNavigatorStyles} from '@utils/theme';
import tracker from '@utils/time_tracker';
import PushNotifications from '@init/push_notifications';
import telemetry from 'app/telemetry';
import {map, get, size, findIndex, find, noop} from 'lodash';
import {PluginType} from 'app/constants/plugin';
import {COOKIE_RESPONSE} from 'app/keycloak/index';
import AsyncStorage from '@react-native-community/async-storage';
import FastImage from 'react-native-fast-image';
import {BoardRepository, Board} from 'react-native-draganddrop-board';
import {KanbanTypes, KanbanUIStatus} from '@constants/';
import {genAssignUsers, getStateOfKanbanChannel, tagToColor} from 'app/utils/kanban';
import {getCookies} from 'app/utils/url';
export let ClientUpgradeListener;
const {height} = Dimensions.get('window');
export default class ChannelBase extends PureComponent {
static propTypes = {
actions: PropTypes.shape({
getChannelStats: PropTypes.func.isRequired,
loadChannelsForTeam: PropTypes.func.isRequired,
selectDefaultTeam: PropTypes.func.isRequired,
selectInitialChannel: PropTypes.func.isRequired,
recordLoadTime: PropTypes.func.isRequired,
getListUnreadMessage: PropTypes.func.isRequired,
handleHideKanban: PropTypes.func.isRequired,
handleOffKanban: PropTypes.func.isRequired,
handleOnKanban: PropTypes.func.isRequired,
handleShowKanban: PropTypes.func.isRequired,
getPostThread: PropTypes.func.isRequired,
selectPost: PropTypes.func.isRequired,
}).isRequired,
componentId: PropTypes.string.isRequired,
currentChannelId: PropTypes.string,
currentTeamId: PropTypes.string,
members: PropTypes.array,
currentUserId: PropTypes.string,
disableTermsModal: PropTypes.bool,
isSupportedServer: PropTypes.bool,
isSystemAdmin: PropTypes.bool,
teamName: PropTypes.string,
theme: PropTypes.object.isRequired,
showTermsOfService: PropTypes.bool,
skipMetrics: PropTypes.bool,
serverURL: PropTypes.string,
kanbanStatus: PropTypes.string,
};
static contextTypes = {
intl: intlShape.isRequired,
};
static defaultProps = {
disableTermsModal: false,
};
constructor(props) {
super(props);
this.postDraft = React.createRef();
this.state = {
channelsRequestFailed: false,
dataKanban: [],
modalKanbanVisible: false,
modalChooseLaneVisible: false,
isAddCard: false,
card: null,
lane_id: null,
cookie: null,
};
if (LocalConfig.EnableMobileClientUpgrade && !ClientUpgradeListener) {
ClientUpgradeListener = require('app/components/client_upgrade_listener').default;
}
this.typingAnimations = [];
}
handleOnKanban = async () => {
const {currentChannelId} = this.props;
await getStateOfKanbanChannel(currentChannelId, (kanbanStatus) => {
if (kanbanStatus) {
switch (kanbanStatus) {
case KanbanUIStatus.ON:
// Nếu Kanban đang ở trạng thái On [default =Hide]=> hide
this.props.actions.handleHideKanban();
break;
case KanbanUIStatus.SHOW:
// Nếu Kanban đang ở trạng thái show => SHOW
this.props.actions.handleShowKanban();
break;
case KanbanUIStatus.HIDE:
// Nếu Kanban đang ở trạng thái Hide [default =Hide]=> Hide
this.props.actions.handleHideKanban();
break;
default:
this.props.actions.handleHideKanban();
break;
}
}
});
}
handleOffKanban = () => {
this.props.actions.handleOffKanban();
}
convertDataAndArrange = async (data) => {
const result = [];
map(data?.lanes, async (lane) => {
// indexLane is the position of the Lane on the Board
const indexLane = findIndex(data?.ordered_lanes, (o) => {
return o === lane?.id;
});
const laneResult = {
id: indexLane + 1,
lane_id: lane?.id,
name: lane?.title,
creator: lane?.creator,
rows: [],
};
const rowsNow = [];
map(lane?.cards, async (card) => {
// eslint-disable-next-line max-nested-callbacks
const indexCard = findIndex(lane?.ordered_cards, (obj) => {
return obj === card?.id;
});
const assignUsersFull = await genAssignUsers(card?.data?.assignUsers, this.props.members);
// const assignUsersFull = [];
// if (size(card?.data?.assignUsers) > 0) {
// forEach(card?.data?.assignUsers, async (user) => {
// if (size(this.props.members) > 0) {
// const resultMember = find(this.props.members, (member) => {
// return member?.username === user;
// });
// assignUsersFull.push({username: user, avatar: resultMember?.avatar || null});
// }
// });
// }
rowsNow[indexCard] = {
id: (indexCard + 1),
card_id: card?.id,
lane_id: card?.lane_id,
name: card?.title,
description: card?.description,
tags: card?.data?.tags,
assignUsers: card?.data?.assignUsers || [],
assignUsersFull,
thread_id: card?.thread_id,
creator: card?.creator,
};
});
laneResult.rows = rowsNow;
result[indexLane] = laneResult;
});
return result;
}
updateDataKanban = (dataKanban) => {
this.setState({dataKanban});
if (this.state.card) {
map(dataKanban, async (lane) => {
const cardResult = find(lane?.rows, (obj) => {
return obj?.card_id === this.state.card?.card_id;
});
if (cardResult) {
this.setState({card: cardResult});
}
});
// update data card
}
}
getBoardContent = (callback = null) => {
const {serverURL, currentChannelId} = this.props;
AsyncStorage.getItem(COOKIE_RESPONSE).then(async (cookies) => {
if (cookies) {
const cookie = getCookies(JSON.parse(cookies));
this.setState({cookie});
const url_get_board = encodeURI(serverURL + `/plugins/${PluginType.CHATOPS_KANBAN_PLUGIN}/c-${currentChannelId}`);
// eslint-disable-next-line no-console
console.log('url_get_board ', url_get_board, ' \n-cookie: ', cookie);
fetch(url_get_board, {
method: 'GET',
credentials: 'include',
headers: {
Accept: 'application/json',
'x-requested-with': 'XMLHttpRequest',
cookie,
},
}).
then((res) => {
return res.json();
}).
then(async (json) => {
// eslint-disable-next-line no-console
// console.log('Dữ liệu kanban: ', JSON.stringify(json));
if (size(json) > 0) {
// eslint-disable-next-line no-console
console.log('getBoardContent data: ', JSON.stringify(json), ' member: ', this.props.members);
if (size(get(json, 'lanes', [])) > 0) {
const dataKanban = await this.convertDataAndArrange(json);
this.updateDataKanban(dataKanban);
} else {
this.setState({
dataKanban: [],
card: null,
lane_id: null,
});
}
// eslint-disable-next-line no-unused-expressions
callback && callback(true);
} else {
// Không có dữ liệu kanban = disable
this.handleOffKanban();
// eslint-disable-next-line no-unused-expressions
callback && callback(false);
}
}).
catch((e) => {
// Chạy vào đây tức là plugin kanban bị disable hoặc ko được cài plugin kanban
this.handleOffKanban();
// eslint-disable-next-line no-unused-expressions
callback && callback(false);
// eslint-disable-next-line no-console
console.log(
'[Keycloak] Call API get_board_channel FAIL',
e,
);
});
} else {
// eslint-disable-next-line no-console
console.log('[COOKIE_RESPONSE] not found => Ko gọi đc api get plugin');
this.handleOffKanban();
}
});
}
// nếu đang ở board
getBoardKanban = async () => {
this.getBoardContent((statusBoard) => {
if (statusBoard) {
this.handleOnKanban();
}
});
}
// Get board khi nhận đc socket
getBoardCurrent = async (channelIdSocket) => {
const {currentChannelId} = this.props;
if (channelIdSocket === currentChannelId) {
this.getBoardContent((statusCurrent) => {
if (statusCurrent) {
if (this.props.kanbanStatus !== KanbanUIStatus.SHOW) {
this.handleOnKanban();
}
}
});
// this.props.actions.getPostThread(rootId);
// this.props.actions.selectPost(rootId);
} else {
// eslint-disable-next-line no-console
console.log('Không phải channel đang mở nên ko cần update data kanban');
}
}
deleteLane = (lane) => {
const {serverURL, currentChannelId} = this.props;
AsyncStorage.getItem(COOKIE_RESPONSE).then(async (cookies) => {
if (cookies) {
const cookie = getCookies(JSON.parse(cookies));
this.setState({cookie});
const url_delete_card = encodeURI(serverURL + `/plugins/${PluginType.CHATOPS_KANBAN_PLUGIN}/channel/${currentChannelId}/lane/${lane?.lane_id}`);
// eslint-disable-next-line no-console
fetch(url_delete_card, {
method: 'DELETE',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
'x-requested-with': 'XMLHttpRequest',
cookie,
},
credentials: 'include',
body: null,
}).
// eslint-disable-next-line @typescript-eslint/no-unused-vars
then((res) => {
// return res.json();
}).
// then(async (json) => {
// console.log('[Done] Du lieu delete card; ', json);
// this.hideCardDetail();
// }).
catch((e) => {
// eslint-disable-next-line no-console
console.log(
'[Keycloak] Call API delete lane FAIL',
e,
);
});
} else {
// eslint-disable-next-line no-console
console.log('[COOKIE_RESPONSE] not found => Ko gọi đc api delete lane');
// this.handleOffKanban();
}
});
}
deleteCard = (item) => {
const {serverURL, currentChannelId} = this.props;
AsyncStorage.getItem(COOKIE_RESPONSE).then(async (cookies) => {
if (cookies) {
const cookie = getCookies(JSON.parse(cookies));
this.setState({cookie});
const url_delete_card = encodeURI(serverURL + `/plugins/${PluginType.CHATOPS_KANBAN_PLUGIN}/channel/${currentChannelId}/card/${item?.lane_id}/${item?.card_id}`);
// eslint-disable-next-line no-console
fetch(url_delete_card, {
method: 'DELETE',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
'x-requested-with': 'XMLHttpRequest',
cookie,
},
credentials: 'include',
body: null,
}).
// eslint-disable-next-line @typescript-eslint/no-unused-vars
then((res) => {
// return res.json();
}).
// then(async (json) => {
// console.log('[Done] Du lieu delete card; ', json);
// this.hideCardDetail();
// }).
catch((e) => {
// eslint-disable-next-line no-console
console.log(
'[Keycloak] Call API delete card FAIL',
e,
);
});
} else {
// eslint-disable-next-line no-console
console.log('[COOKIE_RESPONSE] not found => Ko gọi đc api create card');
// this.handleOffKanban();
}
});
}
clickDeleteLane = (item) => () => {
const {intl} = this.context;
Alert.alert(
intl.formatMessage({
id: 'kanban.deleteLane',
defaultMessage: 'Delete Lane',
}),
intl.formatMessage({
id: 'kanban.confirmDeleteLane',
defaultMessage: 'Are you sure you want to delete this lane?',
}),
[{
text: intl.formatMessage({
id: 'mobile.channel_list.alertNo',
defaultMessage: 'No',
}),
onPress: noop,
}, {
text: intl.formatMessage({
id: 'mobile.channel_list.alertYes',
defaultMessage: 'Yes',
}),
onPress: () => {
this.deleteLane(item);
},
}],
);
}
clickDeleteCard = (item) => () => {
const {intl} = this.context;
Alert.alert(
intl.formatMessage({
id: 'kanban.deleteCard',
defaultMessage: 'Delete Card',
}),
intl.formatMessage({
id: 'kanban.confirmDeleteCard',
defaultMessage: 'Are you sure you want to delete this card?',
}),
[{
text: intl.formatMessage({
id: 'mobile.channel_list.alertNo',
defaultMessage: 'No',
}),
onPress: noop,
}, {
text: intl.formatMessage({
id: 'mobile.channel_list.alertYes',
defaultMessage: 'Yes',
}),
onPress: () => {
this.deleteCard(item);
},
}],
);
}
clickMoveCard = (card) => () => {
this.setState({
lane_id: card?.lane_id,
card,
});
setTimeout(() => {
this.showChooseLane();
}, 350);
}
componentDidMount = async () => {
const {
actions,
currentChannelId,
currentTeamId,
disableTermsModal,
isSupportedServer,
isSystemAdmin,
showTermsOfService,
skipMetrics,
} = this.props;
AsyncStorage.getItem(COOKIE_RESPONSE).then(async (cookies) => {
if (cookies) {
const cookie = getCookies(JSON.parse(cookies));
this.setState({cookie});
}
});
EventEmitter.on('leave_team', this.handleLeaveTeam);
EventEmitter.on(TYPING_VISIBLE, this.runTypingAnimations);
EventEmitter.on(General.REMOVED_FROM_CHANNEL, this.handleRemovedFromChannel);
EventEmitter.on(KanbanTypes.GET_DATA_CHANNEL_KANBAN, this.getBoardCurrent);
if (currentTeamId) {
this.loadChannels(currentTeamId);
} else {
actions.selectDefaultTeam();
}
if (currentChannelId) {
PushNotifications.clearChannelNotifications(currentChannelId);
requestAnimationFrame(() => {
actions.getChannelStats(currentChannelId);
});
}
if (tracker.initialLoad && !skipMetrics) {
actions.recordLoadTime('Start time', 'initialLoad');
}
if (showTermsOfService && !disableTermsModal) {
this.showTermsOfServiceModal();
} else if (!isSupportedServer) {
// Only display the Alert if the TOS does not need to show first
unsupportedServer(isSystemAdmin, this.context.intl.formatMessage);
}
if (!skipMetrics) {
telemetry.end(['start:channel_screen']);
}
this.getBoardKanban();
}
componentDidUpdate(prevProps) {
if (tracker.teamSwitch) {
this.props.actions.recordLoadTime('Switch Team', 'teamSwitch');
}
if (prevProps.isSupportedServer && !this.props.isSupportedServer) {
unsupportedServer(this.props.isSystemAdmin, this.context.intl.formatMessage);
}
if (this.props.theme !== prevProps.theme) {
setNavigatorStyles(this.props.componentId, this.props.theme);
EphemeralStore.allNavigationComponentIds.forEach((componentId) => {
if (this.props.componentId !== componentId) {
setNavigatorStyles(componentId, this.props.theme);
}
});
}
if (this.props.currentTeamId &&
(!this.props.currentChannelId || this.props.currentTeamId !== prevProps.currentTeamId)) {
this.loadChannels(this.props.currentTeamId);
}
if (this.props.currentChannelId && this.props.currentChannelId !== prevProps.currentChannelId) {
// Thay đổi channel thì get lại dữ liệu
this.getBoardKanban();
PushNotifications.clearChannelNotifications(this.props.currentChannelId);
requestAnimationFrame(() => {
this.props.actions.getChannelStats(this.props.currentChannelId);
this.updateNativeScrollView();
});
}
if (LocalConfig.EnableMobileClientUpgrade && !ClientUpgradeListener) {
ClientUpgradeListener = require('app/components/client_upgrade_listener').default;
}
}
componentWillUnmount() {
EventEmitter.off('leave_team', this.handleLeaveTeam);
EventEmitter.off(TYPING_VISIBLE, this.runTypingAnimations);
EventEmitter.off(General.REMOVED_FROM_CHANNEL, this.handleRemovedFromChannel);
EventEmitter.off(KanbanTypes.GET_DATA_CHANNEL_KANBAN, this.getBoardCurrent);
}
registerTypingAnimation = (animation) => {
const length = this.typingAnimations.push(animation);
const removeAnimation = () => {
const animationIndex = length - 1;
this.typingAnimations = this.typingAnimations.filter((a, index) => index !== animationIndex);
};
return removeAnimation;
}
runTypingAnimations = (typingVisible) => {
Animated.parallel(
this.typingAnimations.map((animation) => animation(typingVisible)),
).start();
}
goToChannelInfo = preventDoubleTap(() => {
const {intl} = this.context;
const {theme} = this.props;
const screen = 'ChannelInfo';
const title = intl.formatMessage({id: 'mobile.routes.channelInfo', defaultMessage: 'Info'});
CompassIcon.getImageSource('close', 24, theme.sidebarHeaderTextColor).then((source) => {
const options = {
topBar: {
leftButtons: [{
id: 'close-info',
icon: source,
testID: 'close.channel_info.button',
}],
},
};
Keyboard.dismiss();
showModal(screen, title, null, options);
});
}, 1000);
handleLeaveTeam = () => {
this.props.actions.selectDefaultTeam();
};
handleRemovedFromChannel = (channelName) => {
const {formatMessage} = this.context.intl;
Alert.alert(
formatMessage({
id: 'mobile.user_removed.title',
defaultMessage: 'Removed from {channelName}',
}, {channelName}),
formatMessage({
id: 'mobile.user_removed.message',
defaultMessage: 'You were removed from the channel.',
}),
);
};
loadChannels = (teamId) => {
const {loadChannelsForTeam, selectInitialChannel} = this.props.actions;
if (EphemeralStore.getStartFromNotification()) {
// eslint-disable-next-line no-console
console.log('Switch to channel from a push notification');
EphemeralStore.setStartFromNotification(false);
} else {
loadChannelsForTeam(teamId).then((result) => {
if (result?.error) {
this.setState({channelsRequestFailed: true});
return;
}
this.setState({channelsRequestFailed: false});
selectInitialChannel(teamId);
});
}
};
retryLoad = () => {
const {currentTeamId, actions} = this.props;
if (currentTeamId) {
this.loadChannels(currentTeamId);
} else {
actions.selectDefaultTeam();
}
}
retryLoadChannels = () => {
this.loadChannels(this.props.currentTeamId);
};
renderLoadingOrFailedChannel() {
const {formatMessage} = this.context.intl;
const {
currentChannelId,
teamName,
theme,
} = this.props;
const {channelsRequestFailed} = this.state;
if (!currentChannelId) {
if (channelsRequestFailed) {
const FailedNetworkAction = require('app/components/failed_network_action').default;
const title = formatMessage({id: 'mobile.failed_network_action.teams_title', defaultMessage: 'Something went wrong'});
const message = formatMessage({
id: 'mobile.failed_network_action.teams_channel_description',
defaultMessage: 'Channels could not be loaded for {teamName}.',
}, {teamName});
return (
<FailedNetworkAction
errorMessage={message}
errorTitle={title}
onRetry={this.retryLoadChannels}
theme={theme}
/>
);
}
const Loading = require('app/components/channel_loader').default;
return (
<Loading
channelIsLoading={true}
color={theme.centerChannelColor}
retryLoad={this.retryLoad}
/>
);
}
return null;
}
showTermsOfServiceModal = async () => {
const {intl} = this.context;
const {isSupportedServer, isSystemAdmin, theme} = this.props;
const screen = 'TermsOfService';
const title = intl.formatMessage({id: 'mobile.tos_link', defaultMessage: 'Terms of Service'});
CompassIcon.getImageSource('close', 24, theme.sidebarHeaderTextColor).then((closeButton) => {
const passProps = {
closeButton,
isSupportedServer,
isSystemAdmin,
};
const options = {
layout: {
componentBackgroundColor: theme.centerChannelBg,
},
topBar: {
visible: true,
height: null,
title: {
color: theme.sidebarHeaderTextColor,
text: title,
},
},
};
showModalOverCurrentContext(screen, passProps, options);
});
};
updateNativeScrollView = () => {
EventEmitter.emit(UPDATE_NATIVE_SCROLLVIEW, this.props.currentChannelId);
};
goToThread = (card) => {
// console.log('post138; ', JSON.stringify(post));
telemetry.start(['post_list:thread']);
const {actions, currentChannelId} = this.props;
const channelId = currentChannelId;
const rootId = (card?.thread_id || card?.root_id);
const title = '';
const passProps = {
card,
channelId,
rootId,
};
// eslint-disable-next-line no-console
console.log('passProps:goToThread ', passProps);
Keyboard.dismiss();
actions.getPostThread(rootId);
actions.selectPost(rootId);
requestAnimationFrame(() => {
goToThreadScreen(title, passProps);
});
};
clickItem = (card) => () => {
this.setState({
card,
lane_id: card?.lane_id,
// modalKanbanVisible: true,
});
this.goToThread(card);
// this.showCardDetail();
}
showChooseLane = () => {
this.setState({modalChooseLaneVisible: true});
}
hideChooseLane = () => {
this.setState({modalChooseLaneVisible: false});
}
showCardDetail = () => {
this.setState({modalKanbanVisible: true});
}
hideCardDetail = () => {
this.setState({modalKanbanVisible: false, isAddCard: false});
}
showModalAddCard = (lane) => () => {
// eslint-disable-next-line no-console
console.log('lane add card: ', JSON.stringify(lane));
this.setState({
lane_id: lane?.lane_id, isAddCard: true,
});
setTimeout(() => {
this.setState({modalKanbanVisible: true});
}, 350);
}
hideModalAddCard = () => {
this.setState({modalKanbanVisible: false, isAddCard: false});
}
renderEmptyComponent = (lane) => {
const {intl} = this.context;
return (<View style={style.ev1}>
<FastImage
tintColor={'#1b2c3e'}
style={style.icon}
source={require('@assets/images/emptyBox.png')}
/>
<TouchableOpacity
onPress={this.showModalAddCard(lane)}
style={style.ev2}
>
<Text style={style.ev3}>{intl.formatMessage({id: 'kanban.emptyText', defaultMessage: 'Does not exist any card!'})}</Text>
<Text style={style.ev4}>{intl.formatMessage({id: 'kanban.addCardNow', defaultMessage: 'Add card now'})}</Text>
</TouchableOpacity>
</View>);
}
renderAvatarUser = (member, idx) => {
return (member?.avatar ? <FastImage
key={idx}
source={{
uri: member?.avatar,
headers: {cookie: this.state.cookie},
}}
resizeMode='contain'
style={style.v15}
/> :
(<View
key={idx}
style={style.v14}
>
<Text style={style.v13}>{member.username[0]}</Text>
</View>)
);
}
renderAssignUsers = (item) => {
// eslint-disable-next-line no-console
// console.log('item?.assignUsersFull: ', item?.assignUsersFull, ' member: ', this.props.members);
return (
size(item?.assignUsersFull) > 0 ?
<View style={style.v12}>
{
// eslint-disable-next-line react/jsx-closing-bracket-location
map(item?.assignUsersFull, ((member, idx) => {
if (idx <= 4) {
return (this.renderAvatarUser(member, idx));
}
if (idx === 5) {
return (<View
key={idx}
style={style.v14}
// eslint-disable-next-line react/jsx-closing-bracket-location
>
<Text style={style.v13}>{`+${size(item?.assignUsersFull) - 5}`}</Text>
</View>);
}
return null;
}))
}
</View> : null
);
};
renderCardContent = (item) => {
return (
<TouchableOpacity
key={item?.card_id}
activeOpacity={0.5}
onPress={this.clickItem(item)}
style={style.v1}
>
<View style={style.v2}>
<View style={style.v3}>
<Text
numberOfLines={1}
style={style.v4}
>{item?.name}</Text>
</View>
<View style={{flexDirection: 'row'}}>
<TouchableOpacity
onPress={this.clickMoveCard(item)}
style={style.v5}
>
<FastImage
tintColor={'#1b2c3e'}
style={style.iconMoveCard}
source={require('@assets/images/ic_move_card.png')}
/>
</TouchableOpacity>
<TouchableOpacity
onPress={this.clickDeleteCard(item)}
style={style.v5}
>
<CompassIcon
name='trash-can-outline'
size={16}
color={'#1b2c3e'}
style={style.v6}
/>
</TouchableOpacity>
</View>
</View>
{this.renderAssignUsers(item)}
<View style={style.v7}>
<Text
numberOfLines={3}
style={style.v8}
>{item?.description}</Text>
</View>
{
item?.tags ? <View style={style.v9}>
{
// eslint-disable-next-line react/jsx-closing-bracket-location
map(item?.tags, ((obj, index) => {
return (
<View
key={index}
style={[style.v10, {backgroundColor: tagToColor(obj)}]}
>
<Text
numberOfLines={1}
style={style.v11}
>{obj}</Text>
</View>
);
}))
}
</View> : null
}
</TouchableOpacity>
);
}
renderAddCardUI = (lane) => {
return (
<TouchableOpacity
onPress={this.showModalAddCard(lane)}
style={style.addCardBtn}
>
<FastImage
tintColor={'#1b2c3e'}
style={style.iconTini}
source={require('@assets/images/add_card.png')}
/>
</TouchableOpacity>);
}
renderRightHeaderEmptyColumn = (lane) => {
return (
<TouchableOpacity
onPress={this.clickDeleteLane(lane)}
style={style.addCardBtn}
>
<CompassIcon
name='trash-can-outline'
size={16}
color={'#1b2c3e'}
style={style.v6}
/>
</TouchableOpacity>
);
}
renderKanban = () => {
// console.log('!!!!!-------dataKanban ', JSON.stringify(this.state.dataKanban));
return (size(this.state.dataKanban) > 0 ? <View style={style.main}>
<Board
boardRepository={new BoardRepository(this.state.dataKanban)}
emptyIconColor={'#1b2c3e'}
boardBackground={'#fff'}
// emptyText={intl.formatMessage({ id: 'kanban.emptyText', defaultMessage: 'Does not exist any card!' })}
columnBackgroundColor={'#dddddd'}
columnNameTextColor={'#1b2c3e'}
columnNameFontSize={16}
columnHeight={height - 80}
badgeHeight={20}
badgeWidth={20}
badgeBorderRadius={8}
badgeTextFontSize={10}
badgeBackgroundColor={'#F01E24'}
// eslint-disable-next-line @typescript-eslint/no-empty-function
onDragEnd={() => { }}
// eslint-disable-next-line @typescript-eslint/no-empty-function
open={() => { }}
cardContent={this.renderCardContent}
viewRightHeaderColumn={this.renderAddCardUI}
viewRightHeaderEmptyColumn={this.renderRightHeaderEmptyColumn}
emptyComponent={this.renderEmptyComponent}
/>
</View> : <></>);
}
render() {
// Overriden in channel.android.js and channel.ios.js
// but defined here for channel_base.test.js
return; // eslint-disable-line no-useless-return
}
}
export const style = StyleSheet.create({
addCardBtn: {padding: 4, borderRadius: 4},
flex: {flex: 1},
icon: {width: 50, height: 50},
iconTini: {width: 20, height: 20},
iconMoveCard: {width: 18, height: 18},
main: {width: '100%', flex: 1},
ev1: {flex: 1, width: '100%', alignItems: 'center', justifyContent: 'center'},
ev2: {paddingVertical: 4},
ev3: {fontSize: 13, color: '#1b2c3e', textAlign: 'center'},
av4: {fontSize: 12, color: '#1b2c3e', textAlign: 'center', paddingVertical: 4},
ev4: {textDecorationStyle: 'solid', textDecorationLine: 'underline', fontSize: 14, color: '#1b2c3e', textAlign: 'center', paddingHorizontal: 16, paddingVertical: 4},
v1: {backgroundColor: '#fff', marginBottom: 8, padding: 8, borderRadius: 4},
v2: {width: '100%', borderBottomWidth: 0.5, borderBottomColor: '#00000050', flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between'},
v3: {flex: 1},
v4: {paddingBottom: 4, fontSize: 13, fontWeight: 'bold', color: '#000'},
v5: {alignItems: 'center', paddingBottom: 4},
v6: {paddingLeft: 16},
v7: {width: '100%'},
v8: {paddingVertical: 4, fontSize: 13, color: '#000'},
v9: {width: '100%', flexDirection: 'row', flexWrap: 'wrap'},
v12: {width: '100%', flexDirection: 'row', flexWrap: 'wrap', justifyContent: 'flex-end', alignItems: 'center', paddingTop: 8},
v10: {
alignItems: 'center',
justifyContent: 'center',
marginRight: 4,
marginTop: 4,
borderRadius: 4,
overflow: 'hidden',
},
v11: {paddingHorizontal: 4, paddingVertical: 3, color: '#fff', fontSize: 12},
v13: {paddingHorizontal: 4, paddingVertical: 3, color: '#162A4C', fontSize: 10, textTransform: 'uppercase'},
v14: {backgroundColor: '#CCCCCC80', width: 24, height: 24, borderRadius: 12, alignItems: 'center', justifyContent: 'center', marginRight: 2},
v15: {width: 24, height: 24, borderRadius: 12, backgroundColor: '#ccc', marginRight: 2},
});
`
from react-native-draganddrop-board.
Related Issues (20)
- TypeError: Cannot read property 'y' of undefined
- TypeError: undefined is not an object (evaluating '_this.listeners[columnId][event]' HOT 9
- Cannot update data successfully HOT 3
- Cannot move the board items HOT 1
- Cannot move Card if using cardContent HOT 3
- Ipad Compatibles HOT 7
- How can I put onPress event when I click the Board Column Title?
- Board data is not showing once loaded then going back again to the screen. HOT 8
- Integrate with API
- Really slow when loading 50+ items
- How can get selected column HOT 1
- Vertical instead of horizontal?
- How can I make the drag and drop smoothly? HOT 1
- How to draganddrop cart item ? HOT 1
- Uncaught TypeError: styled_components__WEBPACK_IMPORTED_MODULE_1__.default.View is not a function
- feat: Can we make 3 or 4 column in screen with props.
- boardRepository.updateData(data);
- Update React
- undefined is not an object (evaluating '_this.listeners[columnId][event]')
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from react-native-draganddrop-board.