From c89225cce75a4944510a9d3e597e9741dbbfc38e Mon Sep 17 00:00:00 2001 From: matusmlichsk <61700762+matusmlichsk@users.noreply.github.com> Date: Wed, 7 Aug 2024 13:48:27 +0200 Subject: [PATCH] #2475 Command palette with better actions ux flow for query editor (#2517) --- .../components/ContentViews/QueryView.tsx | 323 ------------------ .../ContentViews/QueryView/QueryView.tsx | 122 +++++++ .../components/QueryOptions/QueryOptions.tsx | 228 +++++++++++++ .../TemplatePicker/TemplatePicker.tsx | 96 ++++++ .../QueryOptions/TemplatePicker/index.ts | 1 + .../components/QueryOptions/index.ts | 1 + .../ContentViews/QueryView/index.ts | 1 + .../components/QueryEditor.tsx | 92 +++-- .../components/StyledComponents/Chip/Chip.tsx | 3 +- Src/WitsmlExplorer.Frontend/styles/Icons.tsx | 9 +- 10 files changed, 518 insertions(+), 358 deletions(-) delete mode 100644 Src/WitsmlExplorer.Frontend/components/ContentViews/QueryView.tsx create mode 100644 Src/WitsmlExplorer.Frontend/components/ContentViews/QueryView/QueryView.tsx create mode 100644 Src/WitsmlExplorer.Frontend/components/ContentViews/QueryView/components/QueryOptions/QueryOptions.tsx create mode 100644 Src/WitsmlExplorer.Frontend/components/ContentViews/QueryView/components/QueryOptions/TemplatePicker/TemplatePicker.tsx create mode 100644 Src/WitsmlExplorer.Frontend/components/ContentViews/QueryView/components/QueryOptions/TemplatePicker/index.ts create mode 100644 Src/WitsmlExplorer.Frontend/components/ContentViews/QueryView/components/QueryOptions/index.ts create mode 100644 Src/WitsmlExplorer.Frontend/components/ContentViews/QueryView/index.ts diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/QueryView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/QueryView.tsx deleted file mode 100644 index e8cb01615..000000000 --- a/Src/WitsmlExplorer.Frontend/components/ContentViews/QueryView.tsx +++ /dev/null @@ -1,323 +0,0 @@ -import { Menu, Tabs, TextField } from "@equinor/eds-core-react"; -import { - ReturnElements, - StoreFunction, - TemplateObjects, - formatXml, - getParserError, - getQueryTemplate -} from "components/ContentViews/QueryViewUtils"; -import ConfirmModal from "components/Modals/ConfirmModal"; -import { QueryEditor } from "components/QueryEditor"; -import { getTag } from "components/QueryEditorUtils"; -import { StyledNativeSelect } from "components/Select"; -import { Button } from "components/StyledComponents/Button"; -import { DispatchOperation } from "contexts/operationStateReducer"; -import OperationType from "contexts/operationType"; -import { QueryActionType, QueryContext } from "contexts/queryContext"; -import { useOperationState } from "hooks/useOperationState"; -import React, { ChangeEvent, useContext, useState } from "react"; -import QueryService from "services/queryService"; -import styled from "styled-components"; -import { Colors } from "styles/Colors"; -import Icon from "styles/Icons"; - -const QueryView = (): React.ReactElement => { - const { - operationState: { colors }, - dispatchOperation - } = useOperationState(); - const { - queryState: { queries, tabIndex }, - dispatchQuery - } = useContext(QueryContext); - const [isLoading, setIsLoading] = useState(false); - const [isTemplateMenuOpen, setIsTemplateMenuOpen] = useState(false); - const [menuAnchor, setMenuAnchor] = useState(null); - const { query, result, storeFunction, returnElements, optionsIn } = - queries[tabIndex]; - - const validateAndFormatQuery = (): boolean => { - const formattedQuery = formatXml(query); - const parserError = getParserError(formattedQuery); - if (parserError) { - dispatchQuery({ type: QueryActionType.SetResult, result: parserError }); - } else if (formattedQuery !== query) { - onQueryChange(formattedQuery); - } - return !parserError; - }; - - const sendQuery = () => { - const getResult = async (dispatchOperation?: DispatchOperation | null) => { - dispatchOperation?.({ type: OperationType.HideModal }); - setIsLoading(true); - const requestReturnElements = - storeFunction === StoreFunction.GetFromStore && - returnElements !== ReturnElements.None - ? returnElements - : undefined; - let response = await QueryService.postQuery( - query, - storeFunction, - requestReturnElements, - optionsIn?.trim() - ); - if (response.startsWith("<")) { - response = formatXml(response); - } - dispatchQuery({ type: QueryActionType.SetResult, result: response }); - setIsLoading(false); - }; - const isValid = validateAndFormatQuery(); - if (!isValid) return; - if (storeFunction === StoreFunction.DeleteFromStore) { - displayConfirmation( - () => getResult(dispatchOperation), - dispatchOperation - ); - } else { - getResult(); - } - }; - - const onQueryChange = (newValue: string) => { - dispatchQuery({ type: QueryActionType.SetQuery, query: newValue }); - }; - - const onFunctionChange = (event: ChangeEvent) => { - dispatchQuery({ - type: QueryActionType.SetStoreFunction, - storeFunction: event.target.value as StoreFunction - }); - }; - - const onReturnElementsChange = (event: ChangeEvent) => { - dispatchQuery({ - type: QueryActionType.SetReturnElements, - returnElements: event.target.value as ReturnElements - }); - }; - - const onOptionsInChange = (event: ChangeEvent) => { - dispatchQuery({ - type: QueryActionType.SetOptionsIn, - optionsIn: event.target.value - }); - }; - - const onTemplateSelect = (templateObject: TemplateObjects) => { - const template = getQueryTemplate(templateObject, returnElements); - if (template != undefined) { - dispatchQuery({ type: QueryActionType.SetQuery, query: template }); - } - setIsTemplateMenuOpen(false); - }; - - const onTabChange = (index: number) => { - if (index >= queries.length) { - dispatchQuery({ type: QueryActionType.AddTab }); - } else { - dispatchQuery({ type: QueryActionType.SetTabIndex, tabIndex: index }); - } - }; - - const onCloseTab = (event: React.MouseEvent, tabId: string) => { - event.stopPropagation(); - dispatchQuery({ type: QueryActionType.RemoveTab, tabId }); - }; - - const getTabName = (query: string) => { - return ( - getTag(query.split("\n")?.[0]) ?? (query.split("\n")?.[0] || "Empty") - ); - }; - - return ( - - - - {queries.map((query) => ( - - {getTabName(query.query)} - onCloseTab(event, query.tabId)} - /> - - ))} - - - - - -
-
- -
- - {Object.values(StoreFunction).map((value) => { - return ( - - ); - })} - - - {Object.values(ReturnElements).map((value) => { - return ( - - ); - })} - - - - setIsTemplateMenuOpen(false)} - anchorEl={menuAnchor} - colors={colors} - > - {Object.values(TemplateObjects).map((value) => { - return ( - onTemplateSelect(value)} - > - {value} - - ); - })} - - -
-
-
- -
-
-
- ); -}; - -const displayConfirmation = ( - onConfirm: () => void, - dispatchOperation: DispatchOperation -) => { - const confirmation = ( - Are you sure you want to delete this object?} - onConfirm={onConfirm} - confirmColor={"danger"} - confirmText={"Delete"} - switchButtonPlaces={true} - /> - ); - dispatchOperation({ - type: OperationType.DisplayModal, - payload: confirmation - }); -}; - -const StyledMenu = styled(Menu)<{ colors: Colors }>` - background: ${(props) => props.colors.ui.backgroundLight}; - padding: 0.25rem 0.5rem 0.25rem 0.5rem; - max-height: 80vh; - overflow-y: scroll; -`; - -const StyledMenuItem = styled(Menu.Item)<{ colors: Colors }>` - &&:hover { - background-color: ${(props) => - props.colors.interactive.contextMenuItemHover}; - } - color: ${(props) => props.colors.text.staticIconsDefault}; - padding: 4px; -`; - -const StyledTextField = styled(TextField)<{ colors: Colors }>` - label { - color: ${(props) => props.colors.text.staticIconsDefault}; - } - div { - background: ${(props) => props.colors.text.staticTextFieldDefault}; - } -`; - -const Layout = styled.div` - display: grid; - grid-template-rows: auto 1fr; - height: 100%; -`; - -const StyledClearIcon = styled(Icon)` - margin-left: 8px; - border-radius: 50%; - &:hover { - background-color: rgba(0, 0, 0, 0.1); - } -`; - -const StyledTab = styled(Tabs.Tab)<{ colors: Colors }>` - color: ${(props) => props.colors.infographic.primaryMossGreen}; -`; - -export default QueryView; diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/QueryView/QueryView.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/QueryView/QueryView.tsx new file mode 100644 index 000000000..bbd327840 --- /dev/null +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/QueryView/QueryView.tsx @@ -0,0 +1,122 @@ +import { Tabs } from "@equinor/eds-core-react"; +import { QueryEditor } from "components/QueryEditor"; +import { getTag } from "components/QueryEditorUtils"; +import { QueryActionType, QueryContext } from "contexts/queryContext"; +import { useOperationState } from "hooks/useOperationState"; +import React, { useContext } from "react"; +import styled from "styled-components"; +import { Colors } from "styles/Colors"; +import Icon from "styles/Icons"; + +import { Box } from "@mui/material"; +import QueryOptions from "./components/QueryOptions"; + +const QueryView = (): React.ReactElement => { + const { + operationState: { colors } + } = useOperationState(); + const { + queryState: { queries, tabIndex }, + dispatchQuery + } = useContext(QueryContext); + + const { query, result } = queries[tabIndex]; + + const onQueryChange = (newValue: string) => { + dispatchQuery({ type: QueryActionType.SetQuery, query: newValue }); + }; + + const onTabChange = (index: number) => { + if (index >= queries.length) { + dispatchQuery({ type: QueryActionType.AddTab }); + } else { + dispatchQuery({ type: QueryActionType.SetTabIndex, tabIndex: index }); + } + }; + + const onCloseTab = (event: React.MouseEvent, tabId: string) => { + event.stopPropagation(); + dispatchQuery({ type: QueryActionType.RemoveTab, tabId }); + }; + + const getTabName = (query: string) => { + return ( + getTag(query.split("\n")?.[0]) ?? (query.split("\n")?.[0] || "Empty") + ); + }; + + return ( + + + + {queries.map((query) => ( + + {getTabName(query.query)} + onCloseTab(event, query.tabId)} + /> + + ))} + + + + + +
+ + + + +
+ +
+
+
+ ); +}; + +const Layout = styled.div` + display: grid; + grid-template-rows: auto 1fr; + height: 100%; + padding: 1rem; +`; + +const StyledClearIcon = styled(Icon)` + margin-left: 8px; + border-radius: 50%; + + &:hover { + background-color: rgba(0, 0, 0, 0.1); + } +`; + +const StyledTab = styled(Tabs.Tab)<{ colors: Colors }>` + color: ${(props) => props.colors.infographic.primaryMossGreen}; +`; + +export default QueryView; diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/QueryView/components/QueryOptions/QueryOptions.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/QueryView/components/QueryOptions/QueryOptions.tsx new file mode 100644 index 000000000..2b58bbe36 --- /dev/null +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/QueryView/components/QueryOptions/QueryOptions.tsx @@ -0,0 +1,228 @@ +import React, { ChangeEvent, FC, useContext, useState } from "react"; +import { Box, Stack } from "@mui/material"; +import { StyledNativeSelect } from "../../../../Select.tsx"; +import { + formatXml, + getParserError, + ReturnElements, + StoreFunction +} from "../../../QueryViewUtils.tsx"; +import TemplatePicker from "./TemplatePicker"; +import { + QueryActionType, + QueryContext +} from "../../../../../contexts/queryContext.tsx"; +import styled, { css } from "styled-components"; +import { TextField } from "@equinor/eds-core-react"; +import { Colors } from "../../../../../styles/Colors.tsx"; +import { useOperationState } from "../../../../../hooks/useOperationState.tsx"; +import { Button } from "../../../../StyledComponents/Button.tsx"; +import Icon from "../../../../../styles/Icons.tsx"; +import { DispatchOperation } from "../../../../../contexts/operationStateReducer.tsx"; +import OperationType from "../../../../../contexts/operationType.ts"; +import QueryService from "../../../../../services/queryService.ts"; +import ConfirmModal from "../../../../Modals/ConfirmModal.tsx"; + +type QueryOptionsProps = { + onQueryChange: (newValue: string) => void; +}; + +const QueryOptions: FC = ({ onQueryChange }) => { + const { + dispatchQuery, + queryState: { queries, tabIndex } + } = useContext(QueryContext); + const { + operationState: { colors }, + dispatchOperation + } = useOperationState(); + + const [isLoading, setIsLoading] = useState(false); + + const { storeFunction, returnElements, optionsIn, query } = queries[tabIndex]; + + const onFunctionChange = (event: ChangeEvent) => { + dispatchQuery({ + type: QueryActionType.SetStoreFunction, + storeFunction: event.target.value as StoreFunction + }); + }; + + const validateAndFormatQuery = (): boolean => { + const formattedQuery = formatXml(query); + const parserError = getParserError(formattedQuery); + if (parserError) { + dispatchQuery({ type: QueryActionType.SetResult, result: parserError }); + } else if (formattedQuery !== query) { + onQueryChange(formattedQuery); + } + return !parserError; + }; + + const sendQuery = () => { + const getResult = async (dispatchOperation?: DispatchOperation | null) => { + dispatchOperation?.({ type: OperationType.HideModal }); + setIsLoading(true); + const requestReturnElements = + storeFunction === StoreFunction.GetFromStore && + returnElements !== ReturnElements.None + ? returnElements + : undefined; + let response = await QueryService.postQuery( + query, + storeFunction, + requestReturnElements, + optionsIn?.trim() + ); + if (response.startsWith("<")) { + response = formatXml(response); + } + dispatchQuery({ type: QueryActionType.SetResult, result: response }); + setIsLoading(false); + }; + const isValid = validateAndFormatQuery(); + if (!isValid) return; + if (storeFunction === StoreFunction.DeleteFromStore) { + displayConfirmation( + () => getResult(dispatchOperation), + dispatchOperation + ); + } else { + getResult(); + } + }; + + const onReturnElementsChange = (event: ChangeEvent) => { + dispatchQuery({ + type: QueryActionType.SetReturnElements, + returnElements: event.target.value as ReturnElements + }); + }; + + const onOptionsInChange = (event: ChangeEvent) => { + dispatchQuery({ + type: QueryActionType.SetOptionsIn, + optionsIn: event.target.value + }); + }; + + return ( + + + + + {Object.values(StoreFunction).map((value) => { + return ( + + ); + })} + + + + + + + + + {storeFunction === StoreFunction.GetFromStore && ( + + + + More options + + + + {Object.values(ReturnElements).map((value) => { + return ( + + ); + })} + + + + + + )} + + ); +}; + +const displayConfirmation = ( + onConfirm: () => void, + dispatchOperation: DispatchOperation +) => { + const confirmation = ( + Are you sure you want to delete this object?} + onConfirm={onConfirm} + confirmColor={"danger"} + confirmText={"Delete"} + switchButtonPlaces={true} + /> + ); + dispatchOperation({ + type: OperationType.DisplayModal, + payload: confirmation + }); +}; + +const StyledTextField = styled(TextField)<{ colors: Colors }>` + label { + color: ${(props) => props.colors.text.staticIconsDefault}; + } + + div { + background: ${(props) => props.colors.text.staticTextFieldDefault}; + } +`; + +const StyledSummary = styled(Box)<{ colors: Colors }>` + ${({ colors }) => css` + color: ${colors.interactive.primaryResting}; + `} +`; + +export default QueryOptions; diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/QueryView/components/QueryOptions/TemplatePicker/TemplatePicker.tsx b/Src/WitsmlExplorer.Frontend/components/ContentViews/QueryView/components/QueryOptions/TemplatePicker/TemplatePicker.tsx new file mode 100644 index 000000000..2ed864bc2 --- /dev/null +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/QueryView/components/QueryOptions/TemplatePicker/TemplatePicker.tsx @@ -0,0 +1,96 @@ +import React, { FC, useState } from "react"; +import { Button } from "../../../../../StyledComponents/Button.tsx"; +import Icon from "../../../../../../styles/Icons.tsx"; +import { + getQueryTemplate, + ReturnElements, + TemplateObjects +} from "../../../../QueryViewUtils.tsx"; +import { + DispatchQuery, + QueryActionType +} from "../../../../../../contexts/queryContext.tsx"; +import { useOperationState } from "../../../../../../hooks/useOperationState.tsx"; +import styled from "styled-components"; +import { Menu } from "@equinor/eds-core-react"; +import { Colors } from "../../../../../../styles/Colors.tsx"; + +type TemplatePickerProps = { + dispatchQuery: DispatchQuery; + returnElements: ReturnElements; +}; + +const TemplatePicker: FC = ({ + dispatchQuery, + returnElements +}) => { + const { + operationState: { colors } + } = useOperationState(); + + const [isTemplateMenuOpen, setIsTemplateMenuOpen] = useState(false); + const [menuAnchor, setMenuAnchor] = useState(null); + + const onTemplateSelect = (templateObject: TemplateObjects) => { + const template = getQueryTemplate(templateObject, returnElements); + if (template != undefined) { + dispatchQuery({ type: QueryActionType.SetQuery, query: template }); + } + setIsTemplateMenuOpen(false); + }; + + return ( + <> + + setIsTemplateMenuOpen(false)} + anchorEl={menuAnchor} + colors={colors} + > + {Object.values(TemplateObjects).map((value) => { + return ( + onTemplateSelect(value)} + > + {value} + + ); + })} + + + ); +}; + +export default TemplatePicker; + +const StyledMenu = styled(Menu)<{ colors: Colors }>` + background: ${(props) => props.colors.ui.backgroundLight}; + max-height: 80vh; + overflow-y: scroll; +`; + +const StyledMenuItem = styled(Menu.Item)<{ colors: Colors }>` + &&:hover { + background-color: ${(props) => + props.colors.interactive.contextMenuItemHover}; + } + + color: ${(props) => props.colors.text.staticIconsDefault}; + padding: 4px; +`; diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/QueryView/components/QueryOptions/TemplatePicker/index.ts b/Src/WitsmlExplorer.Frontend/components/ContentViews/QueryView/components/QueryOptions/TemplatePicker/index.ts new file mode 100644 index 000000000..ac3bad6fb --- /dev/null +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/QueryView/components/QueryOptions/TemplatePicker/index.ts @@ -0,0 +1 @@ +export { default } from "./TemplatePicker.tsx"; diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/QueryView/components/QueryOptions/index.ts b/Src/WitsmlExplorer.Frontend/components/ContentViews/QueryView/components/QueryOptions/index.ts new file mode 100644 index 000000000..e6aa3c075 --- /dev/null +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/QueryView/components/QueryOptions/index.ts @@ -0,0 +1 @@ +export { default } from "./QueryOptions"; diff --git a/Src/WitsmlExplorer.Frontend/components/ContentViews/QueryView/index.ts b/Src/WitsmlExplorer.Frontend/components/ContentViews/QueryView/index.ts new file mode 100644 index 000000000..329b5b066 --- /dev/null +++ b/Src/WitsmlExplorer.Frontend/components/ContentViews/QueryView/index.ts @@ -0,0 +1 @@ +export { default } from "./QueryView.tsx"; diff --git a/Src/WitsmlExplorer.Frontend/components/QueryEditor.tsx b/Src/WitsmlExplorer.Frontend/components/QueryEditor.tsx index bb8566106..9812f7b02 100644 --- a/Src/WitsmlExplorer.Frontend/components/QueryEditor.tsx +++ b/Src/WitsmlExplorer.Frontend/components/QueryEditor.tsx @@ -12,56 +12,84 @@ import AceEditor from "react-ace"; import { useNavigate, useParams } from "react-router-dom"; import styled from "styled-components"; import { Colors, dark } from "styles/Colors"; +import React, { FC, useState } from "react"; +import { Chip } from "./StyledComponents/Chip"; +import Icon from "../styles/Icons.tsx"; +import { Stack } from "@mui/material"; export interface QueryEditorProps { value: string; onChange?: (newValue: string) => void; + showCommandPaletteOption?: boolean; readonly?: boolean; } -export const QueryEditor = (props: QueryEditorProps) => { - const { value, onChange, readonly } = props; +export const QueryEditor: FC = ({ + value, + onChange, + readonly, + showCommandPaletteOption +}) => { + const [ace, setAce] = useState(null); + const navigate = useNavigate(); const { serverUrl } = useParams(); const { operationState: { colors } } = useOperationState(); - const onLoad = (editor: any) => { + const onLoadInternal = (editor: any) => { editor.renderer.setPadding(10); editor.renderer.setScrollMargin(10); - if (readonly) { - editor.renderer.$cursorLayer.element.style.display = "none"; - } else { - editor.completers = [customCompleter]; - } - editor.renderer.on("afterRender", (_: any, renderer: any) => - updateLinesWithWidgets(editor, renderer, navigate, serverUrl, readonly) - ); + + if (readonly) editor.renderer.$cursorLayer.element.style.display = "none"; + else editor.completers = [customCompleter]; + + editor.renderer.on("afterRender", (_: any, renderer: any) => { + updateLinesWithWidgets(editor, renderer, navigate, serverUrl, readonly); + if (showCommandPaletteOption) setAce(editor); + }); }; + const canSeeCommandPalette = showCommandPaletteOption && ace && !readonly; + return ( - + <> + + {canSeeCommandPalette && ( + + { + ace.execCommand("openCommandPalette"); + }} + title="Show command palette [F1]" + > + + Command Palette + + + )} + ); }; diff --git a/Src/WitsmlExplorer.Frontend/components/StyledComponents/Chip/Chip.tsx b/Src/WitsmlExplorer.Frontend/components/StyledComponents/Chip/Chip.tsx index cb32ddbe4..1d2bf8b1e 100644 --- a/Src/WitsmlExplorer.Frontend/components/StyledComponents/Chip/Chip.tsx +++ b/Src/WitsmlExplorer.Frontend/components/StyledComponents/Chip/Chip.tsx @@ -26,13 +26,14 @@ export const Chip = forwardRef( Chip.displayName = "WitsmlExplorerChip"; const WitsmlDefaultChip = styled(EquinorChip)` - ${({ colors: { ui, mode, interactive } }) => { + ${({ colors: { ui, mode, interactive, text } }) => { if (mode === "light") return; return css` --eds_ui_background__light: ${ui.backgroundLight}; --eds_interactive_primary__resting: ${interactive.primaryResting}; --eds_interactive_primary__hover_alt: ${ui.backgroundDefault}; + --eds_interactive_primary__hover: ${text.staticPropertyValue}; `; }} `; diff --git a/Src/WitsmlExplorer.Frontend/styles/Icons.tsx b/Src/WitsmlExplorer.Frontend/styles/Icons.tsx index 9e3e1ada7..62508c79c 100644 --- a/Src/WitsmlExplorer.Frontend/styles/Icons.tsx +++ b/Src/WitsmlExplorer.Frontend/styles/Icons.tsx @@ -2,7 +2,6 @@ import { Icon } from "@equinor/eds-core-react"; import { accessible, account_circle as accountCircle, - filter_alt_active as activeFilter, add, arrow_down as arrowDown, arrow_drop_right as arrowDropRight, @@ -32,29 +31,33 @@ import { favorite_filled as favoriteFilled, favorite_outlined as favoriteOutlined, filter_alt as filter, + filter_alt_active as activeFilter, folder_open as folderOpen, format_line_spacing as formatLine, go_to as goTo, in_progress as inProgress, info_circle as infoCircle, - trending_up as isActive, keyboard, launch, more_vertical as moreVertical, new_alert as newAlert, paste, person, + play, refresh, save, search, settings, + style, sync, text_field as textField, + trending_up as isActive, tune, update, upload, world } from "@equinor/eds-icons"; + const icons = { accessible, accountCircle, @@ -100,10 +103,12 @@ const icons = { newAlert, paste, person, + play, refresh, save, search, settings, + style, sync, textField, tune,