diff --git a/res/css/_components.scss b/res/css/_components.scss index 1feea1d26f..014c295025 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -67,7 +67,6 @@ @import "./views/dialogs/_AddExistingToSpaceDialog.scss"; @import "./views/dialogs/_AddressPickerDialog.scss"; @import "./views/dialogs/_Analytics.scss"; -@import "./views/dialogs/_BetaFeedbackDialog.scss"; @import "./views/dialogs/_BugReportDialog.scss"; @import "./views/dialogs/_ChangelogDialog.scss"; @import "./views/dialogs/_ChatCreateOrReuseChatDialog.scss"; @@ -82,6 +81,7 @@ @import "./views/dialogs/_EditCommunityPrototypeDialog.scss"; @import "./views/dialogs/_FeedbackDialog.scss"; @import "./views/dialogs/_ForwardDialog.scss"; +@import "./views/dialogs/_GenericFeatureFeedbackDialog.scss"; @import "./views/dialogs/_GroupAddressPicker.scss"; @import "./views/dialogs/_HostSignupDialog.scss"; @import "./views/dialogs/_IncomingSasDialog.scss"; diff --git a/res/css/structures/_SpaceRoomDirectory.scss b/res/css/structures/_SpaceRoomDirectory.scss index bc343f535c..cb91aa3c7d 100644 --- a/res/css/structures/_SpaceRoomDirectory.scss +++ b/res/css/structures/_SpaceRoomDirectory.scss @@ -61,6 +61,7 @@ limitations under the License. .mx_AccessibleButton_kind_link { padding: 0; + font-size: inherit; } .mx_SearchBox { diff --git a/res/css/structures/_SpaceRoomView.scss b/res/css/structures/_SpaceRoomView.scss index e4832d9430..58a4b426c2 100644 --- a/res/css/structures/_SpaceRoomView.scss +++ b/res/css/structures/_SpaceRoomView.scss @@ -335,24 +335,17 @@ $SpaceRoomViewInnerWidth: 428px; word-wrap: break-word; } - > hr { - border: none; - height: 1px; - background-color: $groupFilterPanel-bg-color; - } - .mx_SearchBox { margin: 0 0 20px; flex: 0; } .mx_SpaceFeedbackPrompt { - margin-bottom: 16px; - - // hide the HR as we have our own - & + hr { - display: none; - } + padding: 7px; // 8px - 1px border + border: 1px solid $menu-border-color; + border-radius: 8px; + width: max-content; + margin: 0 0 -40px auto; // collapse its own height to not push other components down } .mx_SpaceRoomDirectory_list { @@ -513,66 +506,3 @@ $SpaceRoomViewInnerWidth: 428px; } } } - -.mx_SpaceFeedbackPrompt { - margin-top: 18px; - margin-bottom: 12px; - - > hr { - border: none; - border-top: 1px solid $input-border-color; - margin-bottom: 12px; - } - - > div { - display: flex; - flex-direction: row; - font-size: $font-15px; - line-height: $font-24px; - - > span { - color: $secondary-fg-color; - position: relative; - padding-left: 32px; - font-size: inherit; - line-height: inherit; - margin-right: auto; - - &::before { - content: ''; - position: absolute; - left: 0; - top: 2px; - height: 20px; - width: 20px; - background-color: $secondary-fg-color; - mask-repeat: no-repeat; - mask-size: contain; - mask-image: url('$(res)/img/element-icons/room/room-summary.svg'); - mask-position: center; - } - } - - .mx_AccessibleButton_kind_link { - color: $accent-color; - position: relative; - padding: 0 0 0 24px; - margin-left: 8px; - font-size: inherit; - line-height: inherit; - - &::before { - content: ''; - position: absolute; - left: 0; - height: 16px; - width: 16px; - background-color: $accent-color; - mask-repeat: no-repeat; - mask-size: contain; - mask-image: url('$(res)/img/element-icons/chat-bubbles.svg'); - mask-position: center; - } - } - } -} diff --git a/res/css/views/dialogs/_BetaFeedbackDialog.scss b/res/css/views/dialogs/_GenericFeatureFeedbackDialog.scss similarity index 90% rename from res/css/views/dialogs/_BetaFeedbackDialog.scss rename to res/css/views/dialogs/_GenericFeatureFeedbackDialog.scss index 9f5f6b512e..f83eed9c53 100644 --- a/res/css/views/dialogs/_BetaFeedbackDialog.scss +++ b/res/css/views/dialogs/_GenericFeatureFeedbackDialog.scss @@ -14,8 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -.mx_BetaFeedbackDialog { - .mx_BetaFeedbackDialog_subheading { +.mx_GenericFeatureFeedbackDialog { + .mx_GenericFeatureFeedbackDialog_subheading { color: $primary-fg-color; font-size: $font-14px; line-height: $font-20px; diff --git a/res/css/views/spaces/_SpaceCreateMenu.scss b/res/css/views/spaces/_SpaceCreateMenu.scss index 88b9d8f693..097b2b648e 100644 --- a/res/css/views/spaces/_SpaceCreateMenu.scss +++ b/res/css/views/spaces/_SpaceCreateMenu.scss @@ -43,6 +43,12 @@ $spacePanelWidth: 71px; color: $secondary-fg-color; margin: 0; } + + .mx_SpaceFeedbackPrompt { + border-top: 1px solid $input-border-color; + padding-top: 12px; + margin-top: 16px; + } } // XXX remove this when spaces leaves Beta @@ -99,3 +105,25 @@ $spacePanelWidth: 71px; } } } + +.mx_SpaceFeedbackPrompt { + font-size: $font-15px; + line-height: $font-24px; + + > span { + color: $secondary-fg-color; + position: relative; + font-size: inherit; + line-height: inherit; + margin-right: auto; + } + + .mx_AccessibleButton_kind_link { + color: $accent-color; + position: relative; + padding: 0; + margin-left: 8px; + font-size: inherit; + line-height: inherit; + } +} diff --git a/src/components/structures/SpaceRoomView.tsx b/src/components/structures/SpaceRoomView.tsx index 682a0c68db..4064b2f48e 100644 --- a/src/components/structures/SpaceRoomView.tsx +++ b/src/components/structures/SpaceRoomView.tsx @@ -72,10 +72,8 @@ import IconizedContextMenu, { import AccessibleTooltipButton from "../views/elements/AccessibleTooltipButton"; import { BetaPill } from "../views/beta/BetaCard"; import { UserTab } from "../views/dialogs/UserSettingsDialog"; -import Modal from "../../Modal"; -import BetaFeedbackDialog from "../views/dialogs/BetaFeedbackDialog"; -import SdkConfig from "../../SdkConfig"; import { EffectiveMembership, getEffectiveMembership } from "../../utils/membership"; +import { SpaceFeedbackPrompt } from "../views/spaces/SpaceCreateMenu"; interface IProps { space: Room; @@ -102,28 +100,6 @@ enum Phase { PrivateExistingRooms, } -// XXX: Temporary for the Spaces Beta only -export const SpaceFeedbackPrompt = ({ onClick }: { onClick?: () => void }) => { - if (!SdkConfig.get().bug_report_endpoint_url) return null; - - return
-
-
- { _t("Spaces are a beta feature.") } - { - if (onClick) onClick(); - Modal.createTrackedDialog("Beta Feedback", "feature_spaces", BetaFeedbackDialog, { - featureId: "feature_spaces", - }); - }}> - { _t("Feedback") } - -
-
; -}; - const RoomMemberCount = ({ room, children }) => { const members = useRoomMembers(room); const count = members.length; @@ -432,6 +408,7 @@ const SpaceLanding = ({ space }) => { }; return
+
@@ -456,8 +433,6 @@ const SpaceLanding = ({ space }) => {
) } - -
; @@ -542,7 +517,6 @@ const SpaceSetupFirstRooms = ({ space, title, description, onFinished }) => { value={buttonLabel} /> - ; }; @@ -567,7 +541,6 @@ const SpaceAddExistingRooms = ({ space, onFinished }) => { spacesRenderer={defaultSpacesRenderer} dmsRenderer={defaultDmsRenderer} /> - ; }; @@ -587,7 +560,6 @@ const SpaceSetupPublicShare = ({ justCreatedOpts, space, onFinished, createdRoom { createdRooms ? _t("Go to my first room") : _t("Go to my space") } - ; }; @@ -616,9 +588,8 @@ const SpaceSetupPrivateScope = ({ space, justCreatedOpts, onFinished }) => {

{ _t("Teammates might not be able to view or join any private rooms you make.") }

-

{ _t("We're working on this as part of the beta, but just want to let you know.") }

+

{ _t("We're working on this, but just want to let you know.") }

- ; }; @@ -741,7 +712,6 @@ const SpaceSetupPrivateInvite = ({ space, onFinished }) => { value={buttonLabel} /> - ; }; diff --git a/src/components/views/beta/BetaCard.tsx b/src/components/views/beta/BetaCard.tsx index ec662d831b..c2ba869ab4 100644 --- a/src/components/views/beta/BetaCard.tsx +++ b/src/components/views/beta/BetaCard.tsx @@ -27,6 +27,8 @@ import BetaFeedbackDialog from "../dialogs/BetaFeedbackDialog"; import SdkConfig from "../../../SdkConfig"; import SettingsFlag from "../elements/SettingsFlag"; +// XXX: Keep this around for re-use in future Betas + interface IProps { title?: string; featureId: string; diff --git a/src/components/views/dialogs/AddExistingSubspaceDialog.tsx b/src/components/views/dialogs/AddExistingSubspaceDialog.tsx index a6dbf9dd42..7fef2c2d9d 100644 --- a/src/components/views/dialogs/AddExistingSubspaceDialog.tsx +++ b/src/components/views/dialogs/AddExistingSubspaceDialog.tsx @@ -21,7 +21,6 @@ import { _t } from '../../../languageHandler'; import BaseDialog from "./BaseDialog"; import AccessibleButton from "../elements/AccessibleButton"; import MatrixClientContext from "../../../contexts/MatrixClientContext"; -import { SpaceFeedbackPrompt } from "../../structures/SpaceRoomView"; import { AddExistingToSpace, defaultSpacesRenderer, SubspaceSelector } from "./AddExistingToSpaceDialog"; interface IProps { @@ -61,8 +60,6 @@ const AddExistingSubspaceDialog: React.FC = ({ space, onCreateSubspaceCl spacesRenderer={defaultSpacesRenderer} /> - - onFinished(false)} /> ; }; diff --git a/src/components/views/dialogs/AddExistingToSpaceDialog.tsx b/src/components/views/dialogs/AddExistingToSpaceDialog.tsx index 9b64af0c80..cf4f369d09 100644 --- a/src/components/views/dialogs/AddExistingToSpaceDialog.tsx +++ b/src/components/views/dialogs/AddExistingToSpaceDialog.tsx @@ -35,7 +35,6 @@ import StyledCheckbox from "../elements/StyledCheckbox"; import MatrixClientContext from "../../../contexts/MatrixClientContext"; import { sortRooms } from "../../../stores/room-list/algorithms/tag-sorting/RecentAlgorithm"; import ProgressBar from "../elements/ProgressBar"; -import { SpaceFeedbackPrompt } from "../../structures/SpaceRoomView"; import DecoratedRoomAvatar from "../avatars/DecoratedRoomAvatar"; import QueryMatcher from "../../../autocomplete/QueryMatcher"; import TruncatedList from "../elements/TruncatedList"; @@ -446,8 +445,6 @@ const AddExistingToSpaceDialog: React.FC = ({ space, onCreateRoomClick, dmsRenderer={defaultDmsRenderer} /> - - onFinished(false)} /> ; }; diff --git a/src/components/views/dialogs/BetaFeedbackDialog.tsx b/src/components/views/dialogs/BetaFeedbackDialog.tsx index 34218a3399..c5fba52b51 100644 --- a/src/components/views/dialogs/BetaFeedbackDialog.tsx +++ b/src/components/views/dialogs/BetaFeedbackDialog.tsx @@ -14,22 +14,18 @@ See the License for the specific language governing permissions and limitations under the License. */ -import React, { useState } from "react"; +import React from "react"; -import QuestionDialog from './QuestionDialog'; import { _t } from '../../../languageHandler'; -import Field from "../elements/Field"; -import SdkConfig from "../../../SdkConfig"; import { IDialogProps } from "./IDialogProps"; import SettingsStore from "../../../settings/SettingsStore"; -import { submitFeedback } from "../../../rageshake/submit-rageshake"; -import StyledCheckbox from "../elements/StyledCheckbox"; -import Modal from "../../../Modal"; -import InfoDialog from "./InfoDialog"; import AccessibleButton from "../elements/AccessibleButton"; import defaultDispatcher from "../../../dispatcher/dispatcher"; import { Action } from "../../../dispatcher/actions"; import { UserTab } from "./UserSettingsDialog"; +import GenericFeatureFeedbackDialog from "./GenericFeatureFeedbackDialog"; + +// XXX: Keep this around for re-use in future Betas interface IProps extends IDialogProps { featureId: string; @@ -38,77 +34,28 @@ interface IProps extends IDialogProps { const BetaFeedbackDialog: React.FC = ({ featureId, onFinished }) => { const info = SettingsStore.getBetaInfo(featureId); - const [comment, setComment] = useState(""); - const [canContact, setCanContact] = useState(false); - - const sendFeedback = async (ok: boolean) => { - if (!ok) return onFinished(false); - - const extraData = SettingsStore.getBetaInfo(featureId)?.extraSettings.reduce((o, k) => { - o[k] = SettingsStore.getValue(k); - return o; - }, {}); - - submitFeedback(SdkConfig.get().bug_report_endpoint_url, info.feedbackLabel, comment, canContact, extraData); - onFinished(true); - - Modal.createTrackedDialog("Beta Dialog Sent", featureId, InfoDialog, { - title: _t("Beta feedback"), - description: _t("Thank you for your feedback, we really appreciate it."), - button: _t("Done"), - hasCloseButton: false, - fixedWidth: false, - }); - }; - - return ( -
- { _t(info.feedbackSubheading) } -   - { _t("Your platform and username will be noted to help us use your feedback as much as we can.") } - - { - onFinished(false); - defaultDispatcher.dispatch({ - action: Action.ViewUserSettings, - initialTabId: UserTab.Labs, - }); - }} - > - { _t("To leave the beta, visit your settings.") } - -
- - { - setComment(ev.target.value); - }} - autoFocus={true} - /> - - setCanContact((e.target as HTMLInputElement).checked)} - > - { _t("You may contact me if you have any follow up questions") } - - } - button={_t("Send feedback")} - buttonDisabled={!comment} - onFinished={sendFeedback} - />); + subheading={_t(info.feedbackSubheading)} + onFinished={onFinished} + rageshakeLabel={info.feedbackLabel} + rageshakeData={Object.fromEntries((SettingsStore.getBetaInfo(featureId)?.extraSettings || []).map(k => { + return SettingsStore.getValue(k); + }))} + > + { + onFinished(false); + defaultDispatcher.dispatch({ + action: Action.ViewUserSettings, + initialTabId: UserTab.Labs, + }); + }} + > + { _t("To leave the beta, visit your settings.") } + + ; }; export default BetaFeedbackDialog; diff --git a/src/components/views/dialogs/GenericFeatureFeedbackDialog.tsx b/src/components/views/dialogs/GenericFeatureFeedbackDialog.tsx new file mode 100644 index 0000000000..d68569b126 --- /dev/null +++ b/src/components/views/dialogs/GenericFeatureFeedbackDialog.tsx @@ -0,0 +1,101 @@ +/* +Copyright 2021 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import React, { useState } from "react"; + +import QuestionDialog from './QuestionDialog'; +import { _t } from '../../../languageHandler'; +import Field from "../elements/Field"; +import SdkConfig from "../../../SdkConfig"; +import { IDialogProps } from "./IDialogProps"; +import { submitFeedback } from "../../../rageshake/submit-rageshake"; +import StyledCheckbox from "../elements/StyledCheckbox"; +import Modal from "../../../Modal"; +import InfoDialog from "./InfoDialog"; + +interface IProps extends IDialogProps { + title: string; + subheading: string; + rageshakeLabel: string; + rageshakeData?: Record; +} + +const GenericFeatureFeedbackDialog: React.FC = ({ + title, + subheading, + children, + rageshakeLabel, + rageshakeData = {}, + onFinished, +}) => { + const [comment, setComment] = useState(""); + const [canContact, setCanContact] = useState(false); + + const sendFeedback = async (ok: boolean) => { + if (!ok) return onFinished(false); + + submitFeedback(SdkConfig.get().bug_report_endpoint_url, rageshakeLabel, comment, canContact, rageshakeData); + onFinished(true); + + Modal.createTrackedDialog("Feedback Sent", rageshakeLabel, InfoDialog, { + title, + description: _t("Thank you for your feedback, we really appreciate it."), + button: _t("Done"), + hasCloseButton: false, + fixedWidth: false, + }); + }; + + return ( +
+ { subheading } +   + { _t("Your platform and username will be noted to help us use your feedback as much as we can.") } + + { children } +
+ + { + setComment(ev.target.value); + }} + autoFocus={true} + /> + + setCanContact((e.target as HTMLInputElement).checked)} + > + { _t("You may contact me if you have any follow up questions") } + + } + button={_t("Send feedback")} + buttonDisabled={!comment} + onFinished={sendFeedback} + />); +}; + +export default GenericFeatureFeedbackDialog; diff --git a/src/components/views/spaces/SpaceCreateMenu.tsx b/src/components/views/spaces/SpaceCreateMenu.tsx index 16c8ec6fb5..406028dbc7 100644 --- a/src/components/views/spaces/SpaceCreateMenu.tsx +++ b/src/components/views/spaces/SpaceCreateMenu.tsx @@ -26,15 +26,14 @@ import createRoom from "../../../createRoom"; import MatrixClientContext from "../../../contexts/MatrixClientContext"; import SpaceBasicSettings, { SpaceAvatar } from "./SpaceBasicSettings"; import AccessibleButton from "../elements/AccessibleButton"; -import { BetaPill } from "../beta/BetaCard"; -import defaultDispatcher from "../../../dispatcher/dispatcher"; -import { Action } from "../../../dispatcher/actions"; -import { UserTab } from "../dialogs/UserSettingsDialog"; import Field from "../elements/Field"; import withValidation from "../elements/Validation"; -import { SpaceFeedbackPrompt } from "../../structures/SpaceRoomView"; import { HistoryVisibility, Preset } from "matrix-js-sdk/src/@types/partials"; import RoomAliasField from "../elements/RoomAliasField"; +import SdkConfig from "../../../SdkConfig"; +import Modal from "../../../Modal"; +import GenericFeatureFeedbackDialog from "../dialogs/GenericFeatureFeedbackDialog"; +import SettingsStore from "../../../settings/SettingsStore"; const SpaceCreateMenuType = ({ title, description, className, onClick }) => { return ( @@ -65,6 +64,34 @@ const nameToAlias = (name: string, domain: string): string => { return `#${localpart}:${domain}`; }; +// XXX: Temporary for the Spaces release only +export const SpaceFeedbackPrompt = ({ onClick }: { onClick?: () => void }) => { + if (!SdkConfig.get().bug_report_endpoint_url) return null; + + return
+ { _t("Spaces are a new feature.") } + { + if (onClick) onClick(); + Modal.createTrackedDialog("Spaces Feedback", "", GenericFeatureFeedbackDialog, { + title: _t("Spaces feedback"), + subheading: _t("Thank you for trying Spaces. " + + "Your feedback will help inform the next versions."), + rageshakeLabel: "spaces-feedback", + rageshakeData: Object.fromEntries([ + "feature_spaces.all_rooms", + "feature_spaces.space_member_dms", + "feature_spaces.space_dm_badges", + ].map(k => [k, SettingsStore.getValue(k)])), + }); + }} + > + { _t("Give feedback.") } + +
; +}; + type BProps = Pick, "setAvatar" | "name" | "setName" | "topic" | "setTopic">; interface ISpaceCreateFormProps extends BProps { busy: boolean; @@ -280,13 +307,6 @@ const SpaceCreateMenu = ({ onFinished }) => { managed={false} > - { - onFinished(); - defaultDispatcher.dispatch({ - action: Action.ViewUserSettings, - initialTabId: UserTab.Labs, - }); - }} /> { body } ; diff --git a/src/components/views/spaces/SpaceSettingsGeneralTab.tsx b/src/components/views/spaces/SpaceSettingsGeneralTab.tsx index a43b180752..8ee848a28c 100644 --- a/src/components/views/spaces/SpaceSettingsGeneralTab.tsx +++ b/src/components/views/spaces/SpaceSettingsGeneralTab.tsx @@ -21,7 +21,6 @@ import { EventType } from "matrix-js-sdk/src/@types/event"; import { _t } from "../../../languageHandler"; import AccessibleButton from "../elements/AccessibleButton"; -import { SpaceFeedbackPrompt } from "../../structures/SpaceRoomView"; import SpaceBasicSettings from "./SpaceBasicSettings"; import { avatarUrlForRoom } from "../../../Avatar"; import { IDialogProps } from "../dialogs/IDialogProps"; @@ -96,8 +95,6 @@ const SpaceSettingsGeneralTab = ({ matrixClient: cli, space, onFinished }: IProp { error &&
{ error }
} - -
debug logs to help us track down the problem.": "PRO TIP: If you start a bug, please submit debug logs to help us track down the problem.", + "Feedback": "Feedback", "Report a bug": "Report a bug", "Please view existing bugs on Github first. No match? Start a new one.": "Please view existing bugs on Github first. No match? Start a new one.", + "Send feedback": "Send feedback", "You don't have permission to do this": "You don't have permission to do this", "Sending": "Sending", "Sent": "Sent", @@ -2302,6 +2301,10 @@ "Forward message": "Forward message", "Message preview": "Message preview", "Search for rooms or people": "Search for rooms or people", + "Thank you for your feedback, we really appreciate it.": "Thank you for your feedback, we really appreciate it.", + "Done": "Done", + "Your platform and username will be noted to help us use your feedback as much as we can.": "Your platform and username will be noted to help us use your feedback as much as we can.", + "You may contact me if you have any follow up questions": "You may contact me if you have any follow up questions", "Confirm abort of host creation": "Confirm abort of host creation", "Are you sure you wish to abort creation of the host? The process cannot be continued.": "Are you sure you wish to abort creation of the host? The process cannot be continued.", "Abort": "Abort", @@ -2813,7 +2816,6 @@ "Search names and descriptions": "Search names and descriptions", "If you can't find the room you're looking for, ask for an invite or create a new room.": "If you can't find the room you're looking for, ask for an invite or create a new room.", "Create room": "Create room", - "Spaces are a beta feature.": "Spaces are a beta feature.", "Private space": "Private space", " invites you": " invites you", "To view %(spaceName)s, turn on the Spaces beta": "To view %(spaceName)s, turn on the Spaces beta", @@ -2840,7 +2842,7 @@ "Me and my teammates": "Me and my teammates", "A private space for you and your teammates": "A private space for you and your teammates", "Teammates might not be able to view or join any private rooms you make.": "Teammates might not be able to view or join any private rooms you make.", - "We're working on this as part of the beta, but just want to let you know.": "We're working on this as part of the beta, but just want to let you know.", + "We're working on this, but just want to let you know.": "We're working on this, but just want to let you know.", "Failed to invite the following users to your space: %(csvUsers)s": "Failed to invite the following users to your space: %(csvUsers)s", "Inviting...": "Inviting...", "Invite your teammates": "Invite your teammates", diff --git a/src/settings/Settings.tsx b/src/settings/Settings.tsx index 5aa49df8a1..64edd4c202 100644 --- a/src/settings/Settings.tsx +++ b/src/settings/Settings.tsx @@ -124,6 +124,7 @@ export interface ISetting { // not use this for new settings. invertedSettingName?: string; + // XXX: Keep this around for re-use in future Betas betaInfo?: { title: string; // _td caption: string; // _td diff --git a/src/utils/objects.ts b/src/utils/objects.ts index c2ee6ce100..e3b7b6cf59 100644 --- a/src/utils/objects.ts +++ b/src/utils/objects.ts @@ -141,21 +141,3 @@ export function objectKeyChanges(a: O, b: O): (keyof O)[] { export function objectClone(obj: O): O { return JSON.parse(JSON.stringify(obj)); } - -/** - * Converts a series of entries to an object. - * @param entries The entries to convert. - * @returns The converted object. - */ -// NOTE: Deprecated once we have Object.fromEntries() support. -// @ts-ignore - return type is complaining about non-string keys, but we know better -export function objectFromEntries(entries: Iterable<[K, V]>): {[k: K]: V} { - const obj: { - // @ts-ignore - same as return type - [k: K]: V;} = {}; - for (const e of entries) { - // @ts-ignore - same as return type - obj[e[0]] = e[1]; - } - return obj; -} diff --git a/test/utils/arrays-test.ts b/test/utils/arrays-test.ts index cf9a5f0089..277260bf29 100644 --- a/test/utils/arrays-test.ts +++ b/test/utils/arrays-test.ts @@ -29,7 +29,6 @@ import { ArrayUtil, GroupedArray, } from "../../src/utils/arrays"; -import { objectFromEntries } from "../../src/utils/objects"; function expectSample(i: number, input: number[], expected: number[], smooth = false) { console.log(`Resample case index: ${i}`); // for debugging test failures @@ -336,7 +335,7 @@ describe('arrays', () => { expect(result).toBeDefined(); expect(result.value).toBeDefined(); - const asObject = objectFromEntries(result.value.entries()); + const asObject = Object.fromEntries(result.value.entries()); expect(asObject).toMatchObject(output); }); }); diff --git a/test/utils/objects-test.ts b/test/utils/objects-test.ts index 154fa3604f..b360fbd1d1 100644 --- a/test/utils/objects-test.ts +++ b/test/utils/objects-test.ts @@ -18,7 +18,6 @@ import { objectClone, objectDiff, objectExcluding, - objectFromEntries, objectHasDiff, objectKeyChanges, objectShallowClone, @@ -242,21 +241,4 @@ describe('objects', () => { expect(result.test.third).not.toBe(a.test.third); }); }); - - describe('objectFromEntries', () => { - it('should create an object from an array of entries', () => { - const output = { a: 1, b: 2, c: 3 }; - const result = objectFromEntries(Object.entries(output)); - expect(result).toBeDefined(); - expect(result).toMatchObject(output); - }); - - it('should maintain pointers in values', () => { - const output = { a: {}, b: 2, c: 3 }; - const result = objectFromEntries(Object.entries(output)); - expect(result).toBeDefined(); - expect(result).toMatchObject(output); - expect(result['a']).toBe(output.a); - }); - }); });