@truedat/bg 7.4.0 → 7.4.2
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.
- package/package.json +6 -6
- package/src/concepts/components/Concept.js +28 -6
- package/src/concepts/components/ConceptContext.js +37 -0
- package/src/concepts/components/__tests__/Concept.spec.js +50 -1
- package/src/concepts/components/__tests__/ConceptContext.spec.js +47 -0
- package/src/concepts/components/__tests__/__snapshots__/Concept.spec.js.snap +181 -0
- package/src/concepts/components/__tests__/__snapshots__/ConceptContext.spec.js.snap +9 -0
- package/src/concepts/reducers/concept.js +1 -0
- package/src/concepts/relations/components/ConceptLinkActions.js +47 -17
- package/src/concepts/relations/components/ConceptLinksActions.js +49 -22
- package/src/concepts/relations/components/ConceptLinkstRequestGrantButton.js +65 -0
- package/src/concepts/relations/components/ConceptStructureLinks.js +92 -9
- package/src/concepts/relations/components/__tests__/ConceptLinksActions.spec.js +65 -0
- package/src/concepts/relations/components/__tests__/ConceptLinkstRequestGrantButton.spec.js +37 -0
- package/src/concepts/relations/components/__tests__/ConceptStructureLinks.spec.js +82 -6
- package/src/concepts/relations/components/__tests__/__snapshots__/ConceptLinksActions.spec.js.snap +61 -0
- package/src/concepts/relations/components/__tests__/__snapshots__/ConceptLinkstRequestGrantButton.spec.js.snap +16 -0
- package/src/concepts/relations/components/__tests__/__snapshots__/ConceptStructureLinks.spec.js.snap +193 -28
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truedat/bg",
|
|
3
|
-
"version": "7.4.
|
|
3
|
+
"version": "7.4.2",
|
|
4
4
|
"description": "Truedat Web Business Glossary",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"jsnext:main": "src/index.js",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"@testing-library/jest-dom": "^5.16.5",
|
|
35
35
|
"@testing-library/react": "^12.0.0",
|
|
36
36
|
"@testing-library/user-event": "^13.2.1",
|
|
37
|
-
"@truedat/test": "7.4.
|
|
37
|
+
"@truedat/test": "7.4.2",
|
|
38
38
|
"babel-jest": "^28.1.0",
|
|
39
39
|
"babel-plugin-dynamic-import-node": "^2.3.3",
|
|
40
40
|
"babel-plugin-lodash": "^3.3.4",
|
|
@@ -86,9 +86,9 @@
|
|
|
86
86
|
]
|
|
87
87
|
},
|
|
88
88
|
"dependencies": {
|
|
89
|
-
"@truedat/core": "7.4.
|
|
90
|
-
"@truedat/df": "7.4.
|
|
91
|
-
"@truedat/lm": "7.4.
|
|
89
|
+
"@truedat/core": "7.4.2",
|
|
90
|
+
"@truedat/df": "7.4.2",
|
|
91
|
+
"@truedat/lm": "7.4.2",
|
|
92
92
|
"decode-uri-component": "^0.2.2",
|
|
93
93
|
"file-saver": "^2.0.5",
|
|
94
94
|
"moment": "^2.29.4",
|
|
@@ -111,5 +111,5 @@
|
|
|
111
111
|
"react-dom": ">= 16.8.6 < 17",
|
|
112
112
|
"semantic-ui-react": ">= 2.0.3 < 2.2"
|
|
113
113
|
},
|
|
114
|
-
"gitHead": "
|
|
114
|
+
"gitHead": "bfc4801642aec7b29767605d30866b52f67aacce"
|
|
115
115
|
}
|
|
@@ -4,6 +4,7 @@ import PropTypes from "prop-types";
|
|
|
4
4
|
import { connect } from "react-redux";
|
|
5
5
|
import { Route } from "react-router-dom";
|
|
6
6
|
import { Grid, Segment } from "semantic-ui-react";
|
|
7
|
+
import StructureGrantCart from "@truedat/dd/components/StructureGrantCart";
|
|
7
8
|
import { Comments, CommentsLoader } from "@truedat/core/components";
|
|
8
9
|
import { CONCEPT_VERSION } from "@truedat/core/routes";
|
|
9
10
|
import { useIntl } from "react-intl";
|
|
@@ -19,6 +20,7 @@ import ConceptTabPane from "./ConceptTabPane";
|
|
|
19
20
|
import ConceptSummary from "./ConceptSummary";
|
|
20
21
|
import ConceptTaxonomy from "./ConceptTaxonomy";
|
|
21
22
|
import SharedToDomains from "./SharedToDomains";
|
|
23
|
+
import ConceptContextProvider, { useConceptContext } from "./ConceptContext";
|
|
22
24
|
|
|
23
25
|
const EventsLoader = React.lazy(() =>
|
|
24
26
|
import("@truedat/audit/components/EventsLoader")
|
|
@@ -35,6 +37,9 @@ const ConceptRulesLoader = React.lazy(() =>
|
|
|
35
37
|
export const Concept = ({ id, concept }) => {
|
|
36
38
|
const { locales } = useLanguage();
|
|
37
39
|
const { locale } = useIntl();
|
|
40
|
+
const {
|
|
41
|
+
conceptContext: { grantView },
|
|
42
|
+
} = useConceptContext();
|
|
38
43
|
|
|
39
44
|
const defaultLang = _.flow(
|
|
40
45
|
_.find({ is_default: true }),
|
|
@@ -128,11 +133,17 @@ export const Concept = ({ id, concept }) => {
|
|
|
128
133
|
/>
|
|
129
134
|
</Grid.Column>
|
|
130
135
|
<Grid.Column width={4}>
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
+
{grantView ? (
|
|
137
|
+
<StructureGrantCart allowEmptyCart />
|
|
138
|
+
) : (
|
|
139
|
+
<>
|
|
140
|
+
<ConceptSummary />
|
|
141
|
+
<ConceptRelationsSummary />
|
|
142
|
+
<ConceptTaxonomy />
|
|
143
|
+
<SharedToDomains />
|
|
144
|
+
<ConceptCompleteness />
|
|
145
|
+
</>
|
|
146
|
+
)}
|
|
136
147
|
</Grid.Column>
|
|
137
148
|
</Grid>
|
|
138
149
|
</>
|
|
@@ -144,9 +155,20 @@ Concept.propTypes = {
|
|
|
144
155
|
concept: PropTypes.object,
|
|
145
156
|
};
|
|
146
157
|
|
|
158
|
+
const ConceptWrapper = ({ id, concept }) => (
|
|
159
|
+
<ConceptContextProvider>
|
|
160
|
+
<Concept id={id} concept={concept} />
|
|
161
|
+
</ConceptContextProvider>
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
ConceptWrapper.propTypes = {
|
|
165
|
+
id: PropTypes.number.isRequired,
|
|
166
|
+
concept: PropTypes.object,
|
|
167
|
+
};
|
|
168
|
+
|
|
147
169
|
const mapStateToProps = ({ concept }) => ({
|
|
148
170
|
id: _.prop("business_concept_id")(concept),
|
|
149
171
|
concept: concept,
|
|
150
172
|
});
|
|
151
173
|
|
|
152
|
-
export default connect(mapStateToProps)(
|
|
174
|
+
export default connect(mapStateToProps)(ConceptWrapper);
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import React, { createContext, useState, useContext } from "react";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
|
|
4
|
+
export const ConceptContext = createContext("conceptContext");
|
|
5
|
+
|
|
6
|
+
const initialContext = {
|
|
7
|
+
grantView: false,
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export const ConceptContextProvider = ({ children }) => {
|
|
11
|
+
const [context, setContext] = useState(initialContext);
|
|
12
|
+
|
|
13
|
+
const setProperty = (value) =>
|
|
14
|
+
setContext({
|
|
15
|
+
...context,
|
|
16
|
+
...value,
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<ConceptContext.Provider
|
|
21
|
+
value={{
|
|
22
|
+
conceptContext: context,
|
|
23
|
+
setConceptContextProperty: setProperty,
|
|
24
|
+
}}
|
|
25
|
+
>
|
|
26
|
+
{children}
|
|
27
|
+
</ConceptContext.Provider>
|
|
28
|
+
);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
ConceptContextProvider.propTypes = {
|
|
32
|
+
children: PropTypes.node,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const useConceptContext = () => useContext(ConceptContext);
|
|
36
|
+
|
|
37
|
+
export default ConceptContextProvider;
|
|
@@ -3,6 +3,31 @@ import { render } from "@truedat/test/render";
|
|
|
3
3
|
import { waitFor } from "@testing-library/react";
|
|
4
4
|
import { LangProviderWrapper } from "@truedat/core/i18n";
|
|
5
5
|
import { Concept } from "../Concept";
|
|
6
|
+
import ConceptContextProvider, { useConceptContext } from "../ConceptContext";
|
|
7
|
+
|
|
8
|
+
jest.mock("../ConceptContext", () => {
|
|
9
|
+
const originalModule = jest.requireActual("../ConceptContext");
|
|
10
|
+
|
|
11
|
+
return {
|
|
12
|
+
__esModule: true,
|
|
13
|
+
...originalModule,
|
|
14
|
+
useConceptContext: jest.fn(),
|
|
15
|
+
};
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
jest.mock("@truedat/core/hooks", () => {
|
|
19
|
+
const originalModule = jest.requireActual("@truedat/core/hooks");
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
__esModule: true,
|
|
23
|
+
...originalModule,
|
|
24
|
+
useOperators: () => ({
|
|
25
|
+
data: {},
|
|
26
|
+
error: false,
|
|
27
|
+
loading: false,
|
|
28
|
+
}),
|
|
29
|
+
};
|
|
30
|
+
});
|
|
6
31
|
|
|
7
32
|
beforeAll(() => {
|
|
8
33
|
jest.useFakeTimers();
|
|
@@ -116,9 +141,33 @@ describe("<Concept />", () => {
|
|
|
116
141
|
};
|
|
117
142
|
|
|
118
143
|
it("matches the latest snapshot", async () => {
|
|
144
|
+
useConceptContext.mockReturnValue({
|
|
145
|
+
conceptContext: { grantView: false },
|
|
146
|
+
});
|
|
147
|
+
const { container, queryByText } = render(
|
|
148
|
+
<LangProviderWrapper langs={["es", "en"]}>
|
|
149
|
+
<ConceptContextProvider>
|
|
150
|
+
<Concept {...props} />
|
|
151
|
+
</ConceptContextProvider>
|
|
152
|
+
</LangProviderWrapper>,
|
|
153
|
+
renderOpts
|
|
154
|
+
);
|
|
155
|
+
await waitFor(() => {
|
|
156
|
+
expect(queryByText(/lazy/i)).not.toBeInTheDocument();
|
|
157
|
+
expect(container.querySelector(".loading")).not.toBeInTheDocument();
|
|
158
|
+
});
|
|
159
|
+
expect(container).toMatchSnapshot();
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it("matches the latest snapshot with grantView activated", async () => {
|
|
163
|
+
useConceptContext.mockReturnValue({
|
|
164
|
+
conceptContext: { grantView: true },
|
|
165
|
+
});
|
|
119
166
|
const { container, queryByText } = render(
|
|
120
167
|
<LangProviderWrapper langs={["es", "en"]}>
|
|
121
|
-
<
|
|
168
|
+
<ConceptContextProvider>
|
|
169
|
+
<Concept {...props} />
|
|
170
|
+
</ConceptContextProvider>
|
|
122
171
|
</LangProviderWrapper>,
|
|
123
172
|
renderOpts
|
|
124
173
|
);
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React, { useEffect } from "react";
|
|
2
|
+
import { render } from "@truedat/test/render";
|
|
3
|
+
import { renderHook, act } from "@testing-library/react-hooks";
|
|
4
|
+
import ConceptContext, { useConceptContext } from "../ConceptContext";
|
|
5
|
+
|
|
6
|
+
describe("<ConceptContext />", () => {
|
|
7
|
+
it("matches the latest snapshot", async () => {
|
|
8
|
+
const { container } = render(
|
|
9
|
+
<ConceptContext>
|
|
10
|
+
<div>Hello world</div>
|
|
11
|
+
</ConceptContext>
|
|
12
|
+
);
|
|
13
|
+
expect(container).toMatchSnapshot();
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it("should update context with new values when setProperty is called", () => {
|
|
17
|
+
const { result } = renderHook(() => useConceptContext(), {
|
|
18
|
+
wrapper: ({ children }) => <ConceptContext>{children}</ConceptContext>,
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
act(() => {
|
|
22
|
+
result.current.setConceptContextProperty({ newKey: "newValue" });
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
expect(result.current.conceptContext).toEqual(
|
|
26
|
+
expect.objectContaining({ newKey: "newValue" })
|
|
27
|
+
);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it("should provide context values to child components", () => {
|
|
31
|
+
const TestComponent = () => {
|
|
32
|
+
const { conceptContext, setConceptContextProperty } = useConceptContext();
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
setConceptContextProperty({ testKey: "testValue" });
|
|
35
|
+
}, []);
|
|
36
|
+
return <div>{conceptContext.testKey}</div>;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const { getByText } = render(
|
|
40
|
+
<ConceptContext>
|
|
41
|
+
<TestComponent />
|
|
42
|
+
</ConceptContext>
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
expect(getByText("testValue")).toBeInTheDocument();
|
|
46
|
+
});
|
|
47
|
+
});
|
|
@@ -307,3 +307,184 @@ exports[`<Concept /> matches the latest snapshot 1`] = `
|
|
|
307
307
|
</div>
|
|
308
308
|
</div>
|
|
309
309
|
`;
|
|
310
|
+
|
|
311
|
+
exports[`<Concept /> matches the latest snapshot with grantView activated 1`] = `
|
|
312
|
+
<div>
|
|
313
|
+
<div
|
|
314
|
+
class="ui breadcrumb"
|
|
315
|
+
>
|
|
316
|
+
<a
|
|
317
|
+
class="section"
|
|
318
|
+
href="/concepts"
|
|
319
|
+
>
|
|
320
|
+
Business Glossary
|
|
321
|
+
</a>
|
|
322
|
+
<i
|
|
323
|
+
aria-hidden="true"
|
|
324
|
+
class="right angle icon divider"
|
|
325
|
+
/>
|
|
326
|
+
<a
|
|
327
|
+
class="section"
|
|
328
|
+
href="/concepts/pending"
|
|
329
|
+
>
|
|
330
|
+
Draft
|
|
331
|
+
</a>
|
|
332
|
+
<i
|
|
333
|
+
aria-hidden="true"
|
|
334
|
+
class="right angle icon divider"
|
|
335
|
+
/>
|
|
336
|
+
<span
|
|
337
|
+
class="active section"
|
|
338
|
+
style="cursor: default;"
|
|
339
|
+
>
|
|
340
|
+
Concept_en
|
|
341
|
+
</span>
|
|
342
|
+
</div>
|
|
343
|
+
<div
|
|
344
|
+
class="ui equal width grid"
|
|
345
|
+
style="margin-top: 0px;"
|
|
346
|
+
>
|
|
347
|
+
<div
|
|
348
|
+
class="twelve wide column"
|
|
349
|
+
>
|
|
350
|
+
<div
|
|
351
|
+
class="ui segment"
|
|
352
|
+
>
|
|
353
|
+
<div
|
|
354
|
+
class="ui grid"
|
|
355
|
+
>
|
|
356
|
+
<div
|
|
357
|
+
class="row"
|
|
358
|
+
>
|
|
359
|
+
<div
|
|
360
|
+
class="eight wide column"
|
|
361
|
+
>
|
|
362
|
+
<h2
|
|
363
|
+
class="ui header"
|
|
364
|
+
>
|
|
365
|
+
<i
|
|
366
|
+
aria-hidden="true"
|
|
367
|
+
class="book circular icon"
|
|
368
|
+
/>
|
|
369
|
+
<div
|
|
370
|
+
class="content"
|
|
371
|
+
>
|
|
372
|
+
Concept_es
|
|
373
|
+
<div
|
|
374
|
+
class="sub header"
|
|
375
|
+
>
|
|
376
|
+
templates.undefined
|
|
377
|
+
</div>
|
|
378
|
+
</div>
|
|
379
|
+
</h2>
|
|
380
|
+
</div>
|
|
381
|
+
<div
|
|
382
|
+
class="right aligned eight wide column"
|
|
383
|
+
>
|
|
384
|
+
<button
|
|
385
|
+
class="ui basic icon button button icon group-actions"
|
|
386
|
+
data-tooltip="Sharing"
|
|
387
|
+
>
|
|
388
|
+
<i
|
|
389
|
+
aria-hidden="true"
|
|
390
|
+
class="share alternate icon"
|
|
391
|
+
/>
|
|
392
|
+
</button>
|
|
393
|
+
<button
|
|
394
|
+
class="ui basic icon button button icon group-actions structureButton"
|
|
395
|
+
>
|
|
396
|
+
<i
|
|
397
|
+
aria-hidden="true"
|
|
398
|
+
class="eye icon"
|
|
399
|
+
/>
|
|
400
|
+
</button>
|
|
401
|
+
</div>
|
|
402
|
+
</div>
|
|
403
|
+
<div
|
|
404
|
+
class="row"
|
|
405
|
+
>
|
|
406
|
+
<div
|
|
407
|
+
class="eight wide column"
|
|
408
|
+
>
|
|
409
|
+
<div
|
|
410
|
+
class="ui left floated buttons"
|
|
411
|
+
>
|
|
412
|
+
<button
|
|
413
|
+
class="ui mini active button"
|
|
414
|
+
>
|
|
415
|
+
Spanish
|
|
416
|
+
</button>
|
|
417
|
+
<button
|
|
418
|
+
class="ui mini button"
|
|
419
|
+
>
|
|
420
|
+
English
|
|
421
|
+
</button>
|
|
422
|
+
</div>
|
|
423
|
+
</div>
|
|
424
|
+
<div
|
|
425
|
+
class="right aligned eight wide column"
|
|
426
|
+
/>
|
|
427
|
+
</div>
|
|
428
|
+
</div>
|
|
429
|
+
<div
|
|
430
|
+
class="ui pointing secondary top attached tabular menu"
|
|
431
|
+
>
|
|
432
|
+
<a
|
|
433
|
+
class="item"
|
|
434
|
+
href="/concepts/1/versions/1"
|
|
435
|
+
>
|
|
436
|
+
Concept
|
|
437
|
+
</a>
|
|
438
|
+
<a
|
|
439
|
+
class="item"
|
|
440
|
+
href="/concepts/1/versions/1/links/structures"
|
|
441
|
+
>
|
|
442
|
+
Linkage
|
|
443
|
+
</a>
|
|
444
|
+
<a
|
|
445
|
+
class="item"
|
|
446
|
+
href="/concepts/1/versions/1/rules"
|
|
447
|
+
>
|
|
448
|
+
Quality Rules
|
|
449
|
+
</a>
|
|
450
|
+
<a
|
|
451
|
+
class="item"
|
|
452
|
+
href="/concepts/1/versions/1/archive"
|
|
453
|
+
>
|
|
454
|
+
History
|
|
455
|
+
</a>
|
|
456
|
+
<a
|
|
457
|
+
class="item"
|
|
458
|
+
href="/concepts/1/versions/1/events"
|
|
459
|
+
>
|
|
460
|
+
Audit
|
|
461
|
+
</a>
|
|
462
|
+
</div>
|
|
463
|
+
</div>
|
|
464
|
+
</div>
|
|
465
|
+
<div
|
|
466
|
+
class="four wide column"
|
|
467
|
+
>
|
|
468
|
+
<div
|
|
469
|
+
class="ui segment structure-grant-cart"
|
|
470
|
+
>
|
|
471
|
+
<div
|
|
472
|
+
class="ui header"
|
|
473
|
+
title="structure.grant.cart"
|
|
474
|
+
>
|
|
475
|
+
structure.grant.cart
|
|
476
|
+
</div>
|
|
477
|
+
<div
|
|
478
|
+
class="ui divider"
|
|
479
|
+
/>
|
|
480
|
+
<div
|
|
481
|
+
class="list"
|
|
482
|
+
/>
|
|
483
|
+
<p>
|
|
484
|
+
structure.grant.cart.empty
|
|
485
|
+
</p>
|
|
486
|
+
</div>
|
|
487
|
+
</div>
|
|
488
|
+
</div>
|
|
489
|
+
</div>
|
|
490
|
+
`;
|
|
@@ -1,29 +1,55 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
|
-
import React from "react";
|
|
2
|
+
import React, { useState } from "react";
|
|
3
|
+
import { PropTypes } from "prop-types";
|
|
3
4
|
import { connect } from "react-redux";
|
|
4
|
-
import { Icon } from "semantic-ui-react";
|
|
5
|
+
import { Button, Icon } from "semantic-ui-react";
|
|
5
6
|
import { FormattedMessage } from "react-intl";
|
|
6
7
|
import { ConfirmModal } from "@truedat/core/components";
|
|
7
8
|
import { conceptLinkAction } from "../routines";
|
|
8
9
|
|
|
9
|
-
export const DeleteLink = ({ conceptLinkAction, action, loading }) =>
|
|
10
|
-
|
|
10
|
+
export const DeleteLink = ({ conceptLinkAction, action, loading }) => {
|
|
11
|
+
const [openModal, setOpenModal] = useState(false);
|
|
12
|
+
|
|
13
|
+
return loading ? (
|
|
11
14
|
<Icon loading name="circle notch" color="red" />
|
|
12
15
|
) : (
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
16
|
+
<>
|
|
17
|
+
<ConfirmModal
|
|
18
|
+
open={openModal}
|
|
19
|
+
trigger={
|
|
20
|
+
<Button
|
|
21
|
+
basic
|
|
22
|
+
color="red"
|
|
23
|
+
icon
|
|
24
|
+
onClick={() => setOpenModal(true)}
|
|
25
|
+
size="mini"
|
|
26
|
+
>
|
|
27
|
+
<Icon name="trash alternate outline" color="red" />
|
|
28
|
+
</Button>
|
|
29
|
+
}
|
|
30
|
+
header={
|
|
31
|
+
<FormattedMessage id="relations.actions.data_field.delete.confirmation.header" />
|
|
32
|
+
}
|
|
33
|
+
content={
|
|
34
|
+
<FormattedMessage id="relations.actions.data_field.delete.confirmation.content" />
|
|
35
|
+
}
|
|
36
|
+
onConfirm={() => conceptLinkAction(action)}
|
|
37
|
+
onOpen={() => {
|
|
38
|
+
setOpenModal(true);
|
|
39
|
+
}}
|
|
40
|
+
onClose={() => {
|
|
41
|
+
setOpenModal(false);
|
|
42
|
+
}}
|
|
43
|
+
/>
|
|
44
|
+
</>
|
|
26
45
|
);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
DeleteLink.propTypes = {
|
|
49
|
+
conceptLinkAction: PropTypes.func,
|
|
50
|
+
action: PropTypes.object,
|
|
51
|
+
loading: PropTypes.bool,
|
|
52
|
+
};
|
|
27
53
|
|
|
28
54
|
const mapStateToProps = ({ conceptLinkActionLoading }, ownProps) => ({
|
|
29
55
|
loading: _.pathEq("action.href")(conceptLinkActionLoading)(ownProps),
|
|
@@ -36,4 +62,8 @@ export const DeleteLinkConnected = connect(mapStateToProps, {
|
|
|
36
62
|
export const LinkActions = ({ delete: deleteAction }) =>
|
|
37
63
|
deleteAction ? <DeleteLinkConnected action={deleteAction} /> : null;
|
|
38
64
|
|
|
65
|
+
LinkActions.propTypes = {
|
|
66
|
+
delete: PropTypes.object,
|
|
67
|
+
};
|
|
68
|
+
|
|
39
69
|
export default LinkActions;
|
|
@@ -1,37 +1,64 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
|
+
import { useIntl } from "react-intl";
|
|
4
5
|
import { connect } from "react-redux";
|
|
5
6
|
import { Button } from "semantic-ui-react";
|
|
6
7
|
import { Link } from "react-router-dom";
|
|
7
|
-
import { FormattedMessage } from "react-intl";
|
|
8
8
|
import { linkTo } from "@truedat/core/routes";
|
|
9
|
+
import { Checkbox } from "semantic-ui-react";
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
11
|
+
import ConceptLinkstRequestGrantButton from "./ConceptLinkstRequestGrantButton";
|
|
12
|
+
|
|
13
|
+
export const ConceptLinksActions = ({
|
|
14
|
+
canManageGrantRequests,
|
|
15
|
+
createLinkUrl,
|
|
16
|
+
grantView,
|
|
17
|
+
onGrantViewChange,
|
|
18
|
+
}) => {
|
|
19
|
+
const { formatMessage } = useIntl();
|
|
20
|
+
|
|
21
|
+
return createLinkUrl ? (
|
|
22
|
+
<div style={{ float: "right" }}>
|
|
23
|
+
{canManageGrantRequests ? (
|
|
24
|
+
<React.Fragment>
|
|
25
|
+
<Checkbox
|
|
26
|
+
id="execute_checkbox"
|
|
27
|
+
className="bgOrange"
|
|
28
|
+
toggle
|
|
29
|
+
checked={grantView}
|
|
30
|
+
onChange={() => onGrantViewChange(!grantView)}
|
|
31
|
+
style={{ top: "6px", marginRight: "7.5px" }}
|
|
32
|
+
/>
|
|
33
|
+
<ConceptLinkstRequestGrantButton disabled={!grantView} />
|
|
34
|
+
</React.Fragment>
|
|
35
|
+
) : null}
|
|
36
|
+
<Button
|
|
37
|
+
primary
|
|
38
|
+
as={Link}
|
|
39
|
+
to={createLinkUrl}
|
|
40
|
+
content={formatMessage({ id: "links.actions.create" })}
|
|
41
|
+
/>
|
|
42
|
+
</div>
|
|
19
43
|
) : null;
|
|
44
|
+
};
|
|
20
45
|
|
|
21
46
|
ConceptLinksActions.propTypes = {
|
|
22
|
-
|
|
47
|
+
canManageGrantRequests: PropTypes.bool,
|
|
48
|
+
createLinkUrl: PropTypes.string,
|
|
49
|
+
grantView: PropTypes.bool,
|
|
50
|
+
onGrantViewChange: PropTypes.func,
|
|
23
51
|
};
|
|
24
52
|
|
|
25
|
-
const mapStateToProps = ({
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
});
|
|
53
|
+
const mapStateToProps = ({ conceptActions, conceptActionLoading, concept }) => {
|
|
54
|
+
return {
|
|
55
|
+
createLinkUrl:
|
|
56
|
+
_.has("create_structure_link")(conceptActions) && _.has("id")(concept)
|
|
57
|
+
? linkTo.CONCEPT_LINKS_STRUCTURES_NEW(concept)
|
|
58
|
+
: null,
|
|
59
|
+
conceptActionLoading,
|
|
60
|
+
canManageGrantRequests: concept.actions?.manage_grant_requests,
|
|
61
|
+
};
|
|
62
|
+
};
|
|
36
63
|
|
|
37
64
|
export default connect(mapStateToProps)(ConceptLinksActions);
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import PropTypes from "prop-types";
|
|
4
|
+
import { useIntl } from "react-intl";
|
|
5
|
+
import { connect } from "react-redux";
|
|
6
|
+
import { Button } from "semantic-ui-react";
|
|
7
|
+
import { useSearchContext } from "@truedat/core/search/SearchContext";
|
|
8
|
+
import { addGrantRequestToCart } from "@truedat/dd/routines";
|
|
9
|
+
|
|
10
|
+
export const ConceptLinkstRequestGrantButton = ({
|
|
11
|
+
disabled,
|
|
12
|
+
addGrantRequestToCart,
|
|
13
|
+
requested,
|
|
14
|
+
}) => {
|
|
15
|
+
const { formatMessage } = useIntl();
|
|
16
|
+
const { searchData } = useSearchContext();
|
|
17
|
+
const structures = searchData?.data;
|
|
18
|
+
|
|
19
|
+
const requestAllStructures = () => {
|
|
20
|
+
_.forEach((structure) => {
|
|
21
|
+
const authorizedRequest = _.pathOr(
|
|
22
|
+
false,
|
|
23
|
+
"request_grant"
|
|
24
|
+
)(structure.user_permissions);
|
|
25
|
+
|
|
26
|
+
const isRequested = _.flow(
|
|
27
|
+
_.find({ id: `${structure.id}` }),
|
|
28
|
+
_.negate(_.isUndefined)
|
|
29
|
+
)(requested);
|
|
30
|
+
|
|
31
|
+
const granted = _.has("my_grant_request")(structure);
|
|
32
|
+
|
|
33
|
+
if (authorizedRequest && !isRequested && !granted)
|
|
34
|
+
addGrantRequestToCart({
|
|
35
|
+
...structure,
|
|
36
|
+
id: `${structure.id}`,
|
|
37
|
+
});
|
|
38
|
+
})(structures);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<Button
|
|
43
|
+
secondary
|
|
44
|
+
icon="shield"
|
|
45
|
+
title={formatMessage({ id: "links.actions.grant_request.tooltip" })}
|
|
46
|
+
disabled={disabled}
|
|
47
|
+
content={formatMessage({ id: "links.actions.grant_request" })}
|
|
48
|
+
onClick={requestAllStructures}
|
|
49
|
+
/>
|
|
50
|
+
);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
ConceptLinkstRequestGrantButton.propTypes = {
|
|
54
|
+
disabled: PropTypes.bool,
|
|
55
|
+
addGrantRequestToCart: PropTypes.func,
|
|
56
|
+
requested: PropTypes.arrayOf(PropTypes.object),
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const mapStateToProps = ({ grantRequestsCart }) => ({
|
|
60
|
+
requested: _.pathOr([], "structures")(grantRequestsCart),
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
export default connect(mapStateToProps, { addGrantRequestToCart })(
|
|
64
|
+
ConceptLinkstRequestGrantButton
|
|
65
|
+
);
|
|
@@ -2,26 +2,109 @@ import _ from "lodash/fp";
|
|
|
2
2
|
import React from "react";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
4
|
import { connect } from "react-redux";
|
|
5
|
-
import { Segment } from "semantic-ui-react";
|
|
5
|
+
import { Segment, Grid } from "semantic-ui-react";
|
|
6
|
+
import {
|
|
7
|
+
useDataStructureFilters,
|
|
8
|
+
useDataStructureSearch,
|
|
9
|
+
} from "@truedat/dd/hooks/useStructures";
|
|
10
|
+
import translations from "@truedat/dd/utils/structureCustomTranslations";
|
|
11
|
+
import StructuresSearchResults from "@truedat/dd/components/StructuresSearchResults";
|
|
12
|
+
import {
|
|
13
|
+
SearchContextProvider,
|
|
14
|
+
useSearchContext,
|
|
15
|
+
} from "@truedat/core/search/SearchContext";
|
|
6
16
|
import { getConceptLinks } from "../selectors";
|
|
17
|
+
import { useConceptContext } from "../../components/ConceptContext";
|
|
7
18
|
import ConceptLinksActions from "./ConceptLinksActions";
|
|
8
19
|
|
|
9
20
|
const LinksPane = React.lazy(() => import("@truedat/lm/components/LinksPane"));
|
|
10
21
|
|
|
11
|
-
|
|
12
|
-
const
|
|
22
|
+
const ConceptStructureLinksSegment = ({ groups, visible }) => {
|
|
23
|
+
const { conceptContext, setConceptContextProperty } = useConceptContext();
|
|
24
|
+
const { searchData, loading } = useSearchContext();
|
|
25
|
+
const structures = searchData?.data;
|
|
26
|
+
|
|
27
|
+
const { grantView } = conceptContext;
|
|
28
|
+
|
|
29
|
+
const onGrantViewChange = (grantViewNewState) =>
|
|
30
|
+
setConceptContextProperty({ grantView: grantViewNewState });
|
|
31
|
+
|
|
32
|
+
const LinksActions = visible ? (
|
|
33
|
+
<ConceptLinksActions
|
|
34
|
+
grantView={grantView}
|
|
35
|
+
onGrantViewChange={onGrantViewChange}
|
|
36
|
+
/>
|
|
37
|
+
) : null;
|
|
38
|
+
|
|
13
39
|
return (
|
|
14
40
|
<Segment attached="bottom">
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
41
|
+
{grantView ? (
|
|
42
|
+
<Grid>
|
|
43
|
+
<Grid.Row>
|
|
44
|
+
<Grid.Column>{LinksActions}</Grid.Column>
|
|
45
|
+
</Grid.Row>
|
|
46
|
+
<Grid.Row>
|
|
47
|
+
<Grid.Column>
|
|
48
|
+
<StructuresSearchResults
|
|
49
|
+
structures={structures}
|
|
50
|
+
loading={loading}
|
|
51
|
+
grantable
|
|
52
|
+
/>
|
|
53
|
+
</Grid.Column>
|
|
54
|
+
</Grid.Row>
|
|
55
|
+
</Grid>
|
|
56
|
+
) : (
|
|
57
|
+
<LinksPane
|
|
58
|
+
groups={groups}
|
|
59
|
+
sourceType="concept"
|
|
60
|
+
targetType="structure"
|
|
61
|
+
linksActions={LinksActions}
|
|
62
|
+
/>
|
|
63
|
+
)}
|
|
21
64
|
</Segment>
|
|
22
65
|
);
|
|
23
66
|
};
|
|
24
67
|
|
|
68
|
+
ConceptStructureLinksSegment.propTypes = {
|
|
69
|
+
groups: PropTypes.array,
|
|
70
|
+
visible: PropTypes.bool,
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export const ConceptStructureLinksPane = ({ groups, visible }) => {
|
|
74
|
+
const structures_ids = _.flow(
|
|
75
|
+
_.flatMap(([_columns, [_tag, links]]) => links),
|
|
76
|
+
_.map(({ resource_id }) => parseInt(resource_id))
|
|
77
|
+
)(groups);
|
|
78
|
+
|
|
79
|
+
const enrichSearchPayload = {
|
|
80
|
+
my_grant_requests: true,
|
|
81
|
+
with_data_fields: false,
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const searchProps = {
|
|
85
|
+
initialSortColumn: "name.raw",
|
|
86
|
+
initialSortDirection: "ascending",
|
|
87
|
+
useSearch: useDataStructureSearch,
|
|
88
|
+
useFilters: useDataStructureFilters,
|
|
89
|
+
pageSize: 20,
|
|
90
|
+
userFiltersType: "user_search_filters",
|
|
91
|
+
userFilterScope: "data_structure",
|
|
92
|
+
translations,
|
|
93
|
+
filtersGroup: [],
|
|
94
|
+
defaultFilters: {
|
|
95
|
+
exists: { field: "classes._grantable" },
|
|
96
|
+
ids: structures_ids,
|
|
97
|
+
},
|
|
98
|
+
enrichSearchPayload,
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
return (
|
|
102
|
+
<SearchContextProvider {...searchProps}>
|
|
103
|
+
<ConceptStructureLinksSegment groups={groups} visible={visible} />
|
|
104
|
+
</SearchContextProvider>
|
|
105
|
+
);
|
|
106
|
+
};
|
|
107
|
+
|
|
25
108
|
ConceptStructureLinksPane.propTypes = {
|
|
26
109
|
groups: PropTypes.array,
|
|
27
110
|
visible: PropTypes.bool,
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "@truedat/test/render";
|
|
3
|
+
import { useSearchContext } from "@truedat/core/search/SearchContext";
|
|
4
|
+
import ConceptLinksActions from "../ConceptLinksActions";
|
|
5
|
+
|
|
6
|
+
jest.mock("@truedat/core/search/SearchContext", () => {
|
|
7
|
+
const originalModule = jest.requireActual(
|
|
8
|
+
"@truedat/core/search/SearchContext"
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
return {
|
|
12
|
+
__esModule: true,
|
|
13
|
+
...originalModule,
|
|
14
|
+
useSearchContext: jest.fn(),
|
|
15
|
+
};
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const renderOpts = {
|
|
19
|
+
state: {
|
|
20
|
+
conceptActions: {
|
|
21
|
+
create_structure_link: true,
|
|
22
|
+
},
|
|
23
|
+
concept: {
|
|
24
|
+
id: 1,
|
|
25
|
+
business_concept_id: 11,
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
describe("<ConceptLinksActions />", () => {
|
|
31
|
+
it("matches the latest snapshot with Grant Requests permission", () => {
|
|
32
|
+
useSearchContext.mockReturnValue({ searchData: [] });
|
|
33
|
+
|
|
34
|
+
const grRenderOpts = {
|
|
35
|
+
...renderOpts,
|
|
36
|
+
state: {
|
|
37
|
+
...renderOpts.state,
|
|
38
|
+
concept: {
|
|
39
|
+
...renderOpts.state.concept,
|
|
40
|
+
actions: {
|
|
41
|
+
manage_grant_requests: {},
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const { container } = render(
|
|
48
|
+
<ConceptLinksActions onGrantViewChange={jest.fn()} />,
|
|
49
|
+
grRenderOpts
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
expect(container).toMatchSnapshot();
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("matches the latest snapshot without Grant Requests permission", () => {
|
|
56
|
+
useSearchContext.mockReturnValue({ searchData: [] });
|
|
57
|
+
|
|
58
|
+
const { container } = render(
|
|
59
|
+
<ConceptLinksActions onGrantViewChange={jest.fn()} />,
|
|
60
|
+
renderOpts
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
expect(container).toMatchSnapshot();
|
|
64
|
+
});
|
|
65
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "@truedat/test/render";
|
|
3
|
+
import { useSearchContext } from "@truedat/core/search/SearchContext";
|
|
4
|
+
import ConceptLinkstRequestGrantButton from "../ConceptLinkstRequestGrantButton";
|
|
5
|
+
|
|
6
|
+
jest.mock("@truedat/core/search/SearchContext", () => {
|
|
7
|
+
const originalModule = jest.requireActual(
|
|
8
|
+
"@truedat/core/search/SearchContext"
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
return {
|
|
12
|
+
__esModule: true,
|
|
13
|
+
...originalModule,
|
|
14
|
+
useSearchContext: jest.fn(),
|
|
15
|
+
};
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const renderOpts = {
|
|
19
|
+
state: {
|
|
20
|
+
grantRequestsCart: {
|
|
21
|
+
structures: [],
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
describe("<ConceptLinkstRequestGrantButton />", () => {
|
|
27
|
+
it("matches the latest snapshot", () => {
|
|
28
|
+
useSearchContext.mockReturnValue({ searchData: [] });
|
|
29
|
+
|
|
30
|
+
const { container } = render(
|
|
31
|
+
<ConceptLinkstRequestGrantButton onGrantViewChange={jest.fn()} />,
|
|
32
|
+
renderOpts
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
expect(container).toMatchSnapshot();
|
|
36
|
+
});
|
|
37
|
+
});
|
|
@@ -1,15 +1,91 @@
|
|
|
1
1
|
import _ from "lodash/fp";
|
|
2
|
-
import React from "react";
|
|
3
|
-
import {
|
|
2
|
+
import React, { Suspense } from "react";
|
|
3
|
+
import { render } from "@truedat/test/render";
|
|
4
|
+
import { useSearchContext } from "@truedat/core/search/SearchContext";
|
|
4
5
|
import { ConceptStructureLinksPane } from "../ConceptStructureLinks";
|
|
5
6
|
|
|
7
|
+
import { useConceptContext } from "../../../components/ConceptContext";
|
|
8
|
+
|
|
9
|
+
jest.mock("../../../components/ConceptContext", () => {
|
|
10
|
+
const originalModule = jest.requireActual(
|
|
11
|
+
"../../../components/ConceptContext"
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
return {
|
|
15
|
+
__esModule: true,
|
|
16
|
+
...originalModule,
|
|
17
|
+
useConceptContext: jest.fn(),
|
|
18
|
+
};
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
jest.mock("@truedat/core/search/SearchContext", () => {
|
|
22
|
+
const originalModule = jest.requireActual(
|
|
23
|
+
"@truedat/core/search/SearchContext"
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
__esModule: true,
|
|
28
|
+
...originalModule,
|
|
29
|
+
useSearchContext: jest.fn(),
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
beforeAll(() => {
|
|
34
|
+
jest.useFakeTimers();
|
|
35
|
+
jest.setSystemTime(new Date("2025-01-01T10:00:00Z"));
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
afterAll(() => {
|
|
39
|
+
jest.useRealTimers();
|
|
40
|
+
});
|
|
41
|
+
|
|
6
42
|
describe("<ConceptStructureLinksPane />", () => {
|
|
7
43
|
const props = {
|
|
8
|
-
groups: [[[{ name: "name" }], ["group", [{ name: "foo" }]]]]
|
|
44
|
+
groups: [[[{ name: "name" }], ["group", [{ name: "foo" }]]]],
|
|
9
45
|
};
|
|
10
46
|
|
|
11
|
-
it("matches the latest snapshot", () => {
|
|
12
|
-
|
|
13
|
-
|
|
47
|
+
it("matches the latest snapshot", async () => {
|
|
48
|
+
useConceptContext.mockReturnValue({
|
|
49
|
+
conceptContext: { grantView: false },
|
|
50
|
+
});
|
|
51
|
+
useSearchContext.mockReturnValue({
|
|
52
|
+
searchData: [],
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const { container, findByText } = render(
|
|
56
|
+
<Suspense fallback={null}>
|
|
57
|
+
<ConceptStructureLinksPane {...props} />
|
|
58
|
+
</Suspense>
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
await findByText("Links to Structures");
|
|
62
|
+
|
|
63
|
+
expect(container).toMatchSnapshot();
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it("matches the latest snapshot with grantView", async () => {
|
|
67
|
+
useConceptContext.mockReturnValue({
|
|
68
|
+
conceptContext: { grantView: true },
|
|
69
|
+
});
|
|
70
|
+
useSearchContext.mockReturnValue({
|
|
71
|
+
searchData: {
|
|
72
|
+
data: [
|
|
73
|
+
{
|
|
74
|
+
id: 1,
|
|
75
|
+
name: "test structure",
|
|
76
|
+
type: "Data Base",
|
|
77
|
+
group: "test",
|
|
78
|
+
system: { name: "System_Test" },
|
|
79
|
+
path: ["path", "to", "structure"],
|
|
80
|
+
updated_at: "2024-02-26 10:30:29.909476Z",
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
},
|
|
84
|
+
loading: false,
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
const { container } = render(<ConceptStructureLinksPane {...props} />);
|
|
88
|
+
|
|
89
|
+
expect(container).toMatchSnapshot();
|
|
14
90
|
});
|
|
15
91
|
});
|
package/src/concepts/relations/components/__tests__/__snapshots__/ConceptLinksActions.spec.js.snap
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`<ConceptLinksActions /> matches the latest snapshot with Grant Requests permission 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
style="float: right;"
|
|
7
|
+
>
|
|
8
|
+
<div
|
|
9
|
+
class="ui fitted toggle checkbox bgOrange"
|
|
10
|
+
style="top: 6px; margin-right: 7.5px;"
|
|
11
|
+
>
|
|
12
|
+
<input
|
|
13
|
+
class="hidden"
|
|
14
|
+
id="execute_checkbox"
|
|
15
|
+
readonly=""
|
|
16
|
+
tabindex="0"
|
|
17
|
+
type="checkbox"
|
|
18
|
+
value=""
|
|
19
|
+
/>
|
|
20
|
+
<label
|
|
21
|
+
for="execute_checkbox"
|
|
22
|
+
/>
|
|
23
|
+
</div>
|
|
24
|
+
<button
|
|
25
|
+
class="ui secondary disabled button"
|
|
26
|
+
disabled=""
|
|
27
|
+
tabindex="-1"
|
|
28
|
+
title="links.actions.grant_request.tooltip"
|
|
29
|
+
>
|
|
30
|
+
<i
|
|
31
|
+
aria-hidden="true"
|
|
32
|
+
class="shield icon"
|
|
33
|
+
/>
|
|
34
|
+
links.actions.grant_request
|
|
35
|
+
</button>
|
|
36
|
+
<a
|
|
37
|
+
class="ui primary button"
|
|
38
|
+
href="/concepts/11/versions/1/links/structures/new"
|
|
39
|
+
role="button"
|
|
40
|
+
>
|
|
41
|
+
Add Link
|
|
42
|
+
</a>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
`;
|
|
46
|
+
|
|
47
|
+
exports[`<ConceptLinksActions /> matches the latest snapshot without Grant Requests permission 1`] = `
|
|
48
|
+
<div>
|
|
49
|
+
<div
|
|
50
|
+
style="float: right;"
|
|
51
|
+
>
|
|
52
|
+
<a
|
|
53
|
+
class="ui primary button"
|
|
54
|
+
href="/concepts/11/versions/1/links/structures/new"
|
|
55
|
+
role="button"
|
|
56
|
+
>
|
|
57
|
+
Add Link
|
|
58
|
+
</a>
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
|
+
`;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`<ConceptLinkstRequestGrantButton /> matches the latest snapshot 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<button
|
|
6
|
+
class="ui secondary button"
|
|
7
|
+
title="links.actions.grant_request.tooltip"
|
|
8
|
+
>
|
|
9
|
+
<i
|
|
10
|
+
aria-hidden="true"
|
|
11
|
+
class="shield icon"
|
|
12
|
+
/>
|
|
13
|
+
links.actions.grant_request
|
|
14
|
+
</button>
|
|
15
|
+
</div>
|
|
16
|
+
`;
|
package/src/concepts/relations/components/__tests__/__snapshots__/ConceptStructureLinks.spec.js.snap
CHANGED
|
@@ -1,32 +1,197 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
3
|
exports[`<ConceptStructureLinksPane /> matches the latest snapshot 1`] = `
|
|
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
|
-
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
class="ui bottom attached segment"
|
|
7
|
+
style=""
|
|
8
|
+
>
|
|
9
|
+
<div
|
|
10
|
+
class="ui grid"
|
|
11
|
+
>
|
|
12
|
+
<div
|
|
13
|
+
class="row"
|
|
14
|
+
>
|
|
15
|
+
<div
|
|
16
|
+
class="column"
|
|
17
|
+
/>
|
|
18
|
+
</div>
|
|
19
|
+
<div
|
|
20
|
+
class="row"
|
|
21
|
+
>
|
|
22
|
+
<div
|
|
23
|
+
class="column"
|
|
24
|
+
>
|
|
25
|
+
<h3
|
|
26
|
+
class="ui header"
|
|
27
|
+
>
|
|
28
|
+
Links to Structures
|
|
29
|
+
</h3>
|
|
30
|
+
<table
|
|
31
|
+
class="ui table"
|
|
32
|
+
>
|
|
33
|
+
<thead
|
|
34
|
+
class=""
|
|
35
|
+
>
|
|
36
|
+
<tr
|
|
37
|
+
class=""
|
|
38
|
+
>
|
|
39
|
+
<th
|
|
40
|
+
class=""
|
|
41
|
+
>
|
|
42
|
+
Structure
|
|
43
|
+
</th>
|
|
44
|
+
</tr>
|
|
45
|
+
</thead>
|
|
46
|
+
<tbody
|
|
47
|
+
class=""
|
|
48
|
+
>
|
|
49
|
+
<tr
|
|
50
|
+
class=""
|
|
51
|
+
>
|
|
52
|
+
<td
|
|
53
|
+
class=""
|
|
54
|
+
>
|
|
55
|
+
foo
|
|
56
|
+
</td>
|
|
57
|
+
</tr>
|
|
58
|
+
</tbody>
|
|
59
|
+
</table>
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
</div>
|
|
65
|
+
`;
|
|
66
|
+
|
|
67
|
+
exports[`<ConceptStructureLinksPane /> matches the latest snapshot with grantView 1`] = `
|
|
68
|
+
<div>
|
|
69
|
+
<div
|
|
70
|
+
class="ui bottom attached segment"
|
|
71
|
+
>
|
|
72
|
+
<div
|
|
73
|
+
class="ui grid"
|
|
74
|
+
>
|
|
75
|
+
<div
|
|
76
|
+
class="row"
|
|
77
|
+
>
|
|
78
|
+
<div
|
|
79
|
+
class="column"
|
|
80
|
+
/>
|
|
81
|
+
</div>
|
|
82
|
+
<div
|
|
83
|
+
class="row"
|
|
84
|
+
>
|
|
85
|
+
<div
|
|
86
|
+
class="column"
|
|
87
|
+
>
|
|
88
|
+
<div
|
|
89
|
+
class="dimmable structure-table-overflow"
|
|
90
|
+
>
|
|
91
|
+
<div
|
|
92
|
+
class="ui label structures-label-results"
|
|
93
|
+
>
|
|
94
|
+
NaN structures found
|
|
95
|
+
</div>
|
|
96
|
+
<table
|
|
97
|
+
class="ui sortable table"
|
|
98
|
+
>
|
|
99
|
+
<thead
|
|
100
|
+
class=""
|
|
101
|
+
>
|
|
102
|
+
<tr
|
|
103
|
+
class=""
|
|
104
|
+
>
|
|
105
|
+
<th
|
|
106
|
+
class="two wide"
|
|
107
|
+
>
|
|
108
|
+
Structure
|
|
109
|
+
</th>
|
|
110
|
+
<th
|
|
111
|
+
class="one wide disabled"
|
|
112
|
+
>
|
|
113
|
+
Type
|
|
114
|
+
</th>
|
|
115
|
+
<th
|
|
116
|
+
class="one wide"
|
|
117
|
+
>
|
|
118
|
+
System
|
|
119
|
+
</th>
|
|
120
|
+
<th
|
|
121
|
+
class="one wide disabled"
|
|
122
|
+
>
|
|
123
|
+
Relation Type
|
|
124
|
+
</th>
|
|
125
|
+
<th
|
|
126
|
+
class="one wide disabled"
|
|
127
|
+
>
|
|
128
|
+
Group
|
|
129
|
+
</th>
|
|
130
|
+
<th
|
|
131
|
+
class="one wide"
|
|
132
|
+
>
|
|
133
|
+
structure.last_change_at
|
|
134
|
+
</th>
|
|
135
|
+
<th
|
|
136
|
+
class="center aligned"
|
|
137
|
+
>
|
|
138
|
+
Request grant
|
|
139
|
+
</th>
|
|
140
|
+
</tr>
|
|
141
|
+
</thead>
|
|
142
|
+
<tbody
|
|
143
|
+
class=""
|
|
144
|
+
>
|
|
145
|
+
<tr
|
|
146
|
+
class=""
|
|
147
|
+
>
|
|
148
|
+
<td
|
|
149
|
+
class="structure-cell-overflow"
|
|
150
|
+
>
|
|
151
|
+
<a
|
|
152
|
+
href="/structures/1"
|
|
153
|
+
title="test structure"
|
|
154
|
+
>
|
|
155
|
+
test structure
|
|
156
|
+
</a>
|
|
157
|
+
</td>
|
|
158
|
+
<td
|
|
159
|
+
class=""
|
|
160
|
+
>
|
|
161
|
+
Data Base
|
|
162
|
+
</td>
|
|
163
|
+
<td
|
|
164
|
+
class=""
|
|
165
|
+
>
|
|
166
|
+
System_Test
|
|
167
|
+
</td>
|
|
168
|
+
<td
|
|
169
|
+
class=""
|
|
170
|
+
/>
|
|
171
|
+
<td
|
|
172
|
+
class=""
|
|
173
|
+
>
|
|
174
|
+
test
|
|
175
|
+
</td>
|
|
176
|
+
<td
|
|
177
|
+
class=""
|
|
178
|
+
>
|
|
179
|
+
<time
|
|
180
|
+
datetime="1735725600100"
|
|
181
|
+
>
|
|
182
|
+
2025-01-01 10:00
|
|
183
|
+
</time>
|
|
184
|
+
</td>
|
|
185
|
+
<td
|
|
186
|
+
class="collapsing center aligned one wide"
|
|
187
|
+
/>
|
|
188
|
+
</tr>
|
|
189
|
+
</tbody>
|
|
190
|
+
</table>
|
|
191
|
+
</div>
|
|
192
|
+
</div>
|
|
193
|
+
</div>
|
|
194
|
+
</div>
|
|
195
|
+
</div>
|
|
196
|
+
</div>
|
|
32
197
|
`;
|