@truedat/cx 4.41.3 → 4.41.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/package.json +4 -4
  3. package/src/jobs/components/Job.js +11 -11
  4. package/src/jobs/components/JobRoutes.js +2 -2
  5. package/src/jobs/components/JobRow.js +7 -3
  6. package/src/jobs/components/Jobs.js +16 -28
  7. package/src/jobs/components/JobsTable.js +80 -92
  8. package/src/jobs/components/JobsView.js +23 -0
  9. package/src/jobs/components/SourceJobs.js +29 -0
  10. package/src/jobs/components/__tests__/JobRow.spec.js +44 -23
  11. package/src/jobs/components/__tests__/Jobs.spec.js +33 -8
  12. package/src/jobs/components/__tests__/JobsTable.spec.js +50 -81
  13. package/src/jobs/components/__tests__/JobsView.spec.js +39 -0
  14. package/src/jobs/components/__tests__/SourceJobs.spec.js +38 -0
  15. package/src/jobs/components/__tests__/__snapshots__/Job.spec.js.snap +3 -4
  16. package/src/jobs/components/__tests__/__snapshots__/JobRow.spec.js.snap +40 -32
  17. package/src/jobs/components/__tests__/__snapshots__/Jobs.spec.js.snap +136 -35
  18. package/src/jobs/components/__tests__/__snapshots__/JobsTable.spec.js.snap +104 -227
  19. package/src/jobs/components/__tests__/__snapshots__/JobsView.spec.js.snap +167 -0
  20. package/src/jobs/components/__tests__/__snapshots__/SourceJobs.spec.js.snap +115 -0
  21. package/src/jobs/components/index.js +1 -3
  22. package/src/jobs/selectors/index.js +4 -2
  23. package/src/jobs/selectors/{getJobColumns.js → jobColumnsSelector.js} +11 -27
  24. package/src/jobs/selectors/jobRowsSelector.js +14 -0
  25. package/src/jobs/selectors/sourceJobColumnsSelector.js +35 -0
  26. package/src/messages/en.js +9 -1
  27. package/src/messages/es.js +9 -1
  28. package/src/reducers/cxMessage.js +15 -1
  29. package/src/sources/api/fragments.js +48 -0
  30. package/src/sources/api/mutations.js +51 -0
  31. package/src/sources/api/queries.js +52 -0
  32. package/src/sources/api.js +1 -2
  33. package/src/sources/components/EditSource.js +5 -29
  34. package/src/sources/components/JobForm.js +2 -2
  35. package/src/sources/components/NewJob.js +10 -23
  36. package/src/sources/components/Source.js +12 -76
  37. package/src/sources/components/SourceActions.js +13 -21
  38. package/src/sources/components/SourceBreadcrumbs.js +1 -1
  39. package/src/sources/components/SourceConfiguration.js +60 -0
  40. package/src/sources/components/SourceDetail.js +90 -0
  41. package/src/sources/components/SourceForm.js +50 -53
  42. package/src/sources/components/SourceHeader.js +29 -0
  43. package/src/sources/components/SourceRoutes.js +25 -89
  44. package/src/sources/components/SourceSelector.js +53 -44
  45. package/src/sources/components/SourceTabs.js +54 -0
  46. package/src/sources/components/Sources.js +7 -20
  47. package/src/sources/components/SourcesTable.js +3 -4
  48. package/src/sources/components/__tests__/EditSource.spec.js +1 -2
  49. package/src/sources/components/__tests__/Source.spec.js +1 -1
  50. package/src/sources/components/__tests__/SourceActions.spec.js +3 -1
  51. package/src/sources/components/__tests__/SourceDetail.spec.js +45 -0
  52. package/src/sources/components/__tests__/SourceForm.spec.js +16 -31
  53. package/src/sources/components/__tests__/SourceHeader.spec.js +16 -0
  54. package/src/sources/components/__tests__/SourceSelector.spec.js +44 -0
  55. package/src/sources/components/__tests__/SourceTabs.spec.js +21 -0
  56. package/src/sources/components/__tests__/Sources.spec.js +5 -2
  57. package/src/sources/components/__tests__/__snapshots__/EditSource.spec.js.snap +12 -35
  58. package/src/sources/components/__tests__/__snapshots__/NewSource.spec.js.snap +1 -1
  59. package/src/sources/components/__tests__/__snapshots__/Source.spec.js.snap +23 -65
  60. package/src/sources/components/__tests__/__snapshots__/SourceActions.spec.js.snap +1 -1
  61. package/src/sources/components/__tests__/__snapshots__/SourceDetail.spec.js.snap +154 -0
  62. package/src/sources/components/__tests__/__snapshots__/SourceForm.spec.js.snap +37 -14
  63. package/src/sources/components/__tests__/__snapshots__/SourceHeader.spec.js.snap +85 -0
  64. package/src/sources/components/__tests__/__snapshots__/SourceSelector.spec.js.snap +68 -0
  65. package/src/sources/components/__tests__/__snapshots__/SourceTabs.spec.js.snap +22 -0
  66. package/src/sources/components/__tests__/__snapshots__/Sources.spec.js.snap +2 -2
  67. package/src/sources/components/__tests__/__snapshots__/SourcesTable.spec.js.snap +5 -5
  68. package/src/sources/components/index.js +1 -4
  69. package/src/sources/reducers/__tests__/sourceRedirect.spec.js +26 -21
  70. package/src/sources/reducers/__tests__/sourceUpdateStatus.spec.js +9 -9
  71. package/src/sources/reducers/index.js +1 -12
  72. package/src/sources/reducers/sourceRedirect.js +20 -10
  73. package/src/sources/reducers/sourceUpdateStatus.js +5 -5
  74. package/src/sources/routines.js +0 -3
  75. package/src/sources/sagas/__tests__/createSource.spec.js +35 -20
  76. package/src/sources/sagas/__tests__/deleteSource.spec.js +29 -14
  77. package/src/sources/sagas/__tests__/disableSource.spec.js +2 -8
  78. package/src/sources/sagas/__tests__/enableSource.spec.js +2 -8
  79. package/src/sources/sagas/__tests__/updateSource.spec.js +33 -15
  80. package/src/sources/sagas/createSource.js +24 -14
  81. package/src/sources/sagas/deleteSource.js +14 -15
  82. package/src/sources/sagas/disableSource.js +1 -17
  83. package/src/sources/sagas/enableSource.js +1 -17
  84. package/src/sources/sagas/index.js +0 -9
  85. package/src/sources/sagas/updateSource.js +18 -15
  86. package/src/sources/components/DynamicSourceForm.js +0 -60
  87. package/src/sources/components/SourceLoader.js +0 -59
  88. package/src/sources/components/SourcesLoader.js +0 -39
  89. package/src/sources/components/__tests__/DynamicSourceForm.spec.js +0 -89
  90. package/src/sources/components/__tests__/SourceLoader.spec.js +0 -54
  91. package/src/sources/components/__tests__/SourcesLoader.spec.js +0 -53
  92. package/src/sources/components/__tests__/__snapshots__/DynamicSourceForm.spec.js.snap +0 -8
  93. package/src/sources/components/__tests__/__snapshots__/SourceLoader.spec.js.snap +0 -3
  94. package/src/sources/components/__tests__/__snapshots__/SourcesLoader.spec.js.snap +0 -3
  95. package/src/sources/reducers/__tests__/source.spec.js +0 -44
  96. package/src/sources/reducers/__tests__/sourceLoading.spec.js +0 -30
  97. package/src/sources/reducers/__tests__/sources.spec.js +0 -37
  98. package/src/sources/reducers/__tests__/sourcesLoading.spec.js +0 -30
  99. package/src/sources/reducers/source.js +0 -35
  100. package/src/sources/reducers/sourceLoading.js +0 -16
  101. package/src/sources/reducers/sources.js +0 -28
  102. package/src/sources/reducers/sourcesLoading.js +0 -16
  103. package/src/sources/sagas/__tests__/fetchSource.spec.js +0 -71
  104. package/src/sources/sagas/__tests__/fetchSources.spec.js +0 -69
  105. package/src/sources/sagas/__tests__/updateSourceConfig.spec.js +0 -73
  106. package/src/sources/sagas/fetchSource.js +0 -30
  107. package/src/sources/sagas/fetchSources.js +0 -26
  108. package/src/sources/sagas/updateSourceConfig.js +0 -29
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## [4.41.4] 2022-04-04
4
+
5
+ ### Added
6
+
7
+ - [TD-4126] Improved source views to include a tab with the source's jobs
8
+
9
+ ### Changed
10
+
11
+ - [TD-4450] Use GraphQL API for querying and mutating sources, avoiding use of
12
+ global state
13
+
3
14
  ## [4.38.2]
4
15
 
5
16
  ### Changed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@truedat/cx",
3
- "version": "4.41.3",
3
+ "version": "4.41.4",
4
4
  "description": "Truedat Web Connectors",
5
5
  "sideEffects": false,
6
6
  "jsnext:main": "src/index.js",
@@ -31,7 +31,7 @@
31
31
  "@babel/plugin-transform-modules-commonjs": "^7.15.0",
32
32
  "@babel/preset-env": "^7.15.0",
33
33
  "@babel/preset-react": "^7.14.5",
34
- "@truedat/test": "4.41.2",
34
+ "@truedat/test": "4.41.4",
35
35
  "babel-jest": "^27.0.6",
36
36
  "babel-plugin-dynamic-import-node": "^2.3.3",
37
37
  "babel-plugin-lodash": "^3.3.4",
@@ -85,7 +85,7 @@
85
85
  ]
86
86
  },
87
87
  "dependencies": {
88
- "@truedat/core": "4.41.3",
88
+ "@truedat/core": "4.41.4",
89
89
  "lodash": "^4.17.21",
90
90
  "match-sorter": "^6.3.1",
91
91
  "path-to-regexp": "^1.7.0",
@@ -103,5 +103,5 @@
103
103
  "react-dom": ">= 16.8.6 < 17",
104
104
  "semantic-ui-react": ">= 0.88.2 < 2.1"
105
105
  },
106
- "gitHead": "946829496288ea4ff05b3029b37d8c8d16393127"
106
+ "gitHead": "c7038921dceb3cb9d6950fd9f57b23126ee0d8b0"
107
107
  }
@@ -4,15 +4,15 @@ import PropTypes from "prop-types";
4
4
  import { useIntl } from "react-intl";
5
5
  import Moment from "react-moment";
6
6
  import { connect } from "react-redux";
7
- import { Header, Message, Segment, Feed } from "semantic-ui-react";
7
+ import { Header, Message, Feed } from "semantic-ui-react";
8
8
 
9
- const dateDecorator = date =>
9
+ const dateDecorator = (date) =>
10
10
  date && <Moment locale="es" date={date} format="YYYY-MM-DD HH:mm:ss.SSS" />;
11
11
 
12
12
  export const icons = {
13
13
  STARTED: { name: "play circle outline", color: "green" },
14
14
  SUCCEEDED: { name: "check circle outline", color: "green" },
15
- FAILED: { name: "warning circle", color: "red" }
15
+ FAILED: { name: "warning circle", color: "red" },
16
16
  };
17
17
 
18
18
  export const Event = ({ inserted_at, message, type }) => (
@@ -29,7 +29,7 @@ export const Event = ({ inserted_at, message, type }) => (
29
29
  Event.propTypes = {
30
30
  inserted_at: PropTypes.string,
31
31
  message: PropTypes.string,
32
- type: PropTypes.string
32
+ type: PropTypes.string,
33
33
  };
34
34
 
35
35
  export const EventFeed = ({ events }) =>
@@ -42,7 +42,7 @@ export const EventFeed = ({ events }) =>
42
42
  ) : null;
43
43
 
44
44
  EventFeed.propTypes = {
45
- events: PropTypes.array
45
+ events: PropTypes.array,
46
46
  };
47
47
 
48
48
  export const JobPendingMessage = () => {
@@ -58,13 +58,13 @@ export const JobPendingMessage = () => {
58
58
  export const Job = ({ job }) => {
59
59
  const { formatMessage } = useIntl();
60
60
  return job ? (
61
- <Segment>
61
+ <>
62
62
  <Header
63
- as="h2"
64
- content={job?._embedded?.source?.external_id}
63
+ as="h4"
64
+ content={job?.external_id}
65
65
  subheader={formatMessage({
66
66
  id: `jobType.${job?.type}.label`,
67
- defaultMessage: job?.type
67
+ defaultMessage: job?.type,
68
68
  })}
69
69
  />
70
70
  {isEmpty(job?._embedded?.events) ? (
@@ -72,12 +72,12 @@ export const Job = ({ job }) => {
72
72
  ) : (
73
73
  <EventFeed events={job?._embedded?.events} />
74
74
  )}
75
- </Segment>
75
+ </>
76
76
  ) : null;
77
77
  };
78
78
 
79
79
  Job.propTypes = {
80
- job: PropTypes.object
80
+ job: PropTypes.object,
81
81
  };
82
82
 
83
83
  export const mapStateToProps = ({ job }) => ({ job });
@@ -7,7 +7,7 @@ import Job from "./Job";
7
7
  import JobBreadcrumbs from "./JobBreadcrumbs";
8
8
  import JobFiltersLoader from "./JobFiltersLoader";
9
9
  import JobLoader from "./JobLoader";
10
- import Jobs from "./Jobs";
10
+ import JobsView from "./JobsView";
11
11
  import JobsLoader from "./JobsLoader";
12
12
 
13
13
  export const JobRoutes = () => {
@@ -34,7 +34,7 @@ export const JobRoutes = () => {
34
34
  <>
35
35
  <JobsLoader />
36
36
  <JobFiltersLoader />
37
- <Jobs />
37
+ <JobsView />
38
38
  </>
39
39
  ) : (
40
40
  <Unauthorized />
@@ -8,9 +8,13 @@ import { linkTo } from "@truedat/core/routes";
8
8
 
9
9
  export const JobRow = ({ job, columns }) => {
10
10
  const history = useHistory();
11
- const id = _.prop("external_id")(job);
11
+ const id = job?.externalId || job?.external_id;
12
+ const sourceId = job?.source_id;
13
+ const url = sourceId
14
+ ? linkTo.SOURCE_JOB({ sourceId, id })
15
+ : linkTo.JOB({ id });
12
16
  return _.isEmpty(columns) || _.isEmpty(job) ? null : (
13
- <Table.Row key={id} onClick={() => history.push(linkTo.JOB({ id }))}>
17
+ <Table.Row key={id} onClick={() => history.push(url)}>
14
18
  {columns.map((column, i) => (
15
19
  <Table.Cell
16
20
  key={i}
@@ -24,7 +28,7 @@ export const JobRow = ({ job, columns }) => {
24
28
 
25
29
  JobRow.propTypes = {
26
30
  job: PropTypes.object.isRequired,
27
- columns: PropTypes.array.isRequired
31
+ columns: PropTypes.array.isRequired,
28
32
  };
29
33
 
30
34
  export default JobRow;
@@ -1,43 +1,31 @@
1
1
  import React from "react";
2
2
  import PropTypes from "prop-types";
3
3
  import { connect } from "react-redux";
4
- import { Header, Icon, Segment, Dimmer, Loader } from "semantic-ui-react";
5
- import { FormattedMessage } from "react-intl";
6
-
4
+ import { Dimmer, Loader } from "semantic-ui-react";
7
5
  import JobsSearch from "./JobsSearch";
8
6
  import JobsTable from "./JobsTable";
9
7
  import JobsLabelResults from "./JobsLabelResults";
10
8
  import JobSelectedFilters from "./JobSelectedFilters";
11
9
  import JobsPagination from "./JobsPagination";
12
10
 
13
- export const Jobs = ({ jobsLoading }) => (
14
- <Segment>
15
- <Header as="h2">
16
- <Icon circular name="cogs" />
17
- <Header.Content>
18
- <FormattedMessage id="jobs.header" />
19
- <Header.Subheader>
20
- <FormattedMessage id="jobs.subheader" />
21
- </Header.Subheader>
22
- </Header.Content>
23
- </Header>
24
- <Segment attached="bottom">
25
- <JobsSearch />
26
- <JobSelectedFilters />
27
- <Dimmer.Dimmable dimmed={jobsLoading}>
28
- <Dimmer active={jobsLoading} inverted>
29
- <Loader />
30
- </Dimmer>
31
- </Dimmer.Dimmable>
32
- <JobsLabelResults />
33
- <JobsTable />
34
- <JobsPagination />
35
- </Segment>
36
- </Segment>
11
+ export const Jobs = ({ columns, jobsLoading }) => (
12
+ <>
13
+ <JobsSearch />
14
+ <JobSelectedFilters />
15
+ <Dimmer.Dimmable dimmed={jobsLoading}>
16
+ <Dimmer active={jobsLoading} inverted>
17
+ <Loader />
18
+ </Dimmer>
19
+ </Dimmer.Dimmable>
20
+ <JobsLabelResults />
21
+ <JobsTable columns={columns} />
22
+ <JobsPagination />
23
+ </>
37
24
  );
38
25
 
39
26
  Jobs.propTypes = {
40
- jobsLoading: PropTypes.bool
27
+ jobsLoading: PropTypes.bool,
28
+ columns: PropTypes.array,
41
29
  };
42
30
 
43
31
  const mapStateToProps = ({ jobsLoading }) => ({ jobsLoading });
@@ -1,108 +1,96 @@
1
1
  import _ from "lodash/fp";
2
- import React from "react";
2
+ import React, { useEffect } from "react";
3
3
  import PropTypes from "prop-types";
4
4
  import { connect } from "react-redux";
5
5
  import { Table, Header, Icon } from "semantic-ui-react";
6
6
  import { FormattedMessage } from "react-intl";
7
7
  import { getSortInfo, sortColumn } from "@truedat/core/services/sort";
8
8
  import { sortJobs } from "../routines";
9
- import { getJobsRows, getJobColumns } from "../selectors";
9
+ import { jobRowsSelector, jobColumnsSelector } from "../selectors";
10
10
  import JobRow from "./JobRow";
11
11
 
12
- export class JobsTable extends React.Component {
13
- static propTypes = {
14
- jobsLoading: PropTypes.bool,
15
- jobs: PropTypes.array,
16
- columns: PropTypes.array,
17
- sortJobs: PropTypes.func,
18
- };
12
+ export const JobsTable = ({
13
+ columns,
14
+ jobs,
15
+ jobsLoading,
16
+ jobsSorting,
17
+ sortJobs,
18
+ }) => {
19
+ const [sortBy, setSortBy] = React.useState(null);
20
+ const [direction, setDirection] = React.useState(null);
21
+ useEffect(() => {
22
+ const { column, direction } = getSortInfo(jobsSorting);
23
+ setSortBy(column);
24
+ setDirection(direction);
25
+ }, [jobsSorting]);
19
26
 
20
- //initial state
21
- state = {
22
- sortedColumn: _.prop("column")(getSortInfo(this.props.jobsSorting)),
23
- direction: _.prop("direction")(getSortInfo(this.props.jobsSorting)),
24
- };
27
+ const sortable = _.some(_.path("sort.name"))(columns);
25
28
 
26
- setDirection = (direction) => {
27
- this.setState({ direction: direction });
28
- };
29
+ return (
30
+ <>
31
+ {!_.isEmpty(jobs) && (
32
+ <Table sortable={sortable} selectable>
33
+ <Table.Header>
34
+ <Table.Row>
35
+ {columns &&
36
+ columns.map((column, key) => (
37
+ <Table.HeaderCell
38
+ key={key}
39
+ width={column.width}
40
+ content={
41
+ <FormattedMessage
42
+ id={`jobs.props.${column.header || column.name}`}
43
+ defaultMessage={column.header || column.name}
44
+ />
45
+ }
46
+ sorted={
47
+ _.path("sort.name")(column) === sortBy ? direction : null
48
+ }
49
+ className={_.path("sort.name")(column) ? "" : "disabled"}
50
+ onClick={() =>
51
+ sortColumn(
52
+ column,
53
+ sortJobs,
54
+ setDirection,
55
+ setSortBy,
56
+ direction,
57
+ sortBy
58
+ )
59
+ }
60
+ />
61
+ ))}
62
+ </Table.Row>
63
+ </Table.Header>
64
+ <Table.Body>
65
+ {jobs.map((c, i) => (
66
+ <JobRow key={i} job={c} columns={columns} />
67
+ ))}
68
+ </Table.Body>
69
+ </Table>
70
+ )}
71
+ {_.isEmpty(jobs) && !jobsLoading && (
72
+ <Header as="h4">
73
+ <Icon name="search" />
74
+ <Header.Content>
75
+ <FormattedMessage id="jobs.search.results.empty" />
76
+ </Header.Content>
77
+ </Header>
78
+ )}
79
+ </>
80
+ );
81
+ };
29
82
 
30
- setColumn = (column) => {
31
- this.setState({ sortedColumn: column });
32
- };
83
+ JobsTable.propTypes = {
84
+ jobsLoading: PropTypes.bool,
85
+ jobsSorting: PropTypes.array,
86
+ jobs: PropTypes.array,
87
+ columns: PropTypes.array,
88
+ sortJobs: PropTypes.func,
89
+ };
33
90
 
34
- componentDidUpdate(prevProps) {
35
- if (prevProps.jobsSorting != this.props.jobsSorting) {
36
- const { column: sortedColumn, direction: direction } = getSortInfo(
37
- this.props.jobsSorting
38
- );
39
- this.setState({ sortedColumn, direction });
40
- }
41
- }
42
-
43
- render() {
44
- const { jobs, columns, jobsLoading, sortJobs } = this.props;
45
- const { sortedColumn, direction } = this.state;
46
-
47
- return (
48
- <>
49
- {!_.isEmpty(jobs) && (
50
- <Table sortable selectable>
51
- <Table.Header>
52
- <Table.Row>
53
- {columns &&
54
- columns.map((column, key) => (
55
- <Table.HeaderCell
56
- key={key}
57
- width={column.width}
58
- content={
59
- <FormattedMessage
60
- id={`jobs.props.${column.header || column.name}`}
61
- />
62
- }
63
- sorted={
64
- _.path("sort.name")(column) === sortedColumn
65
- ? direction
66
- : null
67
- }
68
- className={_.path("sort.name")(column) ? "" : "disabled"}
69
- onClick={() =>
70
- sortColumn(
71
- column,
72
- sortJobs,
73
- this.setDirection,
74
- this.setColumn,
75
- direction,
76
- sortedColumn
77
- )
78
- }
79
- />
80
- ))}
81
- </Table.Row>
82
- </Table.Header>
83
- <Table.Body>
84
- {jobs.map((c, i) => (
85
- <JobRow key={i} job={c} columns={columns} />
86
- ))}
87
- </Table.Body>
88
- </Table>
89
- )}
90
- {_.isEmpty(jobs) && !jobsLoading && (
91
- <Header as="h4">
92
- <Icon name="search" />
93
- <Header.Content>
94
- <FormattedMessage id="jobs.search.results.empty" />
95
- </Header.Content>
96
- </Header>
97
- )}
98
- </>
99
- );
100
- }
101
- }
102
-
103
- const mapStateToProps = (state) => ({
104
- columns: getJobColumns(state),
105
- jobs: getJobsRows(state),
91
+ const mapStateToProps = (state, { columns }) => ({
92
+ columns: columns || jobColumnsSelector(state),
93
+ jobs: jobRowsSelector(state),
106
94
  jobsLoading: state.jobsLoading,
107
95
  jobsSorting: _.path("jobQuery.sort")(state),
108
96
  });
@@ -0,0 +1,23 @@
1
+ import React from "react";
2
+ import { Header, Icon, Segment } from "semantic-ui-react";
3
+ import { FormattedMessage } from "react-intl";
4
+ import Jobs from "./Jobs";
5
+
6
+ export const JobsView = () => (
7
+ <Segment>
8
+ <Header as="h2">
9
+ <Icon circular name="cogs" />
10
+ <Header.Content>
11
+ <FormattedMessage id="jobs.header" />
12
+ <Header.Subheader>
13
+ <FormattedMessage id="jobs.subheader" />
14
+ </Header.Subheader>
15
+ </Header.Content>
16
+ </Header>
17
+ <Segment attached="bottom">
18
+ <Jobs />
19
+ </Segment>
20
+ </Segment>
21
+ );
22
+
23
+ export default JobsView;
@@ -0,0 +1,29 @@
1
+ import React from "react";
2
+ import PropTypes from "prop-types";
3
+ import { connect } from "react-redux";
4
+ import { sourceJobColumnsSelector } from "../selectors";
5
+ import JobFiltersLoader from "./JobFiltersLoader";
6
+ import JobsLoader from "./JobsLoader";
7
+ import Jobs from "./Jobs";
8
+
9
+ export const SourceJobs = ({ source, columns }) => {
10
+ const defaultFilters = { source_id: [source?.id] };
11
+ return (
12
+ <>
13
+ <JobsLoader defaultFilters={defaultFilters} />
14
+ <JobFiltersLoader defaultFilters={defaultFilters} />
15
+ <Jobs columns={columns} />
16
+ </>
17
+ );
18
+ };
19
+
20
+ SourceJobs.propTypes = {
21
+ source: PropTypes.object,
22
+ columns: PropTypes.array,
23
+ };
24
+
25
+ const mapStateToProps = (state) => ({
26
+ columns: sourceJobColumnsSelector(state),
27
+ });
28
+
29
+ export default connect(mapStateToProps)(SourceJobs);
@@ -1,37 +1,58 @@
1
1
  import React from "react";
2
- import { shallow } from "enzyme";
3
- import { JobRow } from "../JobRow";
2
+ import userEvent from "@testing-library/user-event";
3
+ import { render } from "@truedat/test/render";
4
+ import { jobColumnsSelector } from "../../selectors";
5
+ import JobRow from "../JobRow";
6
+
7
+ const columns = jobColumnsSelector({});
8
+ const job = {
9
+ source: {
10
+ externalId: "source external_id_2",
11
+ type: "source_type_2",
12
+ },
13
+ source_id: 123,
14
+ status: "init",
15
+ message: "Job started",
16
+ end_date: "2020-01-21 16:31",
17
+ external_id: "foo",
18
+ };
19
+ const renderOpts = {};
4
20
 
5
21
  const mockHistory = {
6
- push: jest.fn()
22
+ push: jest.fn(),
7
23
  };
8
24
 
9
25
  jest.mock("react-router-dom", () => ({
10
26
  ...jest.requireActual("react-router-dom"),
11
- useHistory: () => mockHistory
27
+ useHistory: () => mockHistory,
12
28
  }));
13
29
 
14
30
  describe("<JobRow />", () => {
15
31
  it("matches the latest snapshot", () => {
16
- const columns = [
17
- { name: "source.external_id" },
18
- { name: "source.type" },
19
- { name: "status" },
20
- { name: "message" },
21
- { name: "end_date" }
22
- ];
23
- const job = {
24
- source: {
25
- external_id: "source external_id_2",
26
- type: "source_type_2"
27
- },
28
- status: "init",
29
- message: "Job started",
30
- end_date: "2020-01-21 16:31",
31
- external_id: "foo"
32
- };
33
32
  const props = { columns, job };
34
- const wrapper = shallow(<JobRow {...props} />);
35
- expect(wrapper).toMatchSnapshot();
33
+ const { container } = render(
34
+ <table>
35
+ <tbody>
36
+ <JobRow {...props} />
37
+ </tbody>
38
+ </table>,
39
+ renderOpts
40
+ );
41
+ expect(container).toMatchSnapshot();
42
+ });
43
+
44
+ it("navigates to the job route when row is clicked", () => {
45
+ const props = { columns, job };
46
+ const { getByText } = render(
47
+ <table>
48
+ <tbody>
49
+ <JobRow {...props} />
50
+ </tbody>
51
+ </table>,
52
+ renderOpts
53
+ );
54
+ userEvent.click(getByText(/source_type_2/));
55
+ expect(mockHistory.push.mock.calls.length).toBe(1);
56
+ expect(mockHistory.push.mock.calls[0][0]).toBe("/sources/123/jobs/foo");
36
57
  });
37
58
  });
@@ -1,13 +1,38 @@
1
- import React from "react";
2
- import { shallow } from "enzyme";
3
- import { Jobs } from "../Jobs";
1
+ import React, { Suspense } from "react";
2
+ import { render } from "@truedat/test/render";
3
+ import en from "../../../messages/en";
4
+ import Jobs from "../Jobs";
4
5
 
5
- describe("<Jobs />", () => {
6
- const jobsLoading = false;
6
+ const jobs = [
7
+ {
8
+ external_id: "external_id",
9
+ source: {
10
+ external_id: "source external_id",
11
+ type: "source_type",
12
+ },
13
+ },
14
+ {
15
+ external_id: "external_id_2",
16
+ source: {
17
+ external_id: "source external_id_2",
18
+ type: "source_type_2",
19
+ },
20
+ },
21
+ ];
22
+ const state = { jobs, jobCount: 42 };
23
+ const renderOpts = {
24
+ messages: { en },
25
+ state,
26
+ };
7
27
 
28
+ describe("<Jobs />", () => {
8
29
  it("matches the latest snapshot", () => {
9
- const props = { jobsLoading };
10
- const wrapper = shallow(<Jobs {...props} />);
11
- expect(wrapper).toMatchSnapshot();
30
+ const { container } = render(
31
+ <Suspense fallback={null}>
32
+ <Jobs />
33
+ </Suspense>,
34
+ renderOpts
35
+ );
36
+ expect(container).toMatchSnapshot();
12
37
  });
13
38
  });