strapi-plugin-navigation 1.1.3 → 2.0.0-beta.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 (149) hide show
  1. package/README.md +61 -87
  2. package/admin/src/components/EmptyView/index.js +7 -16
  3. package/admin/src/components/Item/ItemCardBadge/index.js +8 -0
  4. package/admin/src/components/Item/ItemCardHeader/Wrapper.js +21 -0
  5. package/admin/src/components/Item/ItemCardHeader/index.js +59 -0
  6. package/admin/src/components/Item/Wrapper.js +39 -0
  7. package/admin/src/components/Item/index.js +78 -124
  8. package/admin/src/components/NavigationItemList/Wrapper.js +22 -0
  9. package/admin/src/components/NavigationItemList/index.js +56 -0
  10. package/admin/src/components/PluginIcon/index.js +6 -0
  11. package/admin/src/components/Search/index.js +46 -83
  12. package/admin/src/index.js +49 -45
  13. package/admin/src/pages/App/index.js +31 -0
  14. package/admin/src/{containers → pages}/DataManagerProvider/actions.js +0 -0
  15. package/admin/src/{containers → pages}/DataManagerProvider/index.js +77 -84
  16. package/admin/src/{containers → pages}/DataManagerProvider/init.js +0 -0
  17. package/admin/src/pages/DataManagerProvider/reducer.js +125 -0
  18. package/admin/src/pages/View/components/NavigationContentHeader/index.js +18 -0
  19. package/admin/src/pages/View/components/NavigationHeader/index.js +60 -0
  20. package/admin/src/pages/View/components/NavigationItemForm/index.js +403 -0
  21. package/admin/src/{containers → pages}/View/components/NavigationItemForm/utils/form.js +2 -2
  22. package/admin/src/pages/View/components/NavigationItemPopup/NavigationItemPopupFooter.js +40 -0
  23. package/admin/src/pages/View/components/NavigationItemPopup/NavigationItemPopupHeader.js +20 -0
  24. package/admin/src/{containers → pages}/View/components/NavigationItemPopup/index.js +16 -16
  25. package/admin/src/pages/View/index.js +221 -0
  26. package/admin/src/{containers → pages}/View/utils/enums.js +0 -0
  27. package/admin/src/{containers → pages}/View/utils/form.js +1 -1
  28. package/admin/src/{containers → pages}/View/utils/index.js +0 -0
  29. package/admin/src/{containers → pages}/View/utils/parsers.js +13 -12
  30. package/admin/src/pluginId.js +3 -2
  31. package/admin/src/translations/en.json +47 -38
  32. package/admin/src/translations/fr.json +7 -1
  33. package/admin/src/utils/getTrad.js +2 -2
  34. package/package.json +18 -7
  35. package/server/bootstrap.js +41 -0
  36. package/server/config/index.js +8 -0
  37. package/server/config.js +8 -0
  38. package/server/content-types/audience/index.js +9 -0
  39. package/{models/audience.js → server/content-types/audience/lifecycle.js} +0 -0
  40. package/{models/audience.settings.json → server/content-types/audience/schema.json} +4 -2
  41. package/server/content-types/index.js +13 -0
  42. package/server/content-types/navigation/index.js +9 -0
  43. package/{models/navigation.js → server/content-types/navigation/lifecycle.js} +0 -0
  44. package/server/content-types/navigation/schema.js +45 -0
  45. package/server/content-types/navigation-item/index.js +9 -0
  46. package/{models/navigationItem.js → server/content-types/navigation-item/lifecycle.js} +0 -0
  47. package/{models/navigationItem.settings.json → server/content-types/navigation-item/schema.json} +16 -12
  48. package/server/content-types/navigations-items-related/index.js +9 -0
  49. package/{models/navigations_items_related.js → server/content-types/navigations-items-related/lifecycle.js} +0 -0
  50. package/{models/navigations_items_related.settings.json → server/content-types/navigations-items-related/schema.json} +4 -2
  51. package/server/controllers/index.js +7 -0
  52. package/{controllers → server/controllers}/navigation.js +20 -31
  53. package/server/graphql/index.js +23 -0
  54. package/server/graphql/queries/index.js +17 -0
  55. package/server/graphql/queries/render-navigation-child.js +16 -0
  56. package/server/graphql/queries/render-navigation.js +15 -0
  57. package/server/graphql/resolvers-config.js +4 -0
  58. package/server/graphql/types/content-types-name-fields.js +8 -0
  59. package/server/graphql/types/content-types.js +16 -0
  60. package/server/graphql/types/create-navigation-item.js +17 -0
  61. package/server/graphql/types/create-navigation-related.js +8 -0
  62. package/server/graphql/types/create-navigation.js +7 -0
  63. package/server/graphql/types/index.js +15 -0
  64. package/server/graphql/types/navigation-config.js +9 -0
  65. package/server/graphql/types/navigation-details.js +10 -0
  66. package/server/graphql/types/navigation-item.js +29 -0
  67. package/server/graphql/types/navigation-related.js +23 -0
  68. package/server/graphql/types/navigation-render-type.js +4 -0
  69. package/server/graphql/types/navigation.js +9 -0
  70. package/server/register.js +5 -0
  71. package/server/routes/admin.js +38 -0
  72. package/server/routes/client.js +21 -0
  73. package/server/routes/index.js +4 -0
  74. package/{services → server/services}/__tests__/navigation.test.js +0 -0
  75. package/server/services/index.js +7 -0
  76. package/server/services/navigation.js +729 -0
  77. package/{services → server/services}/utils/constant.js +3 -1
  78. package/server/services/utils/functions.js +185 -0
  79. package/strapi-admin.js +1 -0
  80. package/strapi-server.js +20 -0
  81. package/__mocks__/helpers/another-plugin/blog-post.settings.json +0 -31
  82. package/__mocks__/helpers/another-plugin/pages.settings.json +0 -28
  83. package/__mocks__/helpers/blog-post.settings.json +0 -31
  84. package/__mocks__/helpers/home-page.settings.json +0 -4
  85. package/__mocks__/helpers/my-homepage.settings.json +0 -27
  86. package/__mocks__/helpers/pages.settings.json +0 -27
  87. package/__mocks__/helpers/strapi.js +0 -101
  88. package/admin/src/assets/images/icon-cross-blue.svg +0 -1
  89. package/admin/src/assets/images/icon_remove.svg +0 -19
  90. package/admin/src/components/Container/index.js +0 -7
  91. package/admin/src/components/Input/index.js +0 -41
  92. package/admin/src/components/Item/CardItem.js +0 -46
  93. package/admin/src/components/Item/CardItemLevelAdd.js +0 -41
  94. package/admin/src/components/Item/CardItemLevelWrapper.js +0 -27
  95. package/admin/src/components/Item/CardItemPath.js +0 -9
  96. package/admin/src/components/Item/CardItemRestore.js +0 -19
  97. package/admin/src/components/Item/CardItemTitle.js +0 -5
  98. package/admin/src/components/Item/CardWrapper.js +0 -78
  99. package/admin/src/components/ItemFooter/CardItemError.js +0 -11
  100. package/admin/src/components/ItemFooter/CardItemRelation.js +0 -18
  101. package/admin/src/components/ItemFooter/CardItemRelationStatus.js +0 -17
  102. package/admin/src/components/ItemFooter/CardItemType.js +0 -18
  103. package/admin/src/components/ItemFooter/Wrapper.js +0 -26
  104. package/admin/src/components/ItemFooter/index.js +0 -66
  105. package/admin/src/components/ItemOrdering/CardOrderingButton.js +0 -24
  106. package/admin/src/components/ItemOrdering/Wrapper.js +0 -24
  107. package/admin/src/components/ItemOrdering/index.js +0 -36
  108. package/admin/src/components/List/Container.js +0 -34
  109. package/admin/src/components/List/ListLevelRoot.js +0 -18
  110. package/admin/src/components/List/index.js +0 -81
  111. package/admin/src/components/Option/OptionButton.js +0 -18
  112. package/admin/src/components/Option/OptionSet.js +0 -14
  113. package/admin/src/components/Option/Wrapper.js +0 -15
  114. package/admin/src/components/Option/index.js +0 -47
  115. package/admin/src/components/Select/ClearIndicator.js +0 -15
  116. package/admin/src/components/Select/DropdownIndicator.js +0 -39
  117. package/admin/src/components/Select/ErrorMessage.js +0 -10
  118. package/admin/src/components/Select/IndicatorSeparator.js +0 -3
  119. package/admin/src/components/Select/MultiValueContainer.js +0 -43
  120. package/admin/src/components/Select/StyledOption.js +0 -11
  121. package/admin/src/components/Select/index.js +0 -68
  122. package/admin/src/components/Select/utils/styles.js +0 -92
  123. package/admin/src/containers/App/Wrapper.js +0 -14
  124. package/admin/src/containers/App/index.js +0 -34
  125. package/admin/src/containers/DataManagerProvider/reducer.js +0 -136
  126. package/admin/src/containers/DetailsView/Wrapper.js +0 -21
  127. package/admin/src/containers/DetailsView/index.js +0 -111
  128. package/admin/src/containers/Initializer/index.js +0 -26
  129. package/admin/src/containers/ListView/Footer.js +0 -56
  130. package/admin/src/containers/ListView/components.js +0 -138
  131. package/admin/src/containers/ListView/index.js +0 -54
  132. package/admin/src/containers/View/FadedWrapper.js +0 -51
  133. package/admin/src/containers/View/HeaderForm.js +0 -9
  134. package/admin/src/containers/View/HeaderFormCell.js +0 -25
  135. package/admin/src/containers/View/Wrapper.js +0 -17
  136. package/admin/src/containers/View/components/NavigationItemForm/ModalFooter.js +0 -45
  137. package/admin/src/containers/View/components/NavigationItemForm/index.js +0 -427
  138. package/admin/src/containers/View/components/NavigationItemPopup/MediumPopup.js +0 -6
  139. package/admin/src/containers/View/index.js +0 -240
  140. package/admin/src/lifecycles.js +0 -3
  141. package/admin/src/permissions.js +0 -14
  142. package/config/functions/bootstrap.js +0 -138
  143. package/config/routes.json +0 -60
  144. package/config/schema.graphql.js +0 -209
  145. package/examples/audit-log-integrations.js.md +0 -38
  146. package/models/navigation.settings.json +0 -43
  147. package/public/assets/preview.png +0 -0
  148. package/services/navigation.js +0 -732
  149. package/services/utils/functions.js +0 -186
@@ -1,43 +1,37 @@
1
- import React from 'react';
2
- import { useIntl } from 'react-intl';
3
1
  import PropTypes from 'prop-types';
4
- import { isEmpty, isNil, isNumber } from 'lodash';
5
- import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
6
- import { faPlus } from '@fortawesome/free-solid-svg-icons';
7
- import { Button } from '@buffetjs/core';
8
- import CardWrapper from './CardWrapper';
9
- import CardItem from './CardItem';
10
- import ItemFooter from '../ItemFooter';
11
- import { navigationItemType } from '../../containers/View/utils/enums';
12
- import CardItemPath from './CardItemPath';
13
- import CardItemTitle from './CardItemTitle';
14
- import CardItemLevelAdd from './CardItemLevelAdd';
15
- import List from '../List';
16
- import CardItemLevelWrapper from './CardItemLevelWrapper';
17
- import CardItemRestore from './CardItemRestore';
18
- import ItemOrdering from '../ItemOrdering';
2
+ import React from 'react';
3
+ import { isEmpty, isNumber } from 'lodash';
4
+ import { useIntl } from "react-intl";
5
+
6
+ import { Card, CardBody } from '@strapi/design-system/Card';
7
+ import { Divider } from '@strapi/design-system/Divider';
8
+ import { TextButton } from '@strapi/design-system/TextButton';
9
+ import { Typography } from '@strapi/design-system/Typography';
10
+ import PlusIcon from '@strapi/icons/Plus';
11
+ import EarthIcon from '@strapi/icons/Earth';
12
+ import LinkIcon from '@strapi/icons/Link';
13
+
14
+ import { navigationItemType } from '../../pages/View/utils/enums';
15
+ import ItemCardHeader from './ItemCardHeader';
16
+ import List from '../NavigationItemList';
17
+ import Wrapper from './Wrapper';
19
18
  import { getTrad } from '../../translations';
20
- import { extractRelatedItemLabel } from '../../containers/View/utils/parsers';
21
19
 
22
20
  const Item = (props) => {
23
- const { formatMessage } = useIntl();
24
-
25
21
  const {
26
22
  item,
23
+ isLast = false,
27
24
  level = 0,
28
25
  levelPath = '',
29
26
  allowedLevels,
30
- contentTypesNameFields,
31
- contentTypes,
32
27
  relatedRef,
33
- isFirst = false,
34
- isLast = false,
35
28
  isParentAttachedToMenu,
36
- onItemClick,
37
- onItemReOrder,
38
- onItemRestoreClick,
39
- onItemLevelAddClick,
29
+ onItemLevelAdd,
30
+ onItemRemove,
31
+ onItemRestore,
32
+ onItemEdit,
40
33
  error,
34
+ displayChildren,
41
35
  } = props;
42
36
 
43
37
  const {
@@ -45,108 +39,72 @@ const Item = (props) => {
45
39
  title,
46
40
  type,
47
41
  path,
48
- relatedType,
49
42
  removed,
50
43
  externalPath,
51
44
  menuAttached,
52
45
  } = item;
53
46
 
54
- const isRelationDefined = !isNil(relatedRef);
55
-
56
- const formatRelationName = () =>
57
- isRelationDefined ? extractRelatedItemLabel(relatedRef, contentTypesNameFields) : '';
58
-
59
- const footerProps = {
60
- contentTypes,
61
- type: type || navigationItemType.INTERNAL,
62
- removed,
63
- menuAttached,
64
- relatedRef,
65
- relatedType,
66
- attachButtons: !(isFirst && isLast),
67
- formatRelationName,
68
- };
69
-
70
- const cardTitle = isRelationDefined && !title ? formatRelationName() : title;
47
+ const { formatMessage } = useIntl();
48
+ const isExternal = type === navigationItemType.EXTERNAL;
49
+ const isPublished = relatedRef && relatedRef?.publishedAt;
71
50
  const isNextMenuAllowedLevel = isNumber(allowedLevels) ? level < (allowedLevels - 1) : true;
72
51
  const isMenuAllowedLevel = isNumber(allowedLevels) ? level < allowedLevels : true;
73
- const isExternal = item.type === navigationItemType.EXTERNAL;
52
+ const hasChildren = !isEmpty(item.items) && !isExternal && !displayChildren;
74
53
  const absolutePath = isExternal ? undefined : `${levelPath === '/' ? '' : levelPath}/${path === '/' ? '' : path}`;
75
- const hasChildren = !isEmpty(item.items) && !isExternal;
76
-
77
- const handleReOrder = (e, moveBy = 0) => onItemReOrder(e, {
78
- ...item,
79
- relatedRef,
80
- }, moveBy);
81
-
82
- const hasError = error?.parentId === item.parent && error?.errorTitles.includes(cardTitle);
83
54
 
84
55
  return (
85
- <CardWrapper
86
- level={level}
87
- error={hasError}
88
- >
89
- <CardItem
90
- hasChildren={hasChildren}
91
- removed={removed}
92
- hasError={hasError}
93
- onClick={(e) =>
94
- removed ? null : onItemClick(e, {
95
- ...item,
96
- isMenuAllowedLevel,
97
- isParentAttachedToMenu,
98
- }, levelPath)
99
- }
100
- >
101
- {removed && (<CardItemRestore>
102
- <Button
103
- onClick={e => onItemRestoreClick(e, item)}
104
- color="secondary"
105
- label={formatMessage(getTrad('popup.item.form.button.restore'))}
56
+ <Wrapper level={level} isLast={isLast}>
57
+ <Card style={{ width: "728px", zIndex: 1, position: "relative" }}>
58
+ <CardBody>
59
+ <ItemCardHeader
60
+ title={title}
61
+ path={isExternal ? externalPath : absolutePath}
62
+ icon={isExternal ? <EarthIcon /> : <LinkIcon />}
63
+ isPublished={isPublished}
64
+ isExternal={isExternal}
65
+ onItemRemove={() => onItemRemove(item)}
66
+ onItemEdit={() => onItemEdit({
67
+ ...item,
68
+ isMenuAllowedLevel,
69
+ isParentAttachedToMenu,
70
+ }, levelPath, isParentAttachedToMenu)}
71
+ onItemRestore={() => onItemRestore(item)}
72
+ removed={removed}
106
73
  />
107
- </CardItemRestore>)}
108
- <CardItemTitle>{cardTitle}</CardItemTitle>
109
- <CardItemPath>
110
- {isExternal ? externalPath : absolutePath}
111
- </CardItemPath>
112
- <ItemFooter {...footerProps} />
113
- <ItemOrdering
114
- isFirst={isFirst}
115
- isLast={isLast}
116
- onChangeOrder={handleReOrder}
117
- />
118
- </CardItem>
119
- {!(isExternal || removed) && (
120
- <CardItemLevelAdd
121
- color={isNextMenuAllowedLevel ? 'primary' : 'secondary'}
122
- icon={<FontAwesomeIcon icon={faPlus} size="3x" />}
123
- onClick={(e) => onItemLevelAddClick(e, viewId, isNextMenuAllowedLevel, levelPath, menuAttached)}
124
- menuLevel={isNextMenuAllowedLevel}
125
- />
126
- )}
127
- {hasChildren && !removed && (
128
- <List
129
- items={item.items}
130
- onItemClick={onItemClick}
131
- onItemReOrder={onItemReOrder}
132
- onItemRestoreClick={onItemRestoreClick}
133
- onItemLevelAddClick={onItemLevelAddClick}
134
- as={CardItemLevelWrapper}
135
- level={level + 1}
136
- levelPath={absolutePath}
137
- allowedLevels={allowedLevels}
138
- isParentAttachedToMenu={menuAttached}
139
- contentTypesNameFields={contentTypesNameFields}
140
- contentTypes={contentTypes}
141
- error={error}
142
- />
143
- )}
144
- </CardWrapper>
74
+ </CardBody>
75
+ <Divider />
76
+ <CardBody style={{ margin: '8px' }}>
77
+ <TextButton
78
+ disabled={removed}
79
+ startIcon={<PlusIcon />}
80
+ onClick={(e) => onItemLevelAdd(e, viewId, isNextMenuAllowedLevel, absolutePath, menuAttached)}
81
+ >
82
+ <Typography variant="pi" fontWeight="bold" textColor={removed ? "neutral600" : "primary600"}>
83
+ {formatMessage(getTrad("navigation.item.action.newItem"))}
84
+ </Typography>
85
+ </TextButton>
86
+ </CardBody>
87
+ </Card>
88
+ {hasChildren && !removed && <List
89
+ onItemLevelAdd={onItemLevelAdd}
90
+ onItemRemove={onItemRemove}
91
+ onItemEdit={onItemEdit}
92
+ onItemRestore={onItemRestore}
93
+ error={error}
94
+ allowedLevels={allowedLevels}
95
+ isParentAttachedToMenu={true}
96
+ items={item.items}
97
+ level={level + 1}
98
+ levelPath={absolutePath}
99
+ />
100
+ }
101
+ </Wrapper>
102
+
145
103
  );
146
104
  };
147
105
 
148
106
  Item.propTypes = {
149
- item: PropTypes.objectOf({
107
+ item: PropTypes.shape({
150
108
  title: PropTypes.string,
151
109
  type: PropTypes.string,
152
110
  uiRouterKey: PropTypes.string,
@@ -154,19 +112,15 @@ Item.propTypes = {
154
112
  externalPath: PropTypes.string,
155
113
  audience: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number])),
156
114
  related: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
157
- menuAttached: PropTypes.bool,
115
+ menuAttached: PropTypes.bool
158
116
  }).isRequired,
159
117
  relatedRef: PropTypes.object,
160
- contentTypes: PropTypes.array,
161
- contentTypesNameFields: PropTypes.object.isRequired,
162
118
  level: PropTypes.number,
163
119
  levelPath: PropTypes.string,
164
- isFirst: PropTypes.bool,
165
- isLast: PropTypes.bool,
166
120
  isParentAttachedToMenu: PropTypes.bool,
167
- onItemClick: PropTypes.func.isRequired,
168
- onItemRestoreClick: PropTypes.func.isRequired,
169
- onItemLevelAddClick: PropTypes.func.isRequired,
121
+ onItemRestore: PropTypes.func.isRequired,
122
+ onItemLevelAdd: PropTypes.func.isRequired,
123
+ onItemRemove: PropTypes.func.isRequired,
170
124
  };
171
125
 
172
- export default Item;
126
+ export default Item;
@@ -0,0 +1,22 @@
1
+ import styled from 'styled-components';
2
+
3
+ const Wrapper = styled.div`
4
+ position: relative;
5
+ ${({ level, theme }) => level && `
6
+ &::before {
7
+ content: "";
8
+ display: block;
9
+ height: ${theme.spaces[3]};
10
+ width: 19px;
11
+
12
+ position: absolute;
13
+ top: -${theme.spaces[2]};
14
+ left: ${theme.spaces[4]};
15
+
16
+ border: 0px solid transparent;
17
+ border-left: 4px solid ${theme.colors.neutral300};
18
+ }
19
+ `};
20
+ `;
21
+
22
+ export default Wrapper;
@@ -0,0 +1,56 @@
1
+ import React from 'react';
2
+ import PropTypes from "prop-types";
3
+
4
+ import Item from "../Item";
5
+ import Wrapper from "./Wrapper";
6
+
7
+ const List = ({
8
+ allowedLevels,
9
+ error,
10
+ isParentAttachedToMenu = false,
11
+ items,
12
+ level = 0,
13
+ levelPath = '',
14
+ onItemEdit,
15
+ onItemLevelAdd,
16
+ onItemRemove,
17
+ onItemRestore,
18
+ displayFlat,
19
+ }) => (
20
+ <Wrapper level={level}>
21
+ {items.map((item, n) => {
22
+ const { relatedRef, ...itemProps } = item
23
+ return (
24
+ <Item
25
+ key={`list-item-${item.viewId || n}`}
26
+ item={itemProps}
27
+ isLast={n === items.length - 1}
28
+ relatedRef={relatedRef}
29
+ level={level}
30
+ levelPath={levelPath}
31
+ isParentAttachedToMenu={isParentAttachedToMenu}
32
+ allowedLevels={allowedLevels}
33
+ onItemRestore={onItemRestore}
34
+ onItemLevelAdd={onItemLevelAdd}
35
+ onItemRemove={onItemRemove}
36
+ onItemEdit={onItemEdit}
37
+ error={error}
38
+ displayChildren={displayFlat}
39
+ />
40
+ );
41
+ })}
42
+ </Wrapper>
43
+ );
44
+
45
+ List.propTypes = {
46
+ allowedLevels: PropTypes.number,
47
+ isParentAttachedToMenu: PropTypes.bool,
48
+ items: PropTypes.array,
49
+ level: PropTypes.number,
50
+ onItemLevelAdd: PropTypes.func.isRequired,
51
+ onItemRemove: PropTypes.func.isRequired,
52
+ onItemRestore: PropTypes.func.isRequired,
53
+ onItemRestore: PropTypes.func.isRequired,
54
+ };
55
+
56
+ export default List;
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import Puzzle from '@strapi/icons/Puzzle';
3
+
4
+ const PluginIcon = () => <Puzzle />;
5
+
6
+ export default PluginIcon;
@@ -1,86 +1,49 @@
1
- /*
2
- *
3
- * Search
4
- *
5
- */
6
-
7
- import React, { memo } from "react";
8
- import { isEmpty, upperFirst } from "lodash";
9
- import PropTypes from "prop-types";
10
- import { FormattedMessage } from "react-intl";
11
- import { HeaderSearch } from "strapi-helper-plugin";
12
- import getTrad from "../../utils/getTrad";
13
-
14
- const WAIT = 400;
15
-
16
- class Search extends React.Component {
17
- state = { value: this.props.initValue };
18
-
19
- timer = null;
20
-
21
- componentDidUpdate(prevProps) {
22
- const { model, value } = this.props;
23
-
24
- if (
25
- prevProps.model !== model ||
26
- (!isEmpty(prevProps.value) && isEmpty(value))
27
- ) {
28
- this.resetState();
1
+ import React, { useRef, useState, useEffect } from 'react';
2
+ import { useIntl } from 'react-intl';
3
+ import { IconButton } from '@strapi/design-system/IconButton';
4
+ import { Searchbar, SearchForm } from '@strapi/design-system/Searchbar';
5
+ import SearchIcon from "@strapi/icons/Search";
6
+ import { getTradId } from '../../translations';
7
+
8
+ const Search = ({ value, setValue }) => {
9
+ const [isOpen, setIsOpen] = useState(!!value);
10
+ const wrapperRef = useRef(null);
11
+ const { formatMessage } = useIntl();
12
+
13
+ useEffect(() => {
14
+ if (isOpen) {
15
+ setTimeout(() => {
16
+ wrapperRef.current.querySelector('input').focus();
17
+ }, 0);
29
18
  }
30
- }
31
-
32
- resetState = () => this.setState({ value: "" });
33
-
34
- handleChange = ({ target }) => {
35
- clearTimeout(this.timer);
36
- this.setState({ value: target.value });
37
- this.timer = setTimeout(() => this.triggerChange(target.value), WAIT);
38
- };
39
-
40
- handleClick = () => {
41
- this.setState({ value: "" });
42
- this.triggerChange("");
43
- };
44
-
45
- triggerChange = (value) =>
46
- this.props.changeParams({
47
- target: {
48
- name: "_q",
49
- value,
50
- },
51
- });
52
-
53
- render() {
54
- const { model } = this.props;
55
- const { value } = this.state;
56
-
57
- return (
58
- <FormattedMessage id={getTrad("components.Search.placeholder")}>
59
- {(placeholder) => (
60
- <HeaderSearch
61
- label={upperFirst(model)}
62
- onChange={this.handleChange}
63
- onClear={this.handleClick}
64
- placeholder={placeholder}
65
- value={value}
66
- />
67
- )}
68
- </FormattedMessage>
69
- );
70
- }
19
+ }, [isOpen]);
20
+
21
+ if (isOpen) {
22
+ return (
23
+ <div ref={wrapperRef}>
24
+ <SearchForm>
25
+ <Searchbar
26
+ name="searchbar"
27
+ onClear={() => setValue('')}
28
+ value={value}
29
+ size="S"
30
+ onChange={(e) => setValue(e.target.value)}
31
+ clearLabel="Clearing the search"
32
+ placeholder={formatMessage({
33
+ id: getTradId('popup.item.form.audience.placeholder'),
34
+ defaultMessage: 'Type to start searching...',
35
+ })}
36
+ >
37
+ Search for navigation items
38
+ </Searchbar>
39
+ </SearchForm>
40
+ </div>
41
+ );
42
+ } else {
43
+ return (
44
+ <IconButton icon={<SearchIcon />} onClick={() => setIsOpen(!isOpen)} />
45
+ );
46
+ }
71
47
  }
72
48
 
73
- Search.defaultProps = {
74
- changeParams: () => {},
75
- model: "",
76
- value: "",
77
- };
78
-
79
- Search.propTypes = {
80
- changeParams: PropTypes.func,
81
- initValue: PropTypes.string.isRequired,
82
- model: PropTypes.string,
83
- value: PropTypes.string,
84
- };
85
-
86
- export default memo(Search);
49
+ export default Search;
@@ -1,49 +1,53 @@
1
- import pluginPkg from "../../package.json";
2
- import pluginId from "./pluginId";
3
- import App from "./containers/App";
4
- import Initializer from "./containers/Initializer";
5
- import lifecycles from "./lifecycles";
6
- import trads from "./translations";
7
- import pluginPermissions from "./permissions";
1
+ import { prefixPluginTranslations } from '@strapi/helper-plugin';
2
+ import PluginIcon from './components/PluginIcon';
3
+ import pluginPkg from '../../package.json';
4
+ import pluginId from './pluginId';
8
5
 
9
- export default (strapi) => {
10
- const pluginDescription =
11
- pluginPkg.strapi.description || pluginPkg.description;
12
- const { icon, name } = pluginPkg.strapi;
6
+ const name = pluginPkg.strapi.name;
13
7
 
14
- const plugin = {
15
- blockerComponent: null,
16
- blockerComponentProps: {},
17
- description: pluginDescription,
18
- icon,
19
- id: pluginId,
20
- initializer: Initializer,
21
- injectedComponents: [],
22
- isReady: false,
23
- isRequired: pluginPkg.strapi.required || false,
24
- layout: null,
25
- lifecycles,
26
- leftMenuLinks: [],
27
- leftMenuSections: [],
28
- mainComponent: App,
29
- name,
30
- preventComponentRendering: false,
31
- trads,
32
- menu: {
33
- pluginsSectionLinks: [
34
- {
35
- destination: `/plugins/${pluginId}`,
36
- icon,
37
- name,
38
- label: {
39
- id: `${pluginId}.plugin.name`,
40
- defaultMessage: "NAVIGATION",
41
- },
42
- permissions: pluginPermissions.main,
43
- },
44
- ],
45
- },
46
- };
8
+ export default {
9
+ register(app) {
10
+ app.addMenuLink({
11
+ to: `/plugins/${pluginId}`,
12
+ icon: PluginIcon,
13
+ intlLabel: {
14
+ id: `${pluginId}.plugin.name`,
15
+ defaultMessage: 'Navigation',
16
+ },
17
+ Component: async () => {
18
+ const component = await import(/* webpackChunkName: "my-plugin" */ './pages/App');
47
19
 
48
- return strapi.registerPlugin(plugin);
20
+ return component;
21
+ },
22
+ permissions: [],
23
+ });
24
+ app.registerPlugin({
25
+ id: pluginId,
26
+ name,
27
+ });
28
+ },
29
+ bootstrap() {},
30
+ async registerTrads({ locales }) {
31
+ const importedTrads = await Promise.all(
32
+ locales.map(locale => {
33
+ return import(
34
+ /* webpackChunkName: "[pluginId]-[request]" */ `./translations/${locale}.json`
35
+ )
36
+ .then(({ default: data }) => {
37
+ return {
38
+ data: prefixPluginTranslations(data, pluginId),
39
+ locale,
40
+ };
41
+ })
42
+ .catch(() => {
43
+ return {
44
+ data: {},
45
+ locale,
46
+ };
47
+ });
48
+ })
49
+ );
50
+
51
+ return Promise.resolve(importedTrads);
52
+ },
49
53
  };
@@ -0,0 +1,31 @@
1
+ /**
2
+ *
3
+ * This component is the skeleton around the actual pages, and should only
4
+ * contain code that should be seen on all pages. (e.g. navigation bar)
5
+ *
6
+ */
7
+
8
+ import React, { Suspense, lazy } from "react";
9
+ import { Switch, Route } from "react-router-dom";
10
+ import { NotFound, LoadingIndicatorPage } from "@strapi/helper-plugin";
11
+ // Utils
12
+ import DataManagerProvider from "../DataManagerProvider";
13
+ import pluginId from "../../pluginId";
14
+ // Containers
15
+ const View = lazy(() => import("../View"));
16
+
17
+ const App = () => {
18
+ return (
19
+ <DataManagerProvider>
20
+ <Suspense fallback={<LoadingIndicatorPage />}>
21
+ <Switch>
22
+ <Route path={`/plugins/${pluginId}`} component={View} exact />
23
+ <Route component={NotFound} />
24
+ </Switch>
25
+ </Suspense>
26
+ </DataManagerProvider>
27
+ );
28
+ };
29
+
30
+ export default App;
31
+