Skip to content

Commit

Permalink
chore: reusable copy to clipboard method and adds error handling (#5010)
Browse files Browse the repository at this point in the history
  • Loading branch information
tiagoapolo authored Jan 28, 2025
1 parent 05161a2 commit 43108f9
Show file tree
Hide file tree
Showing 12 changed files with 33 additions and 33 deletions.
26 changes: 14 additions & 12 deletions frontend/common/utils/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import AccountStore from 'common/stores/account-store'
import ProjectStore from 'common/stores/project-store'
import Project from 'common/project'
import {
ChangeSet,
ContentType,
FeatureState,
FeatureStateValue,
Expand All @@ -21,7 +20,6 @@ import _ from 'lodash'
import ErrorMessage from 'components/ErrorMessage'
import WarningMessage from 'components/WarningMessage'
import Constants from 'common/constants'
import Format from './format'
import { defaultFlags } from 'common/stores/default-flags'
import Color from 'color'

Expand Down Expand Up @@ -124,10 +122,6 @@ const Utils = Object.assign({}, require('./base/_utils'), {
return res
},

copyFeatureName: (featureName: string) => {
navigator.clipboard.writeText(featureName)
toast('Copied to clipboard')
},
displayLimitAlert(type: string, percentage: number | undefined) {
const envOrProject =
type === 'segment overrides' ? 'environment' : 'project'
Expand Down Expand Up @@ -180,10 +174,20 @@ const Utils = Object.assign({}, require('./base/_utils'), {

return conditions.find((v) => v.value === operator)
},

copyToClipboard: async (value: string, successMessage?: string, errorMessage?: string) => {
try {
await navigator.clipboard.writeText(value)
toast(successMessage ?? 'Copied to clipboard')
} catch (error) {
toast(errorMessage ?? 'Failed to copy to clipboard')
throw error
}
},
/** Checks whether the specified flag exists, which is different from the flag being enabled or not. This is used to
* only add behaviour to Flagsmith-on-Flagsmith flags that have been explicitly created by customers.
*/
flagsmithFeatureExists(flag: string) {
flagsmithFeatureExists(flag: string) {
return Object.prototype.hasOwnProperty.call(flagsmith.getAllFlags(), flag)
},
getApproveChangeRequestPermission() {
Expand Down Expand Up @@ -275,6 +279,7 @@ const Utils = Object.assign({}, require('./base/_utils'), {
getFlagsmithValue(key: string) {
return flagsmith.getValue(key)
},

getIdentitiesEndpoint(_project: ProjectType) {
const project = _project || ProjectStore.model
if (project && project.use_edge_identities) {
Expand All @@ -289,7 +294,6 @@ const Utils = Object.assign({}, require('./base/_utils'), {
defaultFlags.integration_data,
)
},

getIsEdge() {
const model = ProjectStore.model as null | ProjectType

Expand Down Expand Up @@ -333,14 +337,14 @@ const Utils = Object.assign({}, require('./base/_utils'), {
}
}
},

getOrganisationHomePage(id?: string) {
const orgId = id || AccountStore.getOrganisation()?.id
if (!orgId) {
return `/organisations`
}
return `/organisation/${orgId}/projects`
},

getPlanName: (plan: string) => {
if (plan && plan.includes('free')) {
return planNames.free
Expand Down Expand Up @@ -548,7 +552,6 @@ const Utils = Object.assign({}, require('./base/_utils'), {
id ? `${id}/` : ''
}`
},

getViewIdentitiesPermission() {
return 'VIEW_IDENTITIES'
},
Expand Down Expand Up @@ -592,6 +595,7 @@ const Utils = Object.assign({}, require('./base/_utils'), {
if (typeof x !== 'number') return ''
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
},

openChat() {
// @ts-ignore
if (typeof $crisp !== 'undefined') {
Expand All @@ -608,7 +612,6 @@ const Utils = Object.assign({}, require('./base/_utils'), {
removeElementFromArray(array: any[], index: number) {
return array.slice(0, index).concat(array.slice(index + 1))
},

renderWithPermission(permission: boolean, name: string, el: ReactNode) {
return permission ? (
el
Expand All @@ -629,7 +632,6 @@ const Utils = Object.assign({}, require('./base/_utils'), {
const hasStaleFlagsPermission = Utils.getPlansPermission('STALE_FLAGS')
return tag?.type === 'STALE' && !hasStaleFlagsPermission
},

validateMetadataType(type: string, value: any) {
switch (type) {
case 'int': {
Expand Down
2 changes: 1 addition & 1 deletion frontend/web/components/CompareEnvironments.js
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ class CompareEnvironments extends Component {
</div>
<Button
onClick={() => {
Utils.copyFeatureName(p.projectFlagLeft.name)
Utils.copyToClipboard(p.projectFlagLeft.name)
}}
theme='icon'
className='ms-2 me-2'
Expand Down
2 changes: 1 addition & 1 deletion frontend/web/components/CompareIdentities.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ const CompareIdentities: FC<CompareIdentitiesType> = ({
</Tooltip>
</span>
<Button
onClick={() => Utils.copyFeatureName(name)}
onClick={() => Utils.copyToClipboard(name)}
theme='icon'
className='ms-2 me-2'
>
Expand Down
4 changes: 2 additions & 2 deletions frontend/web/components/FeatureRow.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class TheComponent extends Component {
const { projectFlag } = this.props
e?.stopPropagation()?.()
e?.currentTarget?.blur?.()
Utils.copyFeatureName(projectFlag.name)
Utils.copyToClipboard(projectFlag.name)
}
confirmRemove = (projectFlag, cb) => {
openModal2(
Expand Down Expand Up @@ -98,7 +98,7 @@ class TheComponent extends Component {
{this.props.permission ? 'Edit Feature' : 'Feature'}: {projectFlag.name}
<Button
onClick={() => {
Utils.copyFeatureName(projectFlag.name)
Utils.copyToClipboard(projectFlag.name)
}}
theme='icon'
className='ms-2'
Expand Down
4 changes: 2 additions & 2 deletions frontend/web/components/JSONReference.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Button from './base/forms/Button'
import Switch from './Switch'
import flagsmith from 'flagsmith'
import Icon from './Icon'
import Utils from 'common/utils/utils'

type JSONReferenceType = {
title: string
Expand Down Expand Up @@ -142,8 +143,7 @@ const JSONReference: FC<JSONReferenceType> = ({
</div>
<Button
onClick={() => {
navigator.clipboard.writeText(condensed ? idsOnly : value)
toast('Copied')
Utils.copyToClipboard(condensed ? idsOnly : value)
}}
size='xSmall'
iconLeft='copy'
Expand Down
5 changes: 3 additions & 2 deletions frontend/web/components/OrgEnvironmentSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { sortBy } from 'lodash'
import PanelSearch from './PanelSearch'
import Input from './base/forms/Input'
import Button from './base/forms/Button'
import Utils from 'common/utils/utils'

type OrgProjectSelectType = {
organisationId?: string | null
Expand Down Expand Up @@ -116,7 +117,7 @@ const OrgEnvironmentSelect: FC<OrgProjectSelectType> = ({
style={{ width: 80 }}
className='btn-secondary ml-2 mr-4'
onClick={() => {
navigator.clipboard.writeText(projectId)
Utils.copyToClipboard(projectId)
}}
>
Copy
Expand All @@ -138,7 +139,7 @@ const OrgEnvironmentSelect: FC<OrgProjectSelectType> = ({
style={{ width: 80 }}
className='btn-secondary ml-2 mr-4'
onClick={() => {
navigator.clipboard.writeText(environmentId)
Utils.copyToClipboard(environmentId)
}}
>
Copy
Expand Down
4 changes: 2 additions & 2 deletions frontend/web/components/SDKKeysPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Input from './base/forms/Input'
import Icon from './Icon'
import ServerSideSDKKeys from './ServerSideSDKKeys'
import PageTitle from './PageTitle'
import Utils from 'common/utils/utils'

type SDKKeysType = {
match: {
Expand Down Expand Up @@ -49,8 +50,7 @@ const SDKKeysPage: FC<SDKKeysType> = ({
</Flex>
<Button
onClick={() => {
navigator.clipboard.writeText(environmentId)
toast('Copied')
Utils.copyToClipboard(environmentId)
}}
className='ml-2 btn-with-icon'
>
Expand Down
3 changes: 1 addition & 2 deletions frontend/web/components/ServerSideSDKKeys.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,7 @@ class ServerSideSDKKeys extends Component {
</div>
<Button
onClick={() => {
navigator.clipboard.writeText(key)
toast('Copied')
Utils.copyToClipboard(key)
}}
className='ml-2 btn-with-icon'
>
Expand Down
3 changes: 1 addition & 2 deletions frontend/web/components/Token.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ class Token extends Component {
theme='outline'
className='ml-2'
onClick={() => {
navigator.clipboard.writeText(this.props.token)
toast('Copied')
Utils.copyToClipboard(this.props.token)
}}
>
Copy
Expand Down
5 changes: 2 additions & 3 deletions frontend/web/components/modals/CreateSAML.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,8 @@ const CreateSAML: FC<CreateSAML> = ({ organisationId, samlName }) => {
`./auth/saml/${name}/response/`,
new Request(Project.api).url, // Project.api can be relative, e.g. /api/v1/
).href
const copyAcsUrl = async () => {
await navigator.clipboard.writeText(acsUrl)
toast('Copied to clipboard')
const copyAcsUrl = () => {
Utils.copyToClipboard(acsUrl)
}

useEffect(() => {
Expand Down
4 changes: 2 additions & 2 deletions frontend/web/components/pages/UserPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ const UserPage: FC<UserPageType> = (props) => {
<span className='standard-case'>{projectFlag.name}</span>
<Button
onClick={() => {
Utils.copyFeatureName(projectFlag.name)
Utils.copyToClipboard(projectFlag.name)
}}
theme='icon'
className='ms-2'
Expand Down Expand Up @@ -701,7 +701,7 @@ const UserPage: FC<UserPageType> = (props) => {
onClick={(e) => {
e?.stopPropagation()
e?.currentTarget?.blur()
Utils.copyFeatureName(
Utils.copyToClipboard(
projectFlag.name,
)
}}
Expand Down
4 changes: 2 additions & 2 deletions frontend/web/components/pages/UsersAndPermissionsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -386,16 +386,16 @@ const UsersAndPermissionsInner: FC<UsersAndPermissionsInnerType> = ({
theme='secondary'
size='small'
onClick={() => {
navigator.clipboard.writeText(
Utils.copyToClipboard(
`${
document.location.origin
}/invite/${
inviteLinks?.find(
(f) => f.role === role,
)?.hash
}`,
'Link copied',
)
toast('Link copied')
}}
>
Copy Invite Link
Expand Down

0 comments on commit 43108f9

Please sign in to comment.