@wordpress/dataviews 4.1.0 → 4.3.0

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 (223) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +77 -29
  3. package/build/components/dataviews/index.js +10 -14
  4. package/build/components/dataviews/index.js.map +1 -1
  5. package/build/components/dataviews-bulk-actions/index.js +145 -141
  6. package/build/components/dataviews-bulk-actions/index.js.map +1 -1
  7. package/build/components/dataviews-filters/add-filter.js +4 -6
  8. package/build/components/dataviews-filters/add-filter.js.map +1 -1
  9. package/build/components/dataviews-filters/index.js +3 -0
  10. package/build/components/dataviews-filters/index.js.map +1 -1
  11. package/build/components/dataviews-filters/search-widget.js +30 -23
  12. package/build/components/dataviews-filters/search-widget.js.map +1 -1
  13. package/build/components/dataviews-footer/index.js +45 -0
  14. package/build/components/dataviews-footer/index.js.map +1 -0
  15. package/build/components/dataviews-item-actions/index.js +5 -8
  16. package/build/components/dataviews-item-actions/index.js.map +1 -1
  17. package/build/components/dataviews-pagination/index.js +27 -19
  18. package/build/components/dataviews-pagination/index.js.map +1 -1
  19. package/build/components/dataviews-view-config/index.js +197 -41
  20. package/build/components/dataviews-view-config/index.js.map +1 -1
  21. package/build/dataform-controls/datetime.js +49 -0
  22. package/build/dataform-controls/datetime.js.map +1 -0
  23. package/build/dataform-controls/index.js +50 -0
  24. package/build/dataform-controls/index.js.map +1 -0
  25. package/build/dataform-controls/integer.js +45 -0
  26. package/build/dataform-controls/integer.js.map +1 -0
  27. package/build/dataform-controls/radio.js +45 -0
  28. package/build/dataform-controls/radio.js.map +1 -0
  29. package/build/dataform-controls/select.js +58 -0
  30. package/build/dataform-controls/select.js.map +1 -0
  31. package/build/dataform-controls/text.js +45 -0
  32. package/build/dataform-controls/text.js.map +1 -0
  33. package/build/dataforms-layouts/panel/index.js +10 -4
  34. package/build/dataforms-layouts/panel/index.js.map +1 -1
  35. package/build/dataforms-layouts/regular/index.js +6 -3
  36. package/build/dataforms-layouts/regular/index.js.map +1 -1
  37. package/build/dataviews-layouts/grid/density-picker.js +23 -52
  38. package/build/dataviews-layouts/grid/density-picker.js.map +1 -1
  39. package/build/dataviews-layouts/grid/index.js +1 -1
  40. package/build/dataviews-layouts/grid/index.js.map +1 -1
  41. package/build/dataviews-layouts/index.js +48 -2
  42. package/build/dataviews-layouts/index.js.map +1 -1
  43. package/build/dataviews-layouts/list/index.js +124 -80
  44. package/build/dataviews-layouts/list/index.js.map +1 -1
  45. package/build/dataviews-layouts/table/column-header-menu.js +52 -57
  46. package/build/dataviews-layouts/table/column-header-menu.js.map +1 -1
  47. package/build/dataviews-layouts/table/index.js +7 -35
  48. package/build/dataviews-layouts/table/index.js.map +1 -1
  49. package/build/field-types/datetime.js +30 -0
  50. package/build/field-types/datetime.js.map +1 -0
  51. package/build/field-types/index.js +4 -0
  52. package/build/field-types/index.js.map +1 -1
  53. package/build/field-types/integer.js +1 -60
  54. package/build/field-types/integer.js.map +1 -1
  55. package/build/field-types/text.js +1 -60
  56. package/build/field-types/text.js.map +1 -1
  57. package/build/normalize-fields.js +10 -9
  58. package/build/normalize-fields.js.map +1 -1
  59. package/build/types.js.map +1 -1
  60. package/build-module/components/dataviews/index.js +10 -14
  61. package/build-module/components/dataviews/index.js.map +1 -1
  62. package/build-module/components/dataviews-bulk-actions/index.js +145 -143
  63. package/build-module/components/dataviews-bulk-actions/index.js.map +1 -1
  64. package/build-module/components/dataviews-filters/add-filter.js +4 -6
  65. package/build-module/components/dataviews-filters/add-filter.js.map +1 -1
  66. package/build-module/components/dataviews-filters/index.js +3 -0
  67. package/build-module/components/dataviews-filters/index.js.map +1 -1
  68. package/build-module/components/dataviews-filters/search-widget.js +30 -23
  69. package/build-module/components/dataviews-filters/search-widget.js.map +1 -1
  70. package/build-module/components/dataviews-footer/index.js +38 -0
  71. package/build-module/components/dataviews-footer/index.js.map +1 -0
  72. package/build-module/components/dataviews-item-actions/index.js +5 -8
  73. package/build-module/components/dataviews-item-actions/index.js.map +1 -1
  74. package/build-module/components/dataviews-pagination/index.js +28 -20
  75. package/build-module/components/dataviews-pagination/index.js.map +1 -1
  76. package/build-module/components/dataviews-view-config/index.js +203 -47
  77. package/build-module/components/dataviews-view-config/index.js.map +1 -1
  78. package/build-module/dataform-controls/datetime.js +43 -0
  79. package/build-module/dataform-controls/datetime.js.map +1 -0
  80. package/build-module/dataform-controls/index.js +42 -0
  81. package/build-module/dataform-controls/index.js.map +1 -0
  82. package/build-module/dataform-controls/integer.js +38 -0
  83. package/build-module/dataform-controls/integer.js.map +1 -0
  84. package/build-module/dataform-controls/radio.js +38 -0
  85. package/build-module/dataform-controls/radio.js.map +1 -0
  86. package/build-module/dataform-controls/select.js +51 -0
  87. package/build-module/dataform-controls/select.js.map +1 -0
  88. package/build-module/dataform-controls/text.js +38 -0
  89. package/build-module/dataform-controls/text.js.map +1 -0
  90. package/build-module/dataforms-layouts/panel/index.js +10 -4
  91. package/build-module/dataforms-layouts/panel/index.js.map +1 -1
  92. package/build-module/dataforms-layouts/regular/index.js +6 -3
  93. package/build-module/dataforms-layouts/regular/index.js.map +1 -1
  94. package/build-module/dataviews-layouts/grid/density-picker.js +25 -56
  95. package/build-module/dataviews-layouts/grid/density-picker.js.map +1 -1
  96. package/build-module/dataviews-layouts/grid/index.js +1 -1
  97. package/build-module/dataviews-layouts/grid/index.js.map +1 -1
  98. package/build-module/dataviews-layouts/index.js +45 -1
  99. package/build-module/dataviews-layouts/index.js.map +1 -1
  100. package/build-module/dataviews-layouts/list/index.js +125 -80
  101. package/build-module/dataviews-layouts/list/index.js.map +1 -1
  102. package/build-module/dataviews-layouts/table/column-header-menu.js +52 -57
  103. package/build-module/dataviews-layouts/table/column-header-menu.js.map +1 -1
  104. package/build-module/dataviews-layouts/table/index.js +9 -37
  105. package/build-module/dataviews-layouts/table/index.js.map +1 -1
  106. package/build-module/field-types/datetime.js +24 -0
  107. package/build-module/field-types/datetime.js.map +1 -0
  108. package/build-module/field-types/index.js +4 -0
  109. package/build-module/field-types/index.js.map +1 -1
  110. package/build-module/field-types/integer.js +2 -60
  111. package/build-module/field-types/integer.js.map +1 -1
  112. package/build-module/field-types/text.js +2 -60
  113. package/build-module/field-types/text.js.map +1 -1
  114. package/build-module/normalize-fields.js +11 -9
  115. package/build-module/normalize-fields.js.map +1 -1
  116. package/build-module/types.js.map +1 -1
  117. package/build-style/style-rtl.css +93 -80
  118. package/build-style/style.css +93 -80
  119. package/build-types/components/dataform/stories/index.story.d.ts.map +1 -1
  120. package/build-types/components/dataviews/index.d.ts.map +1 -1
  121. package/build-types/components/dataviews/stories/fixtures.d.ts +28 -113
  122. package/build-types/components/dataviews/stories/fixtures.d.ts.map +1 -1
  123. package/build-types/components/dataviews/stories/index.story.d.ts +12 -44
  124. package/build-types/components/dataviews/stories/index.story.d.ts.map +1 -1
  125. package/build-types/components/dataviews-bulk-actions/index.d.ts +11 -1
  126. package/build-types/components/dataviews-bulk-actions/index.d.ts.map +1 -1
  127. package/build-types/components/dataviews-filters/add-filter.d.ts.map +1 -1
  128. package/build-types/components/dataviews-filters/index.d.ts +1 -1
  129. package/build-types/components/dataviews-filters/index.d.ts.map +1 -1
  130. package/build-types/components/dataviews-filters/search-widget.d.ts.map +1 -1
  131. package/build-types/components/dataviews-footer/index.d.ts +2 -0
  132. package/build-types/components/dataviews-footer/index.d.ts.map +1 -0
  133. package/build-types/components/dataviews-item-actions/index.d.ts.map +1 -1
  134. package/build-types/components/dataviews-pagination/index.d.ts.map +1 -1
  135. package/build-types/components/dataviews-view-config/index.d.ts +4 -3
  136. package/build-types/components/dataviews-view-config/index.d.ts.map +1 -1
  137. package/build-types/dataform-controls/datetime.d.ts +6 -0
  138. package/build-types/dataform-controls/datetime.d.ts.map +1 -0
  139. package/build-types/dataform-controls/index.d.ts +11 -0
  140. package/build-types/dataform-controls/index.d.ts.map +1 -0
  141. package/build-types/dataform-controls/integer.d.ts +6 -0
  142. package/build-types/dataform-controls/integer.d.ts.map +1 -0
  143. package/build-types/dataform-controls/radio.d.ts +6 -0
  144. package/build-types/dataform-controls/radio.d.ts.map +1 -0
  145. package/build-types/dataform-controls/select.d.ts +6 -0
  146. package/build-types/dataform-controls/select.d.ts.map +1 -0
  147. package/build-types/dataform-controls/text.d.ts +6 -0
  148. package/build-types/dataform-controls/text.d.ts.map +1 -0
  149. package/build-types/dataforms-layouts/panel/index.d.ts.map +1 -1
  150. package/build-types/dataforms-layouts/regular/index.d.ts.map +1 -1
  151. package/build-types/dataviews-layouts/grid/density-picker.d.ts.map +1 -1
  152. package/build-types/dataviews-layouts/index.d.ts +4 -2
  153. package/build-types/dataviews-layouts/index.d.ts.map +1 -1
  154. package/build-types/dataviews-layouts/list/index.d.ts.map +1 -1
  155. package/build-types/dataviews-layouts/table/column-header-menu.d.ts.map +1 -1
  156. package/build-types/dataviews-layouts/table/index.d.ts.map +1 -1
  157. package/build-types/field-types/datetime.d.ts +13 -0
  158. package/build-types/field-types/datetime.d.ts.map +1 -0
  159. package/build-types/field-types/index.d.ts +1 -1
  160. package/build-types/field-types/index.d.ts.map +1 -1
  161. package/build-types/field-types/integer.d.ts +2 -3
  162. package/build-types/field-types/integer.d.ts.map +1 -1
  163. package/build-types/field-types/text.d.ts +2 -3
  164. package/build-types/field-types/text.d.ts.map +1 -1
  165. package/build-types/normalize-fields.d.ts.map +1 -1
  166. package/build-types/types.d.ts +43 -21
  167. package/build-types/types.d.ts.map +1 -1
  168. package/package.json +12 -12
  169. package/src/components/dataform/stories/index.story.tsx +43 -2
  170. package/src/components/dataviews/index.tsx +14 -18
  171. package/src/components/dataviews/stories/fixtures.tsx +690 -0
  172. package/src/components/dataviews/stories/index.story.tsx +164 -0
  173. package/src/components/dataviews/style.scss +2 -12
  174. package/src/components/dataviews-bulk-actions/index.tsx +264 -213
  175. package/src/components/dataviews-bulk-actions/style.scss +9 -4
  176. package/src/components/dataviews-filters/add-filter.tsx +7 -11
  177. package/src/components/dataviews-filters/index.tsx +3 -0
  178. package/src/components/dataviews-filters/search-widget.tsx +46 -25
  179. package/src/components/dataviews-filters/style.scss +13 -3
  180. package/src/components/dataviews-footer/index.tsx +50 -0
  181. package/src/components/dataviews-footer/style.scss +40 -0
  182. package/src/components/dataviews-item-actions/index.tsx +8 -14
  183. package/src/components/dataviews-pagination/index.tsx +40 -21
  184. package/src/components/dataviews-pagination/style.scss +7 -21
  185. package/src/components/dataviews-view-config/index.tsx +297 -69
  186. package/src/components/dataviews-view-config/style.scss +25 -0
  187. package/src/dataform-controls/datetime.tsx +43 -0
  188. package/src/dataform-controls/index.tsx +61 -0
  189. package/src/dataform-controls/integer.tsx +38 -0
  190. package/src/dataform-controls/radio.tsx +42 -0
  191. package/src/dataform-controls/select.tsx +52 -0
  192. package/src/dataform-controls/style.scss +4 -0
  193. package/src/dataform-controls/text.tsx +40 -0
  194. package/src/dataforms-layouts/panel/index.tsx +8 -2
  195. package/src/dataforms-layouts/regular/index.tsx +6 -2
  196. package/src/dataviews-layouts/grid/density-picker.tsx +33 -67
  197. package/src/dataviews-layouts/grid/index.tsx +1 -1
  198. package/src/dataviews-layouts/grid/style.scss +1 -5
  199. package/src/dataviews-layouts/index.ts +63 -2
  200. package/src/dataviews-layouts/list/index.tsx +199 -123
  201. package/src/dataviews-layouts/list/style.scss +10 -4
  202. package/src/dataviews-layouts/table/column-header-menu.tsx +86 -90
  203. package/src/dataviews-layouts/table/index.tsx +8 -65
  204. package/src/dataviews-layouts/table/style.scss +0 -5
  205. package/src/field-types/datetime.tsx +28 -0
  206. package/src/field-types/index.tsx +5 -0
  207. package/src/field-types/integer.tsx +2 -71
  208. package/src/field-types/text.tsx +2 -70
  209. package/src/normalize-fields.ts +10 -10
  210. package/src/style.scss +2 -1
  211. package/src/test/filter-and-sort-data-view.js +28 -0
  212. package/src/types.ts +56 -32
  213. package/tsconfig.tsbuildinfo +1 -1
  214. package/build/components/dataviews-bulk-actions-toolbar/index.js +0 -207
  215. package/build/components/dataviews-bulk-actions-toolbar/index.js.map +0 -1
  216. package/build-module/components/dataviews-bulk-actions-toolbar/index.js +0 -201
  217. package/build-module/components/dataviews-bulk-actions-toolbar/index.js.map +0 -1
  218. package/build-types/components/dataviews-bulk-actions-toolbar/index.d.ts +0 -2
  219. package/build-types/components/dataviews-bulk-actions-toolbar/index.d.ts.map +0 -1
  220. package/src/components/dataviews/stories/fixtures.js +0 -222
  221. package/src/components/dataviews/stories/index.story.js +0 -65
  222. package/src/components/dataviews-bulk-actions-toolbar/index.tsx +0 -288
  223. package/src/components/dataviews-bulk-actions-toolbar/style.scss +0 -45
@@ -25,16 +25,11 @@ import type {
25
25
  NormalizedField,
26
26
  SortDirection,
27
27
  ViewTable as ViewTableType,
28
+ Operator,
28
29
  } from '../../types';
30
+ import { getVisibleFieldIds } from '../index';
29
31
 
30
- const {
31
- DropdownMenuV2: DropdownMenu,
32
- DropdownMenuGroupV2: DropdownMenuGroup,
33
- DropdownMenuItemV2: DropdownMenuItem,
34
- DropdownMenuRadioItemV2: DropdownMenuRadioItem,
35
- DropdownMenuItemLabelV2: DropdownMenuItemLabel,
36
- DropdownMenuSeparatorV2: DropdownMenuSeparator,
37
- } = unlock( componentsPrivateApis );
32
+ const { DropdownMenuV2 } = unlock( componentsPrivateApis );
38
33
 
39
34
  interface HeaderMenuProps< Item > {
40
35
  fieldId: string;
@@ -50,7 +45,7 @@ function WithDropDownMenuSeparators( { children }: { children: ReactNode } ) {
50
45
  .filter( Boolean )
51
46
  .map( ( child, i ) => (
52
47
  <Fragment key={ i }>
53
- { i > 0 && <DropdownMenuSeparator /> }
48
+ { i > 0 && <DropdownMenuV2.Separator /> }
54
49
  { child }
55
50
  </Fragment>
56
51
  ) );
@@ -67,35 +62,46 @@ const _HeaderMenu = forwardRef( function HeaderMenu< Item >(
67
62
  }: HeaderMenuProps< Item >,
68
63
  ref: Ref< HTMLButtonElement >
69
64
  ) {
65
+ const visibleFieldIds = getVisibleFieldIds( view, fields );
66
+ const index = visibleFieldIds?.indexOf( fieldId ) as number;
67
+ const isSorted = view.sort?.field === fieldId;
68
+ let isHidable = false;
69
+ let isSortable = false;
70
+ let canAddFilter = false;
71
+ let header;
72
+ let operators: Operator[] = [];
73
+
70
74
  const combinedField = view.layout?.combinedFields?.find(
71
75
  ( f ) => f.id === fieldId
72
76
  );
73
- const index = view.fields?.indexOf( fieldId ) as number;
74
- if ( !! combinedField ) {
75
- return combinedField.label;
76
- }
77
77
  const field = fields.find( ( f ) => f.id === fieldId );
78
- if ( ! field ) {
79
- return null;
80
- }
81
- const isHidable = field.enableHiding !== false;
82
- const isSortable = field.enableSorting !== false;
83
- const isSorted = view.sort?.field === field.id;
84
- const operators = sanitizeOperators( field );
85
- // Filter can be added:
86
- // 1. If the field is not already part of a view's filters.
87
- // 2. If the field meets the type and operator requirements.
88
- // 3. If it's not primary. If it is, it should be already visible.
89
- const canAddFilter =
90
- ! view.filters?.some( ( _filter ) => field.id === _filter.field ) &&
91
- !! field.elements?.length &&
92
- !! operators.length &&
93
- ! field.filterBy?.isPrimary;
94
- if ( ! isSortable && ! isHidable && ! canAddFilter ) {
95
- return field.label;
78
+
79
+ if ( ! combinedField ) {
80
+ if ( ! field ) {
81
+ // No combined or regular field found.
82
+ return null;
83
+ }
84
+
85
+ isHidable = field.enableHiding !== false;
86
+ isSortable = field.enableSorting !== false;
87
+ header = field.header;
88
+
89
+ operators = sanitizeOperators( field );
90
+ // Filter can be added:
91
+ // 1. If the field is not already part of a view's filters.
92
+ // 2. If the field meets the type and operator requirements.
93
+ // 3. If it's not primary. If it is, it should be already visible.
94
+ canAddFilter =
95
+ ! view.filters?.some( ( _filter ) => fieldId === _filter.field ) &&
96
+ !! field.elements?.length &&
97
+ !! operators.length &&
98
+ ! field.filterBy?.isPrimary;
99
+ } else {
100
+ header = combinedField.header || combinedField.label;
96
101
  }
102
+
97
103
  return (
98
- <DropdownMenu
104
+ <DropdownMenuV2
99
105
  align="start"
100
106
  trigger={
101
107
  <Button
@@ -104,7 +110,7 @@ const _HeaderMenu = forwardRef( function HeaderMenu< Item >(
104
110
  ref={ ref }
105
111
  variant="tertiary"
106
112
  >
107
- { field.label }
113
+ { header }
108
114
  { view.sort && isSorted && (
109
115
  <span aria-hidden="true">
110
116
  { sortArrows[ view.sort.direction ] }
@@ -116,7 +122,7 @@ const _HeaderMenu = forwardRef( function HeaderMenu< Item >(
116
122
  >
117
123
  <WithDropDownMenuSeparators>
118
124
  { isSortable && (
119
- <DropdownMenuGroup>
125
+ <DropdownMenuV2.Group>
120
126
  { SORTING_DIRECTIONS.map(
121
127
  ( direction: SortDirection ) => {
122
128
  const isChecked =
@@ -124,10 +130,10 @@ const _HeaderMenu = forwardRef( function HeaderMenu< Item >(
124
130
  isSorted &&
125
131
  view.sort.direction === direction;
126
132
 
127
- const value = `${ field.id }-${ direction }`;
133
+ const value = `${ fieldId }-${ direction }`;
128
134
 
129
135
  return (
130
- <DropdownMenuRadioItem
136
+ <DropdownMenuV2.RadioItem
131
137
  key={ value }
132
138
  // All sorting radio items share the same name, so that
133
139
  // selecting a sorting option automatically deselects the
@@ -141,34 +147,34 @@ const _HeaderMenu = forwardRef( function HeaderMenu< Item >(
141
147
  onChangeView( {
142
148
  ...view,
143
149
  sort: {
144
- field: field.id,
150
+ field: fieldId,
145
151
  direction,
146
152
  },
147
153
  } );
148
154
  } }
149
155
  >
150
- <DropdownMenuItemLabel>
156
+ <DropdownMenuV2.ItemLabel>
151
157
  { sortLabels[ direction ] }
152
- </DropdownMenuItemLabel>
153
- </DropdownMenuRadioItem>
158
+ </DropdownMenuV2.ItemLabel>
159
+ </DropdownMenuV2.RadioItem>
154
160
  );
155
161
  }
156
162
  ) }
157
- </DropdownMenuGroup>
163
+ </DropdownMenuV2.Group>
158
164
  ) }
159
165
  { canAddFilter && (
160
- <DropdownMenuGroup>
161
- <DropdownMenuItem
166
+ <DropdownMenuV2.Group>
167
+ <DropdownMenuV2.Item
162
168
  prefix={ <Icon icon={ funnel } /> }
163
169
  onClick={ () => {
164
- setOpenedFilter( field.id );
170
+ setOpenedFilter( fieldId );
165
171
  onChangeView( {
166
172
  ...view,
167
173
  page: 1,
168
174
  filters: [
169
175
  ...( view.filters || [] ),
170
176
  {
171
- field: field.id,
177
+ field: fieldId,
172
178
  value: undefined,
173
179
  operator: operators[ 0 ],
174
180
  },
@@ -176,86 +182,76 @@ const _HeaderMenu = forwardRef( function HeaderMenu< Item >(
176
182
  } );
177
183
  } }
178
184
  >
179
- <DropdownMenuItemLabel>
185
+ <DropdownMenuV2.ItemLabel>
180
186
  { __( 'Add filter' ) }
181
- </DropdownMenuItemLabel>
182
- </DropdownMenuItem>
183
- </DropdownMenuGroup>
187
+ </DropdownMenuV2.ItemLabel>
188
+ </DropdownMenuV2.Item>
189
+ </DropdownMenuV2.Group>
184
190
  ) }
185
- <DropdownMenuGroup>
186
- <DropdownMenuItem
191
+ <DropdownMenuV2.Group>
192
+ <DropdownMenuV2.Item
187
193
  prefix={ <Icon icon={ arrowLeft } /> }
188
194
  disabled={ index < 1 }
189
195
  onClick={ () => {
190
- if ( ! view.fields || index < 1 ) {
191
- return;
192
- }
193
196
  onChangeView( {
194
197
  ...view,
195
198
  fields: [
196
- ...( view.fields.slice( 0, index - 1 ) ??
197
- [] ),
198
- field.id,
199
- view.fields[ index - 1 ],
200
- ...view.fields.slice( index + 1 ),
199
+ ...( visibleFieldIds.slice(
200
+ 0,
201
+ index - 1
202
+ ) ?? [] ),
203
+ fieldId,
204
+ visibleFieldIds[ index - 1 ],
205
+ ...visibleFieldIds.slice( index + 1 ),
201
206
  ],
202
207
  } );
203
208
  } }
204
209
  >
205
- <DropdownMenuItemLabel>
210
+ <DropdownMenuV2.ItemLabel>
206
211
  { __( 'Move left' ) }
207
- </DropdownMenuItemLabel>
208
- </DropdownMenuItem>
209
- <DropdownMenuItem
212
+ </DropdownMenuV2.ItemLabel>
213
+ </DropdownMenuV2.Item>
214
+ <DropdownMenuV2.Item
210
215
  prefix={ <Icon icon={ arrowRight } /> }
211
- disabled={
212
- ! view.fields || index >= view.fields.length - 1
213
- }
216
+ disabled={ index >= visibleFieldIds.length - 1 }
214
217
  onClick={ () => {
215
- if (
216
- ! view.fields ||
217
- index >= view.fields.length - 1
218
- ) {
219
- return;
220
- }
221
218
  onChangeView( {
222
219
  ...view,
223
220
  fields: [
224
- ...( view.fields.slice( 0, index ) ?? [] ),
225
- view.fields[ index + 1 ],
226
- field.id,
227
- ...view.fields.slice( index + 2 ),
221
+ ...( visibleFieldIds.slice( 0, index ) ??
222
+ [] ),
223
+ visibleFieldIds[ index + 1 ],
224
+ fieldId,
225
+ ...visibleFieldIds.slice( index + 2 ),
228
226
  ],
229
227
  } );
230
228
  } }
231
229
  >
232
- <DropdownMenuItemLabel>
230
+ <DropdownMenuV2.ItemLabel>
233
231
  { __( 'Move right' ) }
234
- </DropdownMenuItemLabel>
235
- </DropdownMenuItem>
236
- { isHidable && (
237
- <DropdownMenuItem
232
+ </DropdownMenuV2.ItemLabel>
233
+ </DropdownMenuV2.Item>
234
+ { isHidable && field && (
235
+ <DropdownMenuV2.Item
238
236
  prefix={ <Icon icon={ unseen } /> }
239
237
  onClick={ () => {
240
- const viewFields =
241
- view.fields || fields.map( ( f ) => f.id );
242
238
  onHide( field );
243
239
  onChangeView( {
244
240
  ...view,
245
- fields: viewFields.filter(
246
- ( id ) => id !== field.id
241
+ fields: visibleFieldIds.filter(
242
+ ( id ) => id !== fieldId
247
243
  ),
248
244
  } );
249
245
  } }
250
246
  >
251
- <DropdownMenuItemLabel>
247
+ <DropdownMenuV2.ItemLabel>
252
248
  { __( 'Hide column' ) }
253
- </DropdownMenuItemLabel>
254
- </DropdownMenuItem>
249
+ </DropdownMenuV2.ItemLabel>
250
+ </DropdownMenuV2.Item>
255
251
  ) }
256
- </DropdownMenuGroup>
252
+ </DropdownMenuV2.Group>
257
253
  </WithDropDownMenuSeparators>
258
- </DropdownMenu>
254
+ </DropdownMenuV2>
259
255
  );
260
256
  } );
261
257
 
@@ -8,18 +8,11 @@ import clsx from 'clsx';
8
8
  */
9
9
  import { __ } from '@wordpress/i18n';
10
10
  import {
11
- CheckboxControl,
12
11
  Spinner,
13
12
  __experimentalHStack as HStack,
14
13
  __experimentalVStack as VStack,
15
14
  } from '@wordpress/components';
16
- import {
17
- useEffect,
18
- useId,
19
- useRef,
20
- useState,
21
- useMemo,
22
- } from '@wordpress/element';
15
+ import { useEffect, useId, useRef, useState } from '@wordpress/element';
23
16
 
24
17
  /**
25
18
  * Internal dependencies
@@ -30,6 +23,7 @@ import { sortValues } from '../../constants';
30
23
  import {
31
24
  useSomeItemHasAPossibleBulkAction,
32
25
  useHasAPossibleBulkAction,
26
+ BulkSelectionCheckbox,
33
27
  } from '../../components/dataviews-bulk-actions';
34
28
  import type {
35
29
  Action,
@@ -40,14 +34,7 @@ import type {
40
34
  } from '../../types';
41
35
  import type { SetSelection } from '../../private-types';
42
36
  import ColumnHeaderMenu from './column-header-menu';
43
-
44
- interface BulkSelectionCheckboxProps< Item > {
45
- selection: string[];
46
- onChangeSelection: SetSelection;
47
- data: Item[];
48
- actions: Action< Item >[];
49
- getItemId: ( item: Item ) => string;
50
- }
37
+ import { getVisibleFieldIds } from '../index';
51
38
 
52
39
  interface TableColumnFieldProps< Item > {
53
40
  primaryField?: NormalizedField< Item >;
@@ -84,50 +71,6 @@ interface TableRowProps< Item > {
84
71
  onChangeSelection: SetSelection;
85
72
  }
86
73
 
87
- function BulkSelectionCheckbox< Item >( {
88
- selection,
89
- onChangeSelection,
90
- data,
91
- actions,
92
- getItemId,
93
- }: BulkSelectionCheckboxProps< Item > ) {
94
- const selectableItems = useMemo( () => {
95
- return data.filter( ( item ) => {
96
- return actions.some(
97
- ( action ) =>
98
- action.supportsBulk &&
99
- ( ! action.isEligible || action.isEligible( item ) )
100
- );
101
- } );
102
- }, [ data, actions ] );
103
- const selectedItems = data.filter(
104
- ( item ) =>
105
- selection.includes( getItemId( item ) ) &&
106
- selectableItems.includes( item )
107
- );
108
- const areAllSelected = selectedItems.length === selectableItems.length;
109
- return (
110
- <CheckboxControl
111
- className="dataviews-view-table-selection-checkbox"
112
- __nextHasNoMarginBottom
113
- checked={ areAllSelected }
114
- indeterminate={ ! areAllSelected && !! selectedItems.length }
115
- onChange={ () => {
116
- if ( areAllSelected ) {
117
- onChangeSelection( [] );
118
- } else {
119
- onChangeSelection(
120
- selectableItems.map( ( item ) => getItemId( item ) )
121
- );
122
- }
123
- } }
124
- aria-label={
125
- areAllSelected ? __( 'Deselect all' ) : __( 'Select all' )
126
- }
127
- />
128
- );
129
- }
130
-
131
74
  function TableColumn< Item >( {
132
75
  column,
133
76
  fields,
@@ -212,8 +155,8 @@ function TableRow< Item >( {
212
155
  // Will be set to true if `onTouchStart` fires. This happens before
213
156
  // `onClick` and can be used to exclude touchscreen devices from certain
214
157
  // behaviours.
215
- const isTouchDevice = useRef( false );
216
- const columns = view.fields || fields.map( ( f ) => f.id );
158
+ const isTouchDeviceRef = useRef( false );
159
+ const columns = getVisibleFieldIds( view, fields );
217
160
 
218
161
  return (
219
162
  <tr
@@ -225,14 +168,14 @@ function TableRow< Item >( {
225
168
  onMouseEnter={ handleMouseEnter }
226
169
  onMouseLeave={ handleMouseLeave }
227
170
  onTouchStart={ () => {
228
- isTouchDevice.current = true;
171
+ isTouchDeviceRef.current = true;
229
172
  } }
230
173
  onClick={ () => {
231
174
  if ( ! hasPossibleBulkAction ) {
232
175
  return;
233
176
  }
234
177
  if (
235
- ! isTouchDevice.current &&
178
+ ! isTouchDeviceRef.current &&
236
179
  document.getSelection()?.type !== 'Range'
237
180
  ) {
238
181
  onChangeSelection(
@@ -346,7 +289,7 @@ function ViewTable< Item >( {
346
289
  setNextHeaderMenuToFocus( fallback?.node );
347
290
  };
348
291
 
349
- const columns = view.fields || fields.map( ( f ) => f.id );
292
+ const columns = getVisibleFieldIds( view, fields );
350
293
  const hasData = !! data?.length;
351
294
 
352
295
  const primaryField = fields.find(
@@ -7,11 +7,6 @@
7
7
  color: $gray-700;
8
8
  margin-bottom: auto;
9
9
 
10
- a {
11
- text-decoration: none;
12
- color: $gray-900;
13
- font-weight: 500;
14
- }
15
10
  th {
16
11
  text-align: left;
17
12
  color: $gray-900;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import type { SortDirection, ValidationContext } from '../types';
5
+
6
+ function sort( a: any, b: any, direction: SortDirection ) {
7
+ const timeA = new Date( a ).getTime();
8
+ const timeB = new Date( b ).getTime();
9
+
10
+ return direction === 'asc' ? timeA - timeB : timeB - timeA;
11
+ }
12
+
13
+ function isValid( value: any, context?: ValidationContext ) {
14
+ if ( context?.elements ) {
15
+ const validValues = context?.elements.map( ( f ) => f.value );
16
+ if ( ! validValues.includes( value ) ) {
17
+ return false;
18
+ }
19
+ }
20
+
21
+ return true;
22
+ }
23
+
24
+ export default {
25
+ sort,
26
+ isValid,
27
+ Edit: 'datetime',
28
+ };
@@ -4,6 +4,7 @@
4
4
  import type { FieldType, SortDirection, ValidationContext } from '../types';
5
5
  import { default as integer } from './integer';
6
6
  import { default as text } from './text';
7
+ import { default as datetime } from './datetime';
7
8
 
8
9
  /**
9
10
  *
@@ -20,6 +21,10 @@ export default function getFieldTypeDefinition( type?: FieldType ) {
20
21
  return text;
21
22
  }
22
23
 
24
+ if ( 'datetime' === type ) {
25
+ return datetime;
26
+ }
27
+
23
28
  return {
24
29
  sort: ( a: any, b: any, direction: SortDirection ) => {
25
30
  if ( typeof a === 'number' && typeof b === 'number' ) {
@@ -1,21 +1,7 @@
1
- /**
2
- * WordPress dependencies
3
- */
4
- import {
5
- __experimentalNumberControl as NumberControl,
6
- SelectControl,
7
- } from '@wordpress/components';
8
- import { useCallback } from '@wordpress/element';
9
- import { __ } from '@wordpress/i18n';
10
-
11
1
  /**
12
2
  * Internal dependencies
13
3
  */
14
- import type {
15
- SortDirection,
16
- ValidationContext,
17
- DataFormControlProps,
18
- } from '../types';
4
+ import type { SortDirection, ValidationContext } from '../types';
19
5
 
20
6
  function sort( a: any, b: any, direction: SortDirection ) {
21
7
  return direction === 'asc' ? a - b : b - a;
@@ -41,63 +27,8 @@ function isValid( value: any, context?: ValidationContext ) {
41
27
  return true;
42
28
  }
43
29
 
44
- function Edit< Item >( {
45
- data,
46
- field,
47
- onChange,
48
- hideLabelFromVision,
49
- }: DataFormControlProps< Item > ) {
50
- const { id, label, description } = field;
51
- const value = field.getValue( { item: data } ) ?? '';
52
- const onChangeControl = useCallback(
53
- ( newValue: string | undefined ) =>
54
- onChange( ( prevItem: Item ) => ( {
55
- ...prevItem,
56
- [ id ]: newValue,
57
- } ) ),
58
- [ id, onChange ]
59
- );
60
-
61
- if ( field.elements ) {
62
- const elements = [
63
- /*
64
- * Value can be undefined when:
65
- *
66
- * - the field is not required
67
- * - in bulk editing
68
- *
69
- */
70
- { label: __( 'Select item' ), value: '' },
71
- ...field.elements,
72
- ];
73
-
74
- return (
75
- <SelectControl
76
- label={ label }
77
- value={ value }
78
- options={ elements }
79
- onChange={ onChangeControl }
80
- __next40pxDefaultSize
81
- __nextHasNoMarginBottom
82
- hideLabelFromVision={ hideLabelFromVision }
83
- />
84
- );
85
- }
86
-
87
- return (
88
- <NumberControl
89
- label={ label }
90
- help={ description }
91
- value={ value }
92
- onChange={ onChangeControl }
93
- __next40pxDefaultSize
94
- hideLabelFromVision={ hideLabelFromVision }
95
- />
96
- );
97
- }
98
-
99
30
  export default {
100
31
  sort,
101
32
  isValid,
102
- Edit,
33
+ Edit: 'integer',
103
34
  };
@@ -1,18 +1,7 @@
1
- /**
2
- * WordPress dependencies
3
- */
4
- import { SelectControl, TextControl } from '@wordpress/components';
5
- import { useCallback } from '@wordpress/element';
6
- import { __ } from '@wordpress/i18n';
7
-
8
1
  /**
9
2
  * Internal dependencies
10
3
  */
11
- import type {
12
- SortDirection,
13
- ValidationContext,
14
- DataFormControlProps,
15
- } from '../types';
4
+ import type { SortDirection, ValidationContext } from '../types';
16
5
 
17
6
  function sort( valueA: any, valueB: any, direction: SortDirection ) {
18
7
  return direction === 'asc'
@@ -31,65 +20,8 @@ function isValid( value: any, context?: ValidationContext ) {
31
20
  return true;
32
21
  }
33
22
 
34
- function Edit< Item >( {
35
- data,
36
- field,
37
- onChange,
38
- hideLabelFromVision,
39
- }: DataFormControlProps< Item > ) {
40
- const { id, label, placeholder } = field;
41
- const value = field.getValue( { item: data } );
42
-
43
- const onChangeControl = useCallback(
44
- ( newValue: string ) =>
45
- onChange( ( prevItem: Item ) => ( {
46
- ...prevItem,
47
- [ id ]: newValue,
48
- } ) ),
49
- [ id, onChange ]
50
- );
51
-
52
- if ( field.elements ) {
53
- const elements = [
54
- /*
55
- * Value can be undefined when:
56
- *
57
- * - the field is not required
58
- * - in bulk editing
59
- *
60
- */
61
- { label: __( 'Select item' ), value: '' },
62
- ...field.elements,
63
- ];
64
-
65
- return (
66
- <SelectControl
67
- label={ label }
68
- value={ value }
69
- options={ elements }
70
- onChange={ onChangeControl }
71
- __next40pxDefaultSize
72
- __nextHasNoMarginBottom
73
- hideLabelFromVision={ hideLabelFromVision }
74
- />
75
- );
76
- }
77
-
78
- return (
79
- <TextControl
80
- label={ label }
81
- placeholder={ placeholder }
82
- value={ value ?? '' }
83
- onChange={ onChangeControl }
84
- __next40pxDefaultSize
85
- __nextHasNoMarginBottom
86
- hideLabelFromVision={ hideLabelFromVision }
87
- />
88
- );
89
- }
90
-
91
23
  export default {
92
24
  sort,
93
25
  isValid,
94
- Edit,
26
+ Edit: 'text',
95
27
  };