Skip to content

Commit

Permalink
#38 prepare file conflict details functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
m4nv3ru committed Nov 26, 2022
1 parent 8c23a75 commit cf72719
Show file tree
Hide file tree
Showing 13 changed files with 155 additions and 36 deletions.
14 changes: 12 additions & 2 deletions ui/src/visualizations/team-awareness/chart/chart.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,16 @@ export default class TeamAwareness extends React.PureComponent {

render() {
const {
data: { stakeholders, conflicts },
data: { stakeholders, conflicts, fileDetails },
isConflictsProcessing,
isFileDetailsProcessing,
hasConflictBranchSelected,
highlightPartners,
highlightedStakeholders,
displayConflictDetails,
selectedConflict,
showConflictDetails,
startFileConflictDetails,
hideConflictDetails
} = this.props;
const { colors } = this.state;
Expand All @@ -71,7 +73,15 @@ export default class TeamAwareness extends React.PureComponent {
displayConflictDetails={displayConflictDetails}
/>
<BubbleChart content={stakeholders} colors={colors} highlightedStakeholders={highlightedStakeholders} />
<ConflictDetailsModal show={showConflictDetails} close={hideConflictDetails} selectedConflict={selectedConflict} />
<ConflictDetailsModal
fileDetails={fileDetails}
isFileDetailsProcessing={isFileDetailsProcessing}
show={showConflictDetails}
startFileConflictDetails={startFileConflictDetails}
displayConflictDetails={displayConflictDetails}
close={hideConflictDetails}
selectedConflict={selectedConflict}
/>
</div>
);
}
Expand Down
12 changes: 7 additions & 5 deletions ui/src/visualizations/team-awareness/chart/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,32 @@
import { connect } from 'react-redux';
import { getState } from '../util/util.js';
import Chart from './chart.js';
import { showConflictDetails, setConflictPartners, hideConflictDetails } from '../sagas';
import { showConflictDetails, setConflictPartners, hideConflictDetails, startTeamAwarenessFileConflictDetailsProcessing } from '../sagas';

const mapStateToProps = (appState /*, chartState */) => {
const { data, config } = getState(appState);

console.log('chart', data);
return {
highlightedStakeholders: config.highlightedStakeholders,
hasConflictBranchSelected: config.selectedConflictBranch !== 'not_set',
selectedStakeholders: config.selectedStakeholders,
isConflictsProcessing: data.isConflictsProcessing,
isFileDetailsProcessing: data.isFileDetailsProcessing,

showConflictDetails: config.showConflictDetails,
selectedConflict: config.selectedConflict,
data: {
conflicts: data.data.conflicts,
stakeholders: data.data.stakeholders,
activityTimeline: data.data.activityTimeline
activityTimeline: data.data.activityTimeline,
fileDetails: data.data.fileDetails
}
};
};

const mapDispatchToProps = dispatch => ({
highlightPartners: partners => dispatch(setConflictPartners(partners)),
displayConflictDetails: conflict => dispatch(showConflictDetails(conflict)),
startFileConflictDetails: conflict => dispatch(startTeamAwarenessFileConflictDetailsProcessing(conflict)),
displayConflictDetails: conflict => dispatch(showConflictDetails(Object.assign({ overviewType: 'files' }, conflict))),
hideConflictDetails: () => dispatch(hideConflictDetails())
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import * as styles from './ConflictDetailsModal.scss';
import FileOverview from './FileOverview/FileOverview';
import FileDetails from './FileDetails/FileDetails';

export default class ConflictDetailsModal extends React.Component {
constructor(props) {
Expand All @@ -9,17 +10,37 @@ export default class ConflictDetailsModal extends React.Component {
}

render() {
const { show, close, selectedConflict } = this.props;
if (show === false) return null;
const {
show,
close,
selectedConflict,
displayConflictDetails,
startFileConflictDetails,
isFileDetailsProcessing,
fileDetails
} = this.props;

if (show === false) return null;
const { overviewType } = selectedConflict;
const closeModal = e => {
console.log(e.target);
if (!Array.isArray(e.target.className)) return;
if (e.target.className.indexOf('darkBG') >= 0) {
close();
}
};

const content = <FileOverview selectedConflict={selectedConflict} />;
let content = <h1>Unknown content selected</h1>;
if (overviewType === 'files') {
content = (
<FileOverview
displayConflictDetails={displayConflictDetails}
startFileConflictDetails={startFileConflictDetails}
selectedConflict={selectedConflict}
/>
);
} else if (overviewType === 'fileDetails') {
content = <FileDetails fileDetails={fileDetails} isFileDetailsProcessing={isFileDetailsProcessing} />;
}

return (
<div className={this.styles.darkBG} onClick={e => closeModal(e)}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,16 @@ export default class ConflictFile extends React.Component {
}

render() {
const { filePath, conflicts } = this.props;
console.log(conflicts);
const { filePath, conflicts, displayConflictDetails, startFileConflictDetails } = this.props;

const fileIcon = filePath.endsWith('.js') ? TEXT_DOCUMENT_ICON : EMPTY_DOCUMENT_ICON;
const showInfoIcon = filePath.endsWith('.js');

const showFileDetails = conflict => {
startFileConflictDetails(conflict);
displayConflictDetails(Object.assign({ overviewType: 'fileDetails' }, conflict));
};

return (
<div>
<div className={this.styles.item}>
Expand All @@ -32,7 +36,7 @@ export default class ConflictFile extends React.Component {
</small>
<div>
{conflicts.map(c =>
<div className={this.styles.branch}>
<div key={`file_branch_${c.otherStakeholder.branch}`} className={this.styles.branch}>
<div className={this.styles.branchIcon}>
{GIT_BRANCH_ICON}
</div>
Expand All @@ -41,7 +45,7 @@ export default class ConflictFile extends React.Component {
{c.otherStakeholder.branch}
</div>
{showInfoIcon &&
<button className={this.styles.branchInfoIcon} title="View conflicts">
<button className={this.styles.branchInfoIcon} onClick={() => showFileDetails(c)} title="View conflicts">
{MAGNIFY_DOCUMENT_ICON}
</button>}
</div>
Expand Down

This file was deleted.

Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from 'react';
import * as styles from './FileDetails.scss';
import { LOADING_ICON } from '../Icons';

export default class FileDetails extends React.Component {
constructor(props) {
super(props);
this.styles = Object.assign({}, styles);
}

render() {
const { isFileDetailsProcessing, fileDetails: { selectedConflict } } = this.props;
const { conflictStakeholder, otherStakeholder } = selectedConflict;

console.log(this.props);

if (isFileDetailsProcessing) {
return (
<div className={this.styles.loadingWrapper}>
<div className={this.styles.loadingIcon}>
{LOADING_ICON}
</div>
<div>Loading file conflict details</div>
</div>
);
}
return (
<div>
<div>
Conflict between branches <a>{conflictStakeholder.branch}</a> and <a>{otherStakeholder.branch}</a>
</div>
</div>
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.loadingIcon {
height: 15px;
width: 15px;
}
.loadingWrapper {
display: flex;
flex-direction: row;
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,23 @@ export default class FileOverview extends React.Component {
files.get(c.file.path).push(c);
});

console.log(files);
return files;
}

render() {
const { selectedConflict } = this.props;
const { selectedConflict, displayConflictDetails, startFileConflictDetails } = this.props;

const fileEntries = [];
for (const [filePath, conflicts] of this.getUniqueFiles(selectedConflict)) {
fileEntries.push(<ConflictFile filePath={filePath} key={`conflicted_file_${filePath}`} conflicts={conflicts} />);
fileEntries.push(
<ConflictFile
startFileConflictDetails={startFileConflictDetails}
displayConflictDetails={displayConflictDetails}
filePath={filePath}
key={`conflicted_file_${filePath}`}
conflicts={conflicts}
/>
);
}

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import React from 'react';

const GIT_BRANCH_ICON = (
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
Expand Down Expand Up @@ -47,4 +49,10 @@ const MAGNIFY_DOCUMENT_ICON = (
</svg>
);

export { TEXT_DOCUMENT_ICON, EMPTY_DOCUMENT_ICON, GIT_BRANCH_ICON, MAGNIFY_DOCUMENT_ICON };
const LOADING_ICON = (
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
);

export { TEXT_DOCUMENT_ICON, EMPTY_DOCUMENT_ICON, GIT_BRANCH_ICON, MAGNIFY_DOCUMENT_ICON, LOADING_ICON };
14 changes: 10 additions & 4 deletions ui/src/visualizations/team-awareness/reducers/data.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default handleActions(
REQUEST_TEAM_AWARENESS_DATA: state => _.assign({}, state, { isFetching: true }),
RECEIVE_TEAM_AWARENESS_DATA: (state, action) => {
return _.assign({}, state, {
data: action.payload,
data: Object.assign(state.data, action.payload),
isFetching: false,
lastFetched: Date.now(),
receivedAt: action.meta.receivedAt
Expand All @@ -18,7 +18,11 @@ export default handleActions(
PROCESS_TEAM_AWARENESS_FILE_BROWSER: (state, action) => _.assign({}, state, { data: _.assign({}, state.data, action.payload) }),
START_TEAM_AWARENESS_CONFLICT_PROCESSING: state => Object.assign({}, state, { isConflictsProcessing: true }),
RECEIVE_TEAM_AWARENESS_CONFLICTS: (state, action) =>
Object.assign({}, state, { isConflictsProcessing: false, data: Object.assign(state.data, action.payload) })
Object.assign({}, state, { isConflictsProcessing: false, data: Object.assign(state.data, action.payload) }),
START_TEAM_AWARENESS_FILE_CONFLICT_DETAILS_PROCESSING: (state, action) =>
Object.assign({}, state, { isFileDetailsProcessing: true, data: { fileDetails: { selectedConflict: action.payload } } }),
RECEIVE_TEAM_AWARENESS_FILE_CONFLICT_DETAILS: (state, action) =>
Object.assign({}, state, { isFileDetailsProcessing: false, data: Object.assign(state.data, action.payload) })
},
{
data: {
Expand All @@ -27,10 +31,12 @@ export default handleActions(
branches: [],
commits: [],
conflicts: [],
stakeholders: []
stakeholders: [],
fileDetails: null
},
lastFetched: null,
isFetching: null,
isConflictsProcessing: false
isConflictsProcessing: false,
isFileDetailsProcessing: false
}
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { receiveTeamAwarenessFileConflictDetails } from './index';
import { put, select } from 'redux-saga/effects';
import { getState } from '../util/util';

function* processFileConflictDetails() {
const appState = yield select();
yield put(receiveTeamAwarenessFileConflictDetails(yield analyseFileConflictDetails(appState)));
}

const analyseFileConflictDetails = async appState => {
const { data: { data: { fileDetails } } } = getState(appState);

// TODO: Process file details conflict
// Fetch two files from github
// Load them via AST library
// Compare them
// Give feedback according to the AST data

return { fileDetails };
};

export { processFileConflictDetails };
9 changes: 9 additions & 0 deletions ui/src/visualizations/team-awareness/sagas/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import getBranches from './getBranches';
import getFiles from './getFiles';
import { generateFileBrowser } from './fileTreeOperations';
import { processConflictBranchSelection } from './conflictCalculations';
import { processFileConflictDetails } from './conflictDetailsOperation';

export const setActivityScale = createAction('SET_TEAM_AWARENESS_ACTIVITY_SCALE');
export const setActivityDimensions = createAction('SET_TEAM_AWARENESS_ACTIVITY_DIMENSIONS');
Expand All @@ -27,6 +28,9 @@ export const receiveTeamAwarenessDataError = timestampedActionFactory('RECEIVE_T
export const startTeamAwarenessConflictProcessing = createAction('START_TEAM_AWARENESS_CONFLICT_PROCESSING');
export const receiveTeamAwarenessConflicts = timestampedActionFactory('RECEIVE_TEAM_AWARENESS_CONFLICTS');

export const startTeamAwarenessFileConflictDetailsProcessing = createAction('START_TEAM_AWARENESS_FILE_CONFLICT_DETAILS_PROCESSING');
export const receiveTeamAwarenessFileConflictDetails = createAction('RECEIVE_TEAM_AWARENESS_FILE_CONFLICT_DETAILS');

export const requestRefresh = createAction('REQUEST_REFRESH');
const refresh = createAction('REFRESH');

Expand All @@ -44,6 +48,7 @@ export default function*() {
yield fork(watchMessages);
yield fork(watchRefresh);
yield fork(watchConflictBranch);
yield fork(watchFileConflictDetails);

yield* fetchAwarenessData();
}
Expand All @@ -55,6 +60,10 @@ const invokeAllDataGenerators = action => {
};
};

function* watchFileConflictDetails() {
yield takeEvery('START_TEAM_AWARENESS_FILE_CONFLICT_DETAILS_PROCESSING', processFileConflictDetails);
}

function* watchConflictBranch() {
yield takeEvery('SET_TEAM_AWARENESS_CONFLICT_BRANCH', processConflictBranchSelection);
yield takeEvery('SET_TEAM_AWARENESS_BRANCH', processConflictBranchSelection);
Expand Down

0 comments on commit cf72719

Please sign in to comment.