-
Notifications
You must be signed in to change notification settings - Fork 5.1k
/
application-resources-diff.tsx
88 lines (85 loc) · 4.36 KB
/
application-resources-diff.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import {Checkbox, DataLoader} from 'argo-ui';
import * as jsYaml from 'js-yaml';
import * as React from 'react';
import {Diff, Hunk, parseDiff} from 'react-diff-view';
import 'react-diff-view/style/index.css';
import {diffLines, formatLines} from 'unidiff';
import * as models from '../../../shared/models';
import {services} from '../../../shared/services';
require('./application-resources-diff.scss');
export interface ApplicationResourcesDiffProps {
states: models.ResourceDiff[];
}
export const ApplicationResourcesDiff = (props: ApplicationResourcesDiffProps) => (
<DataLoader key='resource-diff' load={() => services.viewPreferences.getPreferences()}>
{pref => {
const diffText = props.states
.map(state => {
return {
a: state.normalizedLiveState ? jsYaml.safeDump(state.normalizedLiveState, {indent: 2}) : '',
b: state.predictedLiveState ? jsYaml.safeDump(state.predictedLiveState, {indent: 2}) : '',
hook: state.hook,
// doubles as sort order
name: (state.group || '') + '/' + state.kind + '/' + state.namespace + '/' + state.name
};
})
.filter(i => !i.hook)
.filter(i => i.a !== i.b)
.map(i => {
const context = pref.appDetails.compactDiff ? 2 : Number.MAX_SAFE_INTEGER;
// react-diff-view, awesome as it is, does not accept unidiff format, you must add a git header section
return `diff --git a/${i.name} b/${i.name}
index 6829b8a2..4c565f1b 100644
${formatLines(diffLines(i.a, i.b), {context, aname: `a/${name}}`, bname: `b/${i.name}`})}`;
})
.join('\n');
// assume that if you only have one file, we don't need the file path
const whiteBox = props.states.length > 1 ? 'white-box' : '';
const showPath = props.states.length > 1;
const files = parseDiff(diffText);
const viewType = pref.appDetails.inlineDiff ? 'unified' : 'split';
return (
<div className='application-resources-diff'>
<div className={whiteBox + ' application-resources-diff__checkboxes'}>
<Checkbox
id='compactDiff'
checked={pref.appDetails.compactDiff}
onChange={() =>
services.viewPreferences.updatePreferences({
appDetails: {
...pref.appDetails,
compactDiff: !pref.appDetails.compactDiff
}
})
}
/>
<label htmlFor='compactDiff'>Compact diff</label>
<Checkbox
id='inlineDiff'
checked={pref.appDetails.inlineDiff}
onChange={() =>
services.viewPreferences.updatePreferences({
appDetails: {
...pref.appDetails,
inlineDiff: !pref.appDetails.inlineDiff
}
})
}
/>
<label htmlFor='inlineDiff'>Inline Diff</label>
</div>
{files
.sort((a: any, b: any) => a.newPath.localeCompare(b.newPath))
.map((file: any) => (
<div key={file.newPath} className={whiteBox + ' application-component-diff__diff'}>
{showPath && <p className='application-resources-diff__diff__title'>{file.newPath}</p>}
<Diff viewType={viewType} diffType={file.type} hunks={file.hunks}>
{(hunks: any) => hunks.map((hunk: any) => <Hunk key={hunk.content} hunk={hunk} />)}
</Diff>
</div>
))}
</div>
);
}}
</DataLoader>
);