mirror of
https://github.com/enso-org/enso.git
synced 2024-11-26 08:52:58 +03:00
Rename Connector to Datalinks (#9948)
#### Tl;dr Closes: enso-org/cloud-v2#1132 This PR renames Connector to Datalink --- #### Test Plan: Everything should work as before, but instead of sending `connectorId` we send `dataLinkId` and endpoint now is `/datalink` ---
This commit is contained in:
parent
c7476c10f3
commit
55d43a3d8a
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
@ -47,5 +47,5 @@ Cargo.toml
|
||||
# Dashboard, Cloud & Authentication
|
||||
/app/ide-desktop/ @PabloBuchu @indiv0 @somebody1234 @MrFlashAccount
|
||||
# The data-link schema is owned by the libraries team
|
||||
/app/ide-desktop/lib/dashboard/src/data/dataLinkSchema.json @radeusgd @jdunkerley @GregoryTravis @AdRiley
|
||||
/app/ide-desktop/lib/dashboard/src/data/datalinkSchema.json @radeusgd @jdunkerley @GregoryTravis @AdRiley
|
||||
/app/ide-desktop/lib/dashboard/src/data/__tests__ @radeusgd @jdunkerley @GregoryTravis @AdRiley @PabloBuchu @indiv0 @somebody1234
|
||||
|
Before Width: | Height: | Size: 889 B After Width: | Height: | Size: 889 B |
Before Width: | Height: | Size: 625 B After Width: | Height: | Size: 625 B |
@ -83,7 +83,7 @@ export function locateSecretValueInput(page: test.Page) {
|
||||
/** Find a search bar input (if any) on the current page. */
|
||||
export function locateSearchBarInput(page: test.Page) {
|
||||
return locateSearchBar(page).getByPlaceholder(
|
||||
'Type to search for projects, Data Links, users, and more.'
|
||||
'Type to search for projects, Datalinks, users, and more.'
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/** @file A dynamic wizard for creating an arbitrary type of Data Link. */
|
||||
/** @file A dynamic wizard for creating an arbitrary type of Datalink. */
|
||||
import * as React from 'react'
|
||||
|
||||
import * as backendProvider from '#/providers/BackendProvider'
|
||||
@ -31,7 +31,7 @@ export interface JSONSchemaInputProps {
|
||||
readonly setValue: React.Dispatch<React.SetStateAction<NonNullable<unknown> | null>>
|
||||
}
|
||||
|
||||
/** A dynamic wizard for creating an arbitrary type of Data Link. */
|
||||
/** A dynamic wizard for creating an arbitrary type of Datalink. */
|
||||
export default function JSONSchemaInput(props: JSONSchemaInputProps) {
|
||||
const { dropdownTitle, readOnly = false, defs, schema, path, getValidator } = props
|
||||
const { value: valueRaw, setValue: setValueRaw } = props
|
||||
|
@ -43,7 +43,7 @@ const ACTION_TO_TEXT_ID: Readonly<Record<inputBindings.DashboardBindingKey, text
|
||||
uploadFiles: 'uploadFilesShortcut',
|
||||
newProject: 'newProjectShortcut',
|
||||
newFolder: 'newFolderShortcut',
|
||||
newDataLink: 'newDataLinkShortcut',
|
||||
newDatalink: 'newDatalinkShortcut',
|
||||
newSecret: 'newSecretShortcut',
|
||||
useInNewProject: 'useInNewProjectShortcut',
|
||||
closeModal: 'closeModalShortcut',
|
||||
|
@ -2,7 +2,7 @@
|
||||
import * as React from 'react'
|
||||
|
||||
import BlankIcon from 'enso-assets/blank.svg'
|
||||
import ConnectorIcon from 'enso-assets/connector.svg'
|
||||
import DatalinkIcon from 'enso-assets/datalink.svg'
|
||||
import FolderIcon from 'enso-assets/folder.svg'
|
||||
import KeyIcon from 'enso-assets/key.svg'
|
||||
import NetworkIcon from 'enso-assets/network.svg'
|
||||
@ -32,8 +32,8 @@ export default function AssetIcon(props: AssetIconProps) {
|
||||
case backend.AssetType.file: {
|
||||
return <SvgMask src={fileIcon.fileIcon()} className={className} />
|
||||
}
|
||||
case backend.AssetType.dataLink: {
|
||||
return <SvgMask src={ConnectorIcon} className={className} />
|
||||
case backend.AssetType.datalink: {
|
||||
return <SvgMask src={DatalinkIcon} className={className} />
|
||||
}
|
||||
case backend.AssetType.secret: {
|
||||
return <SvgMask src={KeyIcon} className={className} />
|
||||
|
@ -230,7 +230,7 @@ export default function AssetRow(props: AssetRowProps) {
|
||||
}
|
||||
case backendModule.AssetType.project:
|
||||
case backendModule.AssetType.secret:
|
||||
case backendModule.AssetType.dataLink:
|
||||
case backendModule.AssetType.datalink:
|
||||
case backendModule.AssetType.specialLoading:
|
||||
case backendModule.AssetType.specialEmpty: {
|
||||
// Ignored.
|
||||
@ -422,7 +422,7 @@ export default function AssetRow(props: AssetRowProps) {
|
||||
case AssetEventType.newProject:
|
||||
case AssetEventType.newFolder:
|
||||
case AssetEventType.uploadFiles:
|
||||
case AssetEventType.newDataLink:
|
||||
case AssetEventType.newDatalink:
|
||||
case AssetEventType.newSecret:
|
||||
case AssetEventType.updateFiles:
|
||||
case AssetEventType.openProject:
|
||||
@ -509,9 +509,9 @@ export default function AssetRow(props: AssetRowProps) {
|
||||
}
|
||||
break
|
||||
}
|
||||
case backendModule.AssetType.dataLink: {
|
||||
case backendModule.AssetType.datalink: {
|
||||
try {
|
||||
const value = await backend.getConnector(asset.id, asset.title)
|
||||
const value = await backend.getDatalink(asset.id, asset.title)
|
||||
const fileName = `${asset.title}.datalink`
|
||||
download.download(
|
||||
URL.createObjectURL(
|
||||
@ -522,7 +522,7 @@ export default function AssetRow(props: AssetRowProps) {
|
||||
fileName
|
||||
)
|
||||
} catch (error) {
|
||||
toastAndLog('downloadDataLinkError', error, asset.title)
|
||||
toastAndLog('downloadDatalinkError', error, asset.title)
|
||||
}
|
||||
break
|
||||
}
|
||||
@ -687,7 +687,7 @@ export default function AssetRow(props: AssetRowProps) {
|
||||
case backendModule.AssetType.directory:
|
||||
case backendModule.AssetType.project:
|
||||
case backendModule.AssetType.file:
|
||||
case backendModule.AssetType.dataLink:
|
||||
case backendModule.AssetType.datalink:
|
||||
case backendModule.AssetType.secret: {
|
||||
const innerProps: AssetRowInnerProps = {
|
||||
key,
|
||||
|
@ -1,8 +1,8 @@
|
||||
/** @file A dynamic wizard for creating an arbitrary type of Data Link. */
|
||||
/** @file A dynamic wizard for creating an arbitrary type of Datalink. */
|
||||
import * as React from 'react'
|
||||
|
||||
import SCHEMA from '#/data/dataLinkSchema.json' assert { type: 'json' }
|
||||
import * as dataLinkValidator from '#/data/dataLinkValidator'
|
||||
import SCHEMA from '#/data/datalinkSchema.json' assert { type: 'json' }
|
||||
import * as datalinkValidator from '#/data/datalinkValidator'
|
||||
|
||||
import type * as jsonSchemaInput from '#/components/JSONSchemaInput'
|
||||
import JSONSchemaInput from '#/components/JSONSchemaInput'
|
||||
@ -22,19 +22,19 @@ const DEFS: Record<string, object> = SCHEMA.$defs
|
||||
/** Get a known schema using a path.
|
||||
* @throws {Error} when there is no schema present at the given path. */
|
||||
function getValidator(path: string) {
|
||||
return error.assert<(value: unknown) => boolean>(() => dataLinkValidator.AJV.getSchema(path))
|
||||
return error.assert<(value: unknown) => boolean>(() => datalinkValidator.AJV.getSchema(path))
|
||||
}
|
||||
|
||||
// =====================
|
||||
// === DataLinkInput ===
|
||||
// =====================
|
||||
|
||||
/** Props for a {@link DataLinkInput}. */
|
||||
export interface DataLinkInputProps
|
||||
/** Props for a {@link DatalinkInput}. */
|
||||
export interface DatalinkInputProps
|
||||
extends Omit<jsonSchemaInput.JSONSchemaInputProps, 'defs' | 'getValidator' | 'path' | 'schema'> {}
|
||||
|
||||
/** A dynamic wizard for creating an arbitrary type of Data Link. */
|
||||
export default function DataLinkInput(props: DataLinkInputProps) {
|
||||
/** A dynamic wizard for creating an arbitrary type of Datalink. */
|
||||
export default function DatalinkInput(props: DatalinkInputProps) {
|
||||
return (
|
||||
<JSONSchemaInput
|
||||
defs={DEFS}
|
@ -1,7 +1,7 @@
|
||||
/** @file The icon and name of a {@link backendModule.SecretAsset}. */
|
||||
import * as React from 'react'
|
||||
|
||||
import ConnectorIcon from 'enso-assets/connector.svg'
|
||||
import DatalinkIcon from 'enso-assets/datalink.svg'
|
||||
|
||||
import * as eventHooks from '#/hooks/eventHooks'
|
||||
import * as setAssetHooks from '#/hooks/setAssetHooks'
|
||||
@ -23,25 +23,25 @@ import * as indent from '#/utilities/indent'
|
||||
import * as object from '#/utilities/object'
|
||||
import Visibility from '#/utilities/Visibility'
|
||||
|
||||
// =====================
|
||||
// === ConnectorName ===
|
||||
// =====================
|
||||
// ====================
|
||||
// === DatalinkName ===
|
||||
// ====================
|
||||
|
||||
/** Props for a {@link DataLinkNameColumn}. */
|
||||
export interface DataLinkNameColumnProps extends column.AssetColumnProps {}
|
||||
/** Props for a {@link DatalinkNameColumn}. */
|
||||
export interface DatalinkNameColumnProps extends column.AssetColumnProps {}
|
||||
|
||||
/** The icon and name of a {@link backendModule.DataLinkAsset}.
|
||||
* @throws {Error} when the asset is not a {@link backendModule.DataLinkAsset}.
|
||||
/** The icon and name of a {@link backendModule.DatalinkAsset}.
|
||||
* @throws {Error} when the asset is not a {@link backendModule.DatalinkAsset}.
|
||||
* This should never happen. */
|
||||
export default function DataLinkNameColumn(props: DataLinkNameColumnProps) {
|
||||
export default function DatalinkNameColumn(props: DatalinkNameColumnProps) {
|
||||
const { item, setItem, selected, state, rowState, setRowState, isEditable } = props
|
||||
const { assetEvents, dispatchAssetListEvent, setIsAssetPanelTemporarilyVisible } = state
|
||||
const toastAndLog = toastAndLogHooks.useToastAndLog()
|
||||
const { backend } = backendProvider.useBackend()
|
||||
const inputBindings = inputBindingsProvider.useInputBindings()
|
||||
if (item.type !== backendModule.AssetType.dataLink) {
|
||||
if (item.type !== backendModule.AssetType.datalink) {
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
throw new Error('`DataLinkNameColumn` can only display Data Links.')
|
||||
throw new Error('`DatalinkNameColumn` can only display Datalinks.')
|
||||
}
|
||||
const asset = item.item
|
||||
const setAsset = setAssetHooks.useSetAsset(asset, setItem)
|
||||
@ -90,16 +90,16 @@ export default function DataLinkNameColumn(props: DataLinkNameColumnProps) {
|
||||
// are handled by `AssetRow`.
|
||||
break
|
||||
}
|
||||
case AssetEventType.newDataLink: {
|
||||
case AssetEventType.newDatalink: {
|
||||
if (item.key === event.placeholderId) {
|
||||
if (backend.type !== backendModule.BackendType.remote) {
|
||||
toastAndLog('localBackendDataLinkError')
|
||||
toastAndLog('localBackendDatalinkError')
|
||||
} else {
|
||||
rowState.setVisibility(Visibility.faded)
|
||||
try {
|
||||
const { id } = await backend.createConnector({
|
||||
const { id } = await backend.createDatalink({
|
||||
parentDirectoryId: asset.parentId,
|
||||
connectorId: null,
|
||||
datalinkId: null,
|
||||
name: asset.title,
|
||||
value: event.value,
|
||||
})
|
||||
@ -107,7 +107,7 @@ export default function DataLinkNameColumn(props: DataLinkNameColumnProps) {
|
||||
setAsset(object.merger({ id }))
|
||||
} catch (error) {
|
||||
dispatchAssetListEvent({ type: AssetListEventType.delete, key: item.key })
|
||||
toastAndLog('createDataLinkError', error)
|
||||
toastAndLog('createDatalinkError', error)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -145,7 +145,7 @@ export default function DataLinkNameColumn(props: DataLinkNameColumnProps) {
|
||||
}
|
||||
}}
|
||||
>
|
||||
<img src={ConnectorIcon} className="m-name-column-icon size-icon" />
|
||||
<img src={DatalinkIcon} className="m-name-column-icon size-icon" />
|
||||
<EditableSpan
|
||||
editable={false}
|
||||
onSubmit={async newTitle => {
|
@ -83,7 +83,7 @@ export default function DirectoryNameColumn(props: DirectoryNameColumnProps) {
|
||||
switch (event.type) {
|
||||
case AssetEventType.newProject:
|
||||
case AssetEventType.uploadFiles:
|
||||
case AssetEventType.newDataLink:
|
||||
case AssetEventType.newDatalink:
|
||||
case AssetEventType.newSecret:
|
||||
case AssetEventType.openProject:
|
||||
case AssetEventType.updateFiles:
|
||||
|
@ -81,7 +81,7 @@ export default function FileNameColumn(props: FileNameColumnProps) {
|
||||
switch (event.type) {
|
||||
case AssetEventType.newProject:
|
||||
case AssetEventType.newFolder:
|
||||
case AssetEventType.newDataLink:
|
||||
case AssetEventType.newDatalink:
|
||||
case AssetEventType.newSecret:
|
||||
case AssetEventType.openProject:
|
||||
case AssetEventType.closeProject:
|
||||
|
@ -25,9 +25,9 @@ const ASSET_TYPE_TO_TEXT_ID: Readonly<Record<backendModule.AssetType, text.TextI
|
||||
[backendModule.AssetType.project]: 'projectAssetType',
|
||||
[backendModule.AssetType.file]: 'fileAssetType',
|
||||
[backendModule.AssetType.secret]: 'secretAssetType',
|
||||
[backendModule.AssetType.dataLink]: 'connectorAssetType',
|
||||
[backendModule.AssetType.specialEmpty]: 'specialEmptyAssetType',
|
||||
[backendModule.AssetType.specialLoading]: 'specialLoadingAssetType',
|
||||
[backendModule.AssetType.datalink]: 'datalinkAssetType',
|
||||
} satisfies { [Type in backendModule.AssetType]: `${Type}AssetType` }
|
||||
|
||||
// ==================
|
||||
|
@ -17,7 +17,7 @@ const CAPITALIZED_ASSET_TYPE: Readonly<Record<backend.AssetType, string>> = {
|
||||
[backend.AssetType.directory]: 'Folder',
|
||||
[backend.AssetType.project]: 'Project',
|
||||
[backend.AssetType.file]: 'File',
|
||||
[backend.AssetType.dataLink]: 'Data Link',
|
||||
[backend.AssetType.datalink]: 'Datalink',
|
||||
[backend.AssetType.secret]: 'Secret',
|
||||
// These assets should never be visible, since they don't have columns.
|
||||
[backend.AssetType.specialEmpty]: 'Empty asset',
|
||||
|
@ -236,7 +236,7 @@ export default function ProjectIcon(props: ProjectIconProps) {
|
||||
switch (event.type) {
|
||||
case AssetEventType.newFolder:
|
||||
case AssetEventType.uploadFiles:
|
||||
case AssetEventType.newDataLink:
|
||||
case AssetEventType.newDatalink:
|
||||
case AssetEventType.newSecret:
|
||||
case AssetEventType.copy:
|
||||
case AssetEventType.updateFiles:
|
||||
|
@ -110,7 +110,7 @@ export default function ProjectNameColumn(props: ProjectNameColumnProps) {
|
||||
async event => {
|
||||
switch (event.type) {
|
||||
case AssetEventType.newFolder:
|
||||
case AssetEventType.newDataLink:
|
||||
case AssetEventType.newDatalink:
|
||||
case AssetEventType.newSecret:
|
||||
case AssetEventType.openProject:
|
||||
case AssetEventType.closeProject:
|
||||
|
@ -65,7 +65,7 @@ export default function SecretNameColumn(props: SecretNameColumnProps) {
|
||||
case AssetEventType.newProject:
|
||||
case AssetEventType.newFolder:
|
||||
case AssetEventType.uploadFiles:
|
||||
case AssetEventType.newDataLink:
|
||||
case AssetEventType.newDatalink:
|
||||
case AssetEventType.openProject:
|
||||
case AssetEventType.updateFiles:
|
||||
case AssetEventType.closeProject:
|
||||
|
@ -2,7 +2,7 @@
|
||||
import * as React from 'react'
|
||||
|
||||
import type * as column from '#/components/dashboard/column'
|
||||
import DataLinkNameColumn from '#/components/dashboard/DataLinkNameColumn'
|
||||
import DatalinkNameColumn from '#/components/dashboard/DatalinkNameColumn'
|
||||
import DirectoryNameColumn from '#/components/dashboard/DirectoryNameColumn'
|
||||
import FileNameColumn from '#/components/dashboard/FileNameColumn'
|
||||
import ProjectNameColumn from '#/components/dashboard/ProjectNameColumn'
|
||||
@ -30,8 +30,8 @@ export default function AssetNameColumn(props: AssetNameColumnProps) {
|
||||
case backendModule.AssetType.file: {
|
||||
return <FileNameColumn {...props} />
|
||||
}
|
||||
case backendModule.AssetType.dataLink: {
|
||||
return <DataLinkNameColumn {...props} />
|
||||
case backendModule.AssetType.datalink: {
|
||||
return <DatalinkNameColumn {...props} />
|
||||
}
|
||||
case backendModule.AssetType.secret: {
|
||||
return <SecretNameColumn {...props} />
|
||||
|
@ -1,6 +1,6 @@
|
||||
/** @file Shortcuts for the dashboard application. */
|
||||
|
||||
import AddConnectorIcon from 'enso-assets/add_connector.svg'
|
||||
import AddDatalinkIcon from 'enso-assets/add_datalink.svg'
|
||||
import AddFolderIcon from 'enso-assets/add_folder.svg'
|
||||
import AddKeyIcon from 'enso-assets/add_key.svg'
|
||||
import AddNetworkIcon from 'enso-assets/add_network.svg'
|
||||
@ -81,10 +81,10 @@ export const BINDINGS = inputBindings.defineBindings({
|
||||
bindings: !detect.isOnMacOS() ? ['Mod+Alt+N'] : ['Mod+Alt+N', 'Mod+Alt+~'],
|
||||
icon: AddKeyIcon,
|
||||
},
|
||||
newDataLink: {
|
||||
name: 'New Data Link',
|
||||
newDatalink: {
|
||||
name: 'New Datalink',
|
||||
bindings: !detect.isOnMacOS() ? ['Mod+Alt+Shift+N'] : ['Mod+Alt+Shift+N', 'Mod+Alt+Shift+~'],
|
||||
icon: AddConnectorIcon,
|
||||
icon: AddDatalinkIcon,
|
||||
},
|
||||
useInNewProject: {
|
||||
name: 'Use In New Project',
|
||||
|
@ -6,23 +6,23 @@ import * as url from 'node:url'
|
||||
|
||||
import * as v from 'vitest'
|
||||
|
||||
import * as dataLinkValidator from '#/data/dataLinkValidator'
|
||||
import * as datalinkValidator from '#/data/datalinkValidator'
|
||||
|
||||
v.test('correctly rejects invalid values as not matching the schema', () => {
|
||||
v.expect(dataLinkValidator.validateDataLink({})).toBe(false)
|
||||
v.expect(dataLinkValidator.validateDataLink('foobar')).toBe(false)
|
||||
v.expect(dataLinkValidator.validateDataLink({ foo: 'BAR' })).toBe(false)
|
||||
v.expect(datalinkValidator.validateDatalink({})).toBe(false)
|
||||
v.expect(datalinkValidator.validateDatalink('foobar')).toBe(false)
|
||||
v.expect(datalinkValidator.validateDatalink({ foo: 'BAR' })).toBe(false)
|
||||
})
|
||||
|
||||
/** Load and parse a data-link description. */
|
||||
function loadDataLinkFile(dataLinkPath: string): unknown {
|
||||
const text: string = fs.readFileSync(dataLinkPath, { encoding: 'utf-8' })
|
||||
function loadDataLinkFile(datalinkPath: string): unknown {
|
||||
const text: string = fs.readFileSync(datalinkPath, { encoding: 'utf-8' })
|
||||
return JSON.parse(text)
|
||||
}
|
||||
|
||||
/** Check if the given data-link description matches the schema, reporting any errors. */
|
||||
function testSchema(json: unknown, fileName: string): void {
|
||||
const validate = dataLinkValidator.validateDataLink
|
||||
const validate = datalinkValidator.validateDatalink
|
||||
if (!validate(json)) {
|
||||
v.assert.fail(`Failed to validate ${fileName}:\n${JSON.stringify(validate.errors, null, 2)}`)
|
||||
}
|
||||
@ -60,7 +60,7 @@ v.test('rejects invalid schemas (Base)', () => {
|
||||
const invalidSchemas = ['example-http-format-invalid.datalink']
|
||||
for (const schema of invalidSchemas) {
|
||||
const json = loadDataLinkFile(path.resolve(BASE_DATA_LINKS_ROOT, schema))
|
||||
v.expect(dataLinkValidator.validateDataLink(json)).toBe(false)
|
||||
v.expect(datalinkValidator.validateDatalink(json)).toBe(false)
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
/** @file AJV instance configured for data links. */
|
||||
/** @file AJV instance configured for datalinks. */
|
||||
import type * as ajv from 'ajv/dist/2020'
|
||||
import Ajv from 'ajv/dist/2020'
|
||||
|
||||
import SCHEMA from '#/data/dataLinkSchema.json' assert { type: 'json' }
|
||||
import SCHEMA from '#/data/datalinkSchema.json' assert { type: 'json' }
|
||||
|
||||
import * as error from '#/utilities/error'
|
||||
|
||||
@ -12,6 +12,6 @@ AJV.addSchema(SCHEMA)
|
||||
|
||||
// This is a function, even though it does not contain function syntax.
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
export const validateDataLink = error.assert<ajv.ValidateFunction>(() =>
|
||||
export const validateDatalink = error.assert<ajv.ValidateFunction>(() =>
|
||||
AJV.getSchema('#/$defs/DataLink')
|
||||
)
|
@ -10,7 +10,7 @@ enum AssetEventType {
|
||||
newFolder = 'new-folder',
|
||||
uploadFiles = 'upload-files',
|
||||
updateFiles = 'update-files',
|
||||
newDataLink = 'new-data-link',
|
||||
newDatalink = 'new-datalink',
|
||||
newSecret = 'new-secret',
|
||||
openProject = 'open-project',
|
||||
closeProject = 'close-project',
|
||||
|
@ -5,7 +5,7 @@ enum AssetListEventType {
|
||||
newFolder = 'new-folder',
|
||||
newProject = 'new-project',
|
||||
uploadFiles = 'upload-files',
|
||||
newDataLink = 'new-data-link',
|
||||
newDatalink = 'new-datalink',
|
||||
newSecret = 'new-secret',
|
||||
insertAssets = 'insert-assets',
|
||||
closeFolder = 'close-folder',
|
||||
|
@ -29,7 +29,7 @@ interface AssetEvents {
|
||||
readonly newFolder: AssetNewFolderEvent
|
||||
readonly uploadFiles: AssetUploadFilesEvent
|
||||
readonly updateFiles: AssetUpdateFilesEvent
|
||||
readonly newDataLink: AssetNewDataLinkEvent
|
||||
readonly newDatalink: AssetNewDatalinkEvent
|
||||
readonly newSecret: AssetNewSecretEvent
|
||||
readonly openProject: AssetOpenProjectEvent
|
||||
readonly closeProject: AssetCloseProjectEvent
|
||||
@ -63,7 +63,7 @@ type SanityCheck<
|
||||
export interface AssetNewProjectEvent extends AssetBaseEvent<AssetEventType.newProject> {
|
||||
readonly placeholderId: backend.ProjectId
|
||||
readonly templateId: string | null
|
||||
readonly datalinkId: backend.ConnectorId | null
|
||||
readonly datalinkId: backend.DatalinkId | null
|
||||
readonly onSpinnerStateChange: ((state: spinner.SpinnerState) => void) | null
|
||||
}
|
||||
|
||||
@ -82,9 +82,9 @@ export interface AssetUpdateFilesEvent extends AssetBaseEvent<AssetEventType.upd
|
||||
readonly files: ReadonlyMap<backend.AssetId, File>
|
||||
}
|
||||
|
||||
/** A signal to create a Data Link. */
|
||||
export interface AssetNewDataLinkEvent extends AssetBaseEvent<AssetEventType.newDataLink> {
|
||||
readonly placeholderId: backend.ConnectorId
|
||||
/** A signal to create a Datalink. */
|
||||
export interface AssetNewDatalinkEvent extends AssetBaseEvent<AssetEventType.newDatalink> {
|
||||
readonly placeholderId: backend.DatalinkId
|
||||
readonly value: unknown
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ interface AssetListEvents {
|
||||
readonly newProject: AssetListNewProjectEvent
|
||||
readonly uploadFiles: AssetListUploadFilesEvent
|
||||
readonly newSecret: AssetListNewSecretEvent
|
||||
readonly newDataLink: AssetListNewDataLinkEvent
|
||||
readonly newDatalink: AssetListNewDatalinkEvent
|
||||
readonly insertAssets: AssetListInsertAssetsEvent
|
||||
readonly closeFolder: AssetListCloseFolderEvent
|
||||
readonly copy: AssetListCopyEvent
|
||||
@ -62,7 +62,7 @@ interface AssetListNewProjectEvent extends AssetListBaseEvent<AssetListEventType
|
||||
readonly parentKey: backend.DirectoryId
|
||||
readonly parentId: backend.DirectoryId
|
||||
readonly templateId: string | null
|
||||
readonly datalinkId: backend.ConnectorId | null
|
||||
readonly datalinkId: backend.DatalinkId | null
|
||||
readonly preferredName: string | null
|
||||
readonly onSpinnerStateChange: ((state: spinner.SpinnerState) => void) | null
|
||||
}
|
||||
@ -75,7 +75,7 @@ interface AssetListUploadFilesEvent extends AssetListBaseEvent<AssetListEventTyp
|
||||
}
|
||||
|
||||
/** A signal to create a new secret. */
|
||||
interface AssetListNewDataLinkEvent extends AssetListBaseEvent<AssetListEventType.newDataLink> {
|
||||
interface AssetListNewDatalinkEvent extends AssetListBaseEvent<AssetListEventType.newDatalink> {
|
||||
readonly parentKey: backend.DirectoryId
|
||||
readonly parentId: backend.DirectoryId
|
||||
readonly name: string
|
||||
|
@ -129,7 +129,7 @@ export default function AssetContextMenu(props: AssetContextMenuProps) {
|
||||
) : (
|
||||
<ContextMenus hidden={hidden} key={asset.id} event={event}>
|
||||
<ContextMenu aria-label={getText('assetContextMenuLabel')} hidden={hidden}>
|
||||
{asset.type === backendModule.AssetType.dataLink && (
|
||||
{asset.type === backendModule.AssetType.datalink && (
|
||||
<ContextMenuEntry
|
||||
hidden={hidden}
|
||||
action="useInNewProject"
|
||||
@ -377,7 +377,7 @@ export default function AssetContextMenu(props: AssetContextMenuProps) {
|
||||
isDisabled={
|
||||
isCloud &&
|
||||
asset.type !== backendModule.AssetType.file &&
|
||||
asset.type !== backendModule.AssetType.dataLink &&
|
||||
asset.type !== backendModule.AssetType.datalink &&
|
||||
asset.type !== backendModule.AssetType.project
|
||||
}
|
||||
action="download"
|
||||
|
@ -3,7 +3,7 @@ import * as React from 'react'
|
||||
|
||||
import PenIcon from 'enso-assets/pen.svg'
|
||||
|
||||
import * as dataLinkValidator from '#/data/dataLinkValidator'
|
||||
import * as datalinkValidator from '#/data/datalinkValidator'
|
||||
|
||||
import * as toastAndLogHooks from '#/hooks/toastAndLogHooks'
|
||||
|
||||
@ -17,7 +17,7 @@ import type Category from '#/layouts/CategorySwitcher/Category'
|
||||
|
||||
import * as aria from '#/components/aria'
|
||||
import SharedWithColumn from '#/components/dashboard/column/SharedWithColumn'
|
||||
import DataLinkInput from '#/components/dashboard/DataLinkInput'
|
||||
import DatalinkInput from '#/components/dashboard/DatalinkInput'
|
||||
import Label from '#/components/dashboard/Label'
|
||||
import StatelessSpinner, * as statelessSpinner from '#/components/StatelessSpinner'
|
||||
import Button from '#/components/styled/Button'
|
||||
@ -65,14 +65,14 @@ export default function AssetProperties(props: AssetPropertiesProps) {
|
||||
const [isEditingDescription, setIsEditingDescription] = React.useState(false)
|
||||
const [queuedDescription, setQueuedDescripion] = React.useState<string | null>(null)
|
||||
const [description, setDescription] = React.useState('')
|
||||
const [dataLinkValue, setDataLinkValue] = React.useState<NonNullable<unknown> | null>(null)
|
||||
const [editedDataLinkValue, setEditedDataLinkValue] = React.useState<NonNullable<unknown> | null>(
|
||||
dataLinkValue
|
||||
const [datalinkValue, setDatalinkValue] = React.useState<NonNullable<unknown> | null>(null)
|
||||
const [editedDatalinkValue, setEditedDatalinkValue] = React.useState<NonNullable<unknown> | null>(
|
||||
datalinkValue
|
||||
)
|
||||
const [isDataLinkFetched, setIsDataLinkFetched] = React.useState(false)
|
||||
const isDataLinkSubmittable = React.useMemo(
|
||||
() => dataLinkValidator.validateDataLink(dataLinkValue),
|
||||
[dataLinkValue]
|
||||
const [isDatalinkFetched, setIsDatalinkFetched] = React.useState(false)
|
||||
const isDatalinkSubmittable = React.useMemo(
|
||||
() => datalinkValidator.validateDatalink(datalinkValue),
|
||||
[datalinkValue]
|
||||
)
|
||||
const setItem = React.useCallback(
|
||||
(valueOrUpdater: React.SetStateAction<assetTreeNode.AnyAssetTreeNode>) => {
|
||||
@ -89,8 +89,8 @@ export default function AssetProperties(props: AssetPropertiesProps) {
|
||||
ownsThisAsset ||
|
||||
self?.permission === permissions.PermissionAction.admin ||
|
||||
self?.permission === permissions.PermissionAction.edit
|
||||
const isDataLink = item.item.type === backendModule.AssetType.dataLink
|
||||
const isDataLinkDisabled = dataLinkValue === editedDataLinkValue || !isDataLinkSubmittable
|
||||
const isDatalink = item.item.type === backendModule.AssetType.datalink
|
||||
const isDatalinkDisabled = datalinkValue === editedDatalinkValue || !isDatalinkSubmittable
|
||||
|
||||
React.useEffect(() => {
|
||||
setDescription(item.item.description ?? '')
|
||||
@ -98,11 +98,11 @@ export default function AssetProperties(props: AssetPropertiesProps) {
|
||||
|
||||
React.useEffect(() => {
|
||||
void (async () => {
|
||||
if (item.item.type === backendModule.AssetType.dataLink) {
|
||||
const value = await backend.getConnector(item.item.id, item.item.title)
|
||||
setDataLinkValue(value)
|
||||
setEditedDataLinkValue(value)
|
||||
setIsDataLinkFetched(true)
|
||||
if (item.item.type === backendModule.AssetType.datalink) {
|
||||
const value = await backend.getDatalink(item.item.id, item.item.title)
|
||||
setDatalinkValue(value)
|
||||
setEditedDatalinkValue(value)
|
||||
setIsDatalinkFetched(true)
|
||||
}
|
||||
})()
|
||||
}, [backend, item.item])
|
||||
@ -239,50 +239,50 @@ export default function AssetProperties(props: AssetPropertiesProps) {
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{isDataLink && (
|
||||
{isDatalink && (
|
||||
<div className="pointer-events-auto flex flex-col items-start gap-side-panel-section">
|
||||
<aria.Heading
|
||||
level={2}
|
||||
className="h-side-panel-heading py-side-panel-heading-y text-lg leading-snug"
|
||||
>
|
||||
{getText('dataLink')}
|
||||
{getText('datalink')}
|
||||
</aria.Heading>
|
||||
{!isDataLinkFetched ? (
|
||||
{!isDatalinkFetched ? (
|
||||
<div className="grid place-items-center self-stretch">
|
||||
<StatelessSpinner size={48} state={statelessSpinner.SpinnerState.loadingMedium} />
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<DataLinkInput
|
||||
<DatalinkInput
|
||||
readOnly={!canEditThisAsset}
|
||||
dropdownTitle="Type"
|
||||
value={editedDataLinkValue}
|
||||
setValue={setEditedDataLinkValue}
|
||||
value={editedDatalinkValue}
|
||||
setValue={setEditedDatalinkValue}
|
||||
/>
|
||||
{canEditThisAsset && (
|
||||
<div className="flex gap-buttons">
|
||||
<UnstyledButton
|
||||
isDisabled={isDataLinkDisabled}
|
||||
{...(isDataLinkDisabled
|
||||
? { title: 'Edit the Data Link before updating it.' }
|
||||
isDisabled={isDatalinkDisabled}
|
||||
{...(isDatalinkDisabled
|
||||
? { title: 'Edit the Datalink before updating it.' }
|
||||
: {})}
|
||||
className="button bg-invite text-white enabled:active"
|
||||
onPress={() => {
|
||||
void (async () => {
|
||||
if (item.item.type === backendModule.AssetType.dataLink) {
|
||||
const oldDataLinkValue = dataLinkValue
|
||||
if (item.item.type === backendModule.AssetType.datalink) {
|
||||
const oldDatalinkValue = datalinkValue
|
||||
try {
|
||||
setDataLinkValue(editedDataLinkValue)
|
||||
await backend.createConnector({
|
||||
connectorId: item.item.id,
|
||||
setDatalinkValue(editedDatalinkValue)
|
||||
await backend.createDatalink({
|
||||
datalinkId: item.item.id,
|
||||
name: item.item.title,
|
||||
parentDirectoryId: null,
|
||||
value: editedDataLinkValue,
|
||||
value: editedDatalinkValue,
|
||||
})
|
||||
} catch (error) {
|
||||
toastAndLog(null, error)
|
||||
setDataLinkValue(oldDataLinkValue)
|
||||
setEditedDataLinkValue(oldDataLinkValue)
|
||||
setDatalinkValue(oldDatalinkValue)
|
||||
setEditedDatalinkValue(oldDatalinkValue)
|
||||
}
|
||||
}
|
||||
})()
|
||||
@ -291,10 +291,10 @@ export default function AssetProperties(props: AssetPropertiesProps) {
|
||||
{getText('update')}
|
||||
</UnstyledButton>
|
||||
<UnstyledButton
|
||||
isDisabled={isDataLinkDisabled}
|
||||
isDisabled={isDatalinkDisabled}
|
||||
className="button bg-selected-frame enabled:active"
|
||||
onPress={() => {
|
||||
setEditedDataLinkValue(dataLinkValue)
|
||||
setEditedDatalinkValue(datalinkValue)
|
||||
}}
|
||||
>
|
||||
{getText('cancel')}
|
||||
|
@ -181,9 +181,9 @@ const SUGGESTIONS_FOR_NEGATIVE_TYPE: assetSearchBar.Suggestion[] = [
|
||||
deleteFromQuery: query => query.deleteFromLastTerm({ negativeTypes: ['file'] }),
|
||||
},
|
||||
{
|
||||
render: () => 'type:connector',
|
||||
addToQuery: query => query.addToLastTerm({ negativeTypes: ['connector'] }),
|
||||
deleteFromQuery: query => query.deleteFromLastTerm({ negativeTypes: ['connector'] }),
|
||||
render: () => 'type:datalink',
|
||||
addToQuery: query => query.addToLastTerm({ negativeTypes: ['datalink'] }),
|
||||
deleteFromQuery: query => query.deleteFromLastTerm({ negativeTypes: ['datalink'] }),
|
||||
},
|
||||
]
|
||||
|
||||
@ -232,7 +232,7 @@ function insertArbitraryAssetTreeNodeChildren(
|
||||
[backendModule.AssetType.directory]: [],
|
||||
[backendModule.AssetType.project]: [],
|
||||
[backendModule.AssetType.file]: [],
|
||||
[backendModule.AssetType.dataLink]: [],
|
||||
[backendModule.AssetType.datalink]: [],
|
||||
[backendModule.AssetType.secret]: [],
|
||||
[backendModule.AssetType.specialLoading]: [],
|
||||
[backendModule.AssetType.specialEmpty]: [],
|
||||
@ -449,7 +449,7 @@ export default function AssetsTable(props: AssetsTableProps) {
|
||||
const assetType =
|
||||
node.item.type === backendModule.AssetType.directory
|
||||
? 'folder'
|
||||
: node.item.type === backendModule.AssetType.dataLink
|
||||
: node.item.type === backendModule.AssetType.datalink
|
||||
? 'datalink'
|
||||
: String(node.item.type)
|
||||
const assetExtension =
|
||||
@ -918,7 +918,7 @@ export default function AssetsTable(props: AssetsTableProps) {
|
||||
return (
|
||||
node?.item.type === backendModule.AssetType.project ||
|
||||
node?.item.type === backendModule.AssetType.file ||
|
||||
node?.item.type === backendModule.AssetType.dataLink
|
||||
node?.item.type === backendModule.AssetType.datalink
|
||||
)
|
||||
})
|
||||
)
|
||||
@ -1230,7 +1230,7 @@ export default function AssetsTable(props: AssetsTableProps) {
|
||||
})
|
||||
break
|
||||
}
|
||||
case backendModule.AssetType.dataLink: {
|
||||
case backendModule.AssetType.datalink: {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
setIsAssetPanelTemporarilyVisible(true)
|
||||
@ -1653,10 +1653,10 @@ export default function AssetsTable(props: AssetsTableProps) {
|
||||
}
|
||||
break
|
||||
}
|
||||
case AssetListEventType.newDataLink: {
|
||||
const placeholderItem: backendModule.DataLinkAsset = {
|
||||
type: backendModule.AssetType.dataLink,
|
||||
id: backendModule.ConnectorId(uniqueString.uniqueString()),
|
||||
case AssetListEventType.newDatalink: {
|
||||
const placeholderItem: backendModule.DatalinkAsset = {
|
||||
type: backendModule.AssetType.datalink,
|
||||
id: backendModule.DatalinkId(uniqueString.uniqueString()),
|
||||
title: event.name,
|
||||
modifiedAt: dateTime.toRfc3339(new Date()),
|
||||
parentId: event.parentId,
|
||||
@ -1668,7 +1668,7 @@ export default function AssetsTable(props: AssetsTableProps) {
|
||||
doToggleDirectoryExpansion(event.parentId, event.parentKey, null, true)
|
||||
insertAssets([placeholderItem], event.parentKey, event.parentId)
|
||||
dispatchAssetEvent({
|
||||
type: AssetEventType.newDataLink,
|
||||
type: AssetEventType.newDatalink,
|
||||
placeholderId: placeholderItem.id,
|
||||
value: event.value,
|
||||
})
|
||||
|
@ -285,10 +285,10 @@ export default function Drive(props: DriveProps) {
|
||||
[rootDirectoryId, /* should never change */ dispatchAssetListEvent]
|
||||
)
|
||||
|
||||
const doCreateDataLink = React.useCallback(
|
||||
const doCreateDatalink = React.useCallback(
|
||||
(name: string, value: unknown) => {
|
||||
dispatchAssetListEvent({
|
||||
type: AssetListEventType.newDataLink,
|
||||
type: AssetListEventType.newDatalink,
|
||||
parentKey: targetDirectoryNodeRef.current?.key ?? rootDirectoryId,
|
||||
parentId: targetDirectoryNodeRef.current?.item.id ?? rootDirectoryId,
|
||||
name,
|
||||
@ -377,7 +377,7 @@ export default function Drive(props: DriveProps) {
|
||||
doUploadFiles={doUploadFiles}
|
||||
doCreateDirectory={doCreateDirectory}
|
||||
doCreateSecret={doCreateSecret}
|
||||
doCreateDataLink={doCreateDataLink}
|
||||
doCreateDatalink={doCreateDatalink}
|
||||
dispatchAssetEvent={dispatchAssetEvent}
|
||||
/>
|
||||
</div>
|
||||
|
@ -2,7 +2,7 @@
|
||||
* the current directory and some configuration options. */
|
||||
import * as React from 'react'
|
||||
|
||||
import AddConnectorIcon from 'enso-assets/add_connector.svg'
|
||||
import AddDatalinkIcon from 'enso-assets/add_datalink.svg'
|
||||
import AddFolderIcon from 'enso-assets/add_folder.svg'
|
||||
import AddKeyIcon from 'enso-assets/add_key.svg'
|
||||
import DataDownloadIcon from 'enso-assets/data_download.svg'
|
||||
@ -24,7 +24,7 @@ import HorizontalMenuBar from '#/components/styled/HorizontalMenuBar'
|
||||
import UnstyledButton from '#/components/UnstyledButton'
|
||||
|
||||
import ConfirmDeleteModal from '#/modals/ConfirmDeleteModal'
|
||||
import UpsertDataLinkModal from '#/modals/UpsertDataLinkModal'
|
||||
import UpsertDatalinkModal from '#/modals/UpsertDatalinkModal'
|
||||
import UpsertSecretModal from '#/modals/UpsertSecretModal'
|
||||
|
||||
import * as backendModule from '#/services/Backend'
|
||||
@ -43,7 +43,7 @@ export interface DriveBarProps {
|
||||
readonly doCreateProject: () => void
|
||||
readonly doCreateDirectory: () => void
|
||||
readonly doCreateSecret: (name: string, value: string) => void
|
||||
readonly doCreateDataLink: (name: string, value: unknown) => void
|
||||
readonly doCreateDatalink: (name: string, value: unknown) => void
|
||||
readonly doUploadFiles: (files: File[]) => void
|
||||
readonly dispatchAssetEvent: (event: assetEvent.AssetEvent) => void
|
||||
}
|
||||
@ -52,7 +52,7 @@ export interface DriveBarProps {
|
||||
* and a column display mode switcher. */
|
||||
export default function DriveBar(props: DriveBarProps) {
|
||||
const { category, canDownload, doEmptyTrash, doCreateProject, doCreateDirectory } = props
|
||||
const { doCreateSecret, doCreateDataLink, doUploadFiles, dispatchAssetEvent } = props
|
||||
const { doCreateSecret, doCreateDatalink, doUploadFiles, dispatchAssetEvent } = props
|
||||
const { backend } = backendProvider.useBackend()
|
||||
const { setModal, unsetModal } = modalProvider.useSetModal()
|
||||
const { getText } = textProvider.useText()
|
||||
@ -150,10 +150,10 @@ export default function DriveBar(props: DriveBarProps) {
|
||||
{isCloud && (
|
||||
<Button
|
||||
active
|
||||
image={AddConnectorIcon}
|
||||
alt={getText('newDataLink')}
|
||||
image={AddDatalinkIcon}
|
||||
alt={getText('newDatalink')}
|
||||
onPress={() => {
|
||||
setModal(<UpsertDataLinkModal doCreate={doCreateDataLink} />)
|
||||
setModal(<UpsertDatalinkModal doCreate={doCreateDatalink} />)
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
@ -12,7 +12,7 @@ import * as aria from '#/components/aria'
|
||||
import ContextMenu from '#/components/ContextMenu'
|
||||
import ContextMenuEntry from '#/components/ContextMenuEntry'
|
||||
|
||||
import UpsertDataLinkModal from '#/modals/UpsertDataLinkModal'
|
||||
import UpsertDatalinkModal from '#/modals/UpsertDatalinkModal'
|
||||
import UpsertSecretModal from '#/modals/UpsertSecretModal'
|
||||
|
||||
import * as backendModule from '#/services/Backend'
|
||||
@ -145,13 +145,13 @@ export default function GlobalContextMenu(props: GlobalContextMenuProps) {
|
||||
{isCloud && (
|
||||
<ContextMenuEntry
|
||||
hidden={hidden}
|
||||
action="newDataLink"
|
||||
action="newDatalink"
|
||||
doAction={() => {
|
||||
setModal(
|
||||
<UpsertDataLinkModal
|
||||
<UpsertDatalinkModal
|
||||
doCreate={(name, value) => {
|
||||
dispatchAssetListEvent({
|
||||
type: AssetListEventType.newDataLink,
|
||||
type: AssetListEventType.newDatalink,
|
||||
parentKey: directoryKey ?? rootDirectoryId,
|
||||
parentId: directoryId ?? rootDirectoryId,
|
||||
name,
|
||||
|
@ -1,14 +1,14 @@
|
||||
/** @file A modal for creating a Data Link. */
|
||||
/** @file A modal for creating a Datalink. */
|
||||
import * as React from 'react'
|
||||
|
||||
import SCHEMA from '#/data/dataLinkSchema.json' assert { type: 'json' }
|
||||
import * as dataLinkValidator from '#/data/dataLinkValidator'
|
||||
import SCHEMA from '#/data/datalinkSchema.json' assert { type: 'json' }
|
||||
import * as datalinkValidator from '#/data/datalinkValidator'
|
||||
|
||||
import * as modalProvider from '#/providers/ModalProvider'
|
||||
import * as textProvider from '#/providers/TextProvider'
|
||||
|
||||
import * as aria from '#/components/aria'
|
||||
import DataLinkInput from '#/components/dashboard/DataLinkInput'
|
||||
import DatalinkInput from '#/components/dashboard/DatalinkInput'
|
||||
import Modal from '#/components/Modal'
|
||||
import ButtonRow from '#/components/styled/ButtonRow'
|
||||
import FocusArea from '#/components/styled/FocusArea'
|
||||
@ -22,26 +22,26 @@ import * as jsonSchema from '#/utilities/jsonSchema'
|
||||
// =================
|
||||
|
||||
const DEFS: Record<string, object> = SCHEMA.$defs
|
||||
const INITIAL_DATA_LINK_VALUE =
|
||||
const INITIAL_DATALINK_VALUE =
|
||||
jsonSchema.constantValue(DEFS, SCHEMA.$defs.DataLink, true)[0] ?? null
|
||||
|
||||
// ===========================
|
||||
// === UpsertDataLinkModal ===
|
||||
// ===========================
|
||||
|
||||
/** Props for a {@link UpsertDataLinkModal}. */
|
||||
export interface UpsertDataLinkModalProps {
|
||||
readonly doCreate: (name: string, dataLink: unknown) => void
|
||||
/** Props for a {@link UpsertDatalinkModal}. */
|
||||
export interface UpsertDatalinkModalProps {
|
||||
readonly doCreate: (name: string, datalink: unknown) => void
|
||||
}
|
||||
|
||||
/** A modal for creating a Data Link. */
|
||||
export default function UpsertDataLinkModal(props: UpsertDataLinkModalProps) {
|
||||
/** A modal for creating a Datalink. */
|
||||
export default function UpsertDatalinkModal(props: UpsertDatalinkModalProps) {
|
||||
const { doCreate } = props
|
||||
const { unsetModal } = modalProvider.useSetModal()
|
||||
const { getText } = textProvider.useText()
|
||||
const [name, setName] = React.useState('')
|
||||
const [value, setValue] = React.useState<NonNullable<unknown> | null>(INITIAL_DATA_LINK_VALUE)
|
||||
const isValueSubmittable = React.useMemo(() => dataLinkValidator.validateDataLink(value), [value])
|
||||
const [value, setValue] = React.useState<NonNullable<unknown> | null>(INITIAL_DATALINK_VALUE)
|
||||
const isValueSubmittable = React.useMemo(() => datalinkValidator.validateDatalink(value), [value])
|
||||
const isSubmittable = name !== '' && isValueSubmittable
|
||||
|
||||
const doSubmit = () => {
|
||||
@ -62,7 +62,7 @@ export default function UpsertDataLinkModal(props: UpsertDataLinkModalProps) {
|
||||
}}
|
||||
>
|
||||
<aria.Heading className="relative text-sm font-semibold">
|
||||
{getText('createDataLink')}
|
||||
{getText('createDatalink')}
|
||||
</aria.Heading>
|
||||
<FocusArea direction="horizontal">
|
||||
{innerProps => (
|
||||
@ -75,7 +75,7 @@ export default function UpsertDataLinkModal(props: UpsertDataLinkModalProps) {
|
||||
<FocusRing>
|
||||
<aria.Input
|
||||
autoFocus
|
||||
placeholder={getText('dataLinkNamePlaceholder')}
|
||||
placeholder={getText('datalinkNamePlaceholder')}
|
||||
className={`focus-child text grow rounded-full border bg-transparent px-input-x ${
|
||||
name !== '' ? 'border-primary/10' : 'border-red-700/60'
|
||||
}`}
|
||||
@ -89,7 +89,7 @@ export default function UpsertDataLinkModal(props: UpsertDataLinkModalProps) {
|
||||
)}
|
||||
</FocusArea>
|
||||
<div className="relative">
|
||||
<DataLinkInput dropdownTitle="Type" value={value} setValue={setValue} />
|
||||
<DatalinkInput dropdownTitle="Type" value={value} setValue={setValue} />
|
||||
</div>
|
||||
<ButtonRow>
|
||||
<UnstyledButton
|
@ -51,9 +51,9 @@ export const FileId = newtype.newtypeConstructor<FileId>()
|
||||
export type SecretId = newtype.Newtype<string, 'SecretId'>
|
||||
export const SecretId = newtype.newtypeConstructor<SecretId>()
|
||||
|
||||
/** Unique identifier for a Data Link. */
|
||||
export type ConnectorId = newtype.Newtype<string, 'ConnectorId'>
|
||||
export const ConnectorId = newtype.newtypeConstructor<ConnectorId>()
|
||||
/** Unique identifier for a Datalink. */
|
||||
export type DatalinkId = newtype.Newtype<string, 'DatalinkId'>
|
||||
export const DatalinkId = newtype.newtypeConstructor<DatalinkId>()
|
||||
|
||||
/** Unique identifier for an arbitrary asset. */
|
||||
export type AssetId = IdType[keyof IdType]
|
||||
@ -340,12 +340,12 @@ export interface SecretInfo {
|
||||
readonly path: string
|
||||
}
|
||||
|
||||
/** A Data Link. */
|
||||
export type Connector = newtype.Newtype<unknown, 'Connector'>
|
||||
/** A Datalink. */
|
||||
export type Datalink = newtype.Newtype<unknown, 'Datalink'>
|
||||
|
||||
/** Metadata uniquely identifying a Data Link. */
|
||||
export interface ConnectorInfo {
|
||||
readonly id: ConnectorId
|
||||
/** Metadata uniquely identifying a Datalink. */
|
||||
export interface DatalinkInfo {
|
||||
readonly id: DatalinkId
|
||||
}
|
||||
|
||||
/** A label. */
|
||||
@ -655,7 +655,7 @@ export enum AssetType {
|
||||
project = 'project',
|
||||
file = 'file',
|
||||
secret = 'secret',
|
||||
dataLink = 'connector',
|
||||
datalink = 'datalink',
|
||||
directory = 'directory',
|
||||
/** A special {@link AssetType} representing the unknown items of a directory, before the
|
||||
* request to retrieve the items completes. */
|
||||
@ -668,7 +668,7 @@ export enum AssetType {
|
||||
export interface IdType {
|
||||
readonly [AssetType.project]: ProjectId
|
||||
readonly [AssetType.file]: FileId
|
||||
readonly [AssetType.dataLink]: ConnectorId
|
||||
readonly [AssetType.datalink]: DatalinkId
|
||||
readonly [AssetType.secret]: SecretId
|
||||
readonly [AssetType.directory]: DirectoryId
|
||||
readonly [AssetType.specialLoading]: LoadingAssetId
|
||||
@ -684,7 +684,7 @@ export const ASSET_TYPE_ORDER: Readonly<Record<AssetType, number>> = {
|
||||
[AssetType.directory]: 0,
|
||||
[AssetType.project]: 1,
|
||||
[AssetType.file]: 2,
|
||||
[AssetType.dataLink]: 3,
|
||||
[AssetType.datalink]: 3,
|
||||
[AssetType.secret]: 4,
|
||||
[AssetType.specialLoading]: 999,
|
||||
[AssetType.specialEmpty]: 1000,
|
||||
@ -726,8 +726,8 @@ export interface ProjectAsset extends Asset<AssetType.project> {}
|
||||
/** A convenience alias for {@link Asset}<{@link AssetType.file}>. */
|
||||
export interface FileAsset extends Asset<AssetType.file> {}
|
||||
|
||||
/** A convenience alias for {@link Asset}<{@link AssetType.dataLink}>. */
|
||||
export interface DataLinkAsset extends Asset<AssetType.dataLink> {}
|
||||
/** A convenience alias for {@link Asset}<{@link AssetType.datalink}>. */
|
||||
export interface DatalinkAsset extends Asset<AssetType.datalink> {}
|
||||
|
||||
/** A convenience alias for {@link Asset}<{@link AssetType.secret}>. */
|
||||
export interface SecretAsset extends Asset<AssetType.secret> {}
|
||||
@ -838,7 +838,7 @@ interface HasType<Type extends AssetType> {
|
||||
|
||||
/** A union of all possible {@link Asset} variants. */
|
||||
export type AnyAsset<Type extends AssetType = AssetType> = Extract<
|
||||
| DataLinkAsset
|
||||
| DatalinkAsset
|
||||
| DirectoryAsset
|
||||
| FileAsset
|
||||
| ProjectAsset
|
||||
@ -875,8 +875,8 @@ export function createPlaceholderAssetId<Type extends AssetType>(
|
||||
result = FileId(id)
|
||||
break
|
||||
}
|
||||
case AssetType.dataLink: {
|
||||
result = ConnectorId(id)
|
||||
case AssetType.datalink: {
|
||||
result = DatalinkId(id)
|
||||
break
|
||||
}
|
||||
case AssetType.secret: {
|
||||
@ -903,8 +903,8 @@ export function createPlaceholderAssetId<Type extends AssetType>(
|
||||
export const assetIsProject = assetIsType(AssetType.project)
|
||||
/** A type guard that returns whether an {@link Asset} is a {@link DirectoryAsset}. */
|
||||
export const assetIsDirectory = assetIsType(AssetType.directory)
|
||||
/** A type guard that returns whether an {@link Asset} is a {@link DataLinkAsset}. */
|
||||
export const assetIsDataLink = assetIsType(AssetType.dataLink)
|
||||
/** A type guard that returns whether an {@link Asset} is a {@link DatalinkAsset}. */
|
||||
export const assetIsDatalink = assetIsType(AssetType.datalink)
|
||||
/** A type guard that returns whether an {@link Asset} is a {@link SecretAsset}. */
|
||||
export const assetIsSecret = assetIsType(AssetType.secret)
|
||||
/** A type guard that returns whether an {@link Asset} is a {@link FileAsset}. */
|
||||
@ -1034,7 +1034,7 @@ export interface CreateProjectRequestBody {
|
||||
readonly projectName: string
|
||||
readonly projectTemplateName?: string
|
||||
readonly parentDirectoryId?: DirectoryId
|
||||
readonly datalinkId?: ConnectorId
|
||||
readonly datalinkId?: DatalinkId
|
||||
}
|
||||
|
||||
/** HTTP request body for the "update project" endpoint.
|
||||
@ -1068,12 +1068,12 @@ export interface UpdateSecretRequestBody {
|
||||
readonly value: string
|
||||
}
|
||||
|
||||
/** HTTP request body for the "create connector" endpoint. */
|
||||
export interface CreateConnectorRequestBody {
|
||||
/** HTTP request body for the "create datalink" endpoint. */
|
||||
export interface CreateDatalinkRequestBody {
|
||||
readonly name: string
|
||||
readonly value: unknown
|
||||
readonly parentDirectoryId: DirectoryId | null
|
||||
readonly connectorId: ConnectorId | null
|
||||
readonly datalinkId: DatalinkId | null
|
||||
}
|
||||
|
||||
/** HTTP request body for the "create tag" endpoint. */
|
||||
@ -1320,12 +1320,12 @@ export default abstract class Backend {
|
||||
abstract updateFile(fileId: FileId, body: UpdateFileRequestBody, title: string): Promise<void>
|
||||
/** Return file details. */
|
||||
abstract getFileDetails(fileId: FileId, title: string): Promise<FileDetails>
|
||||
/** Create a Data Link. */
|
||||
abstract createConnector(body: CreateConnectorRequestBody): Promise<ConnectorInfo>
|
||||
/** Return a Data Link. */
|
||||
abstract getConnector(connectorId: ConnectorId, title: string | null): Promise<Connector>
|
||||
/** Delete a Data Link. */
|
||||
abstract deleteConnector(connectorId: ConnectorId, title: string | null): Promise<void>
|
||||
/** Create a Datalink. */
|
||||
abstract createDatalink(body: CreateDatalinkRequestBody): Promise<DatalinkInfo>
|
||||
/** Return a Datalink. */
|
||||
abstract getDatalink(datalinkId: DatalinkId, title: string | null): Promise<Datalink>
|
||||
/** Delete a Datalink. */
|
||||
abstract deleteDatalink(datalinkId: DatalinkId, title: string | null): Promise<void>
|
||||
/** Create a secret environment variable. */
|
||||
abstract createSecret(body: CreateSecretRequestBody): Promise<SecretId>
|
||||
/** Return a secret environment variable. */
|
||||
|
@ -621,17 +621,17 @@ export default class LocalBackend extends Backend {
|
||||
}
|
||||
|
||||
/** Invalid operation. */
|
||||
override createConnector() {
|
||||
override createDatalink() {
|
||||
return this.invalidOperation()
|
||||
}
|
||||
|
||||
/** Invalid operation. */
|
||||
override getConnector() {
|
||||
override getDatalink() {
|
||||
return this.invalidOperation()
|
||||
}
|
||||
|
||||
/** Invalid operation. */
|
||||
override deleteConnector() {
|
||||
override deleteDatalink() {
|
||||
return this.invalidOperation()
|
||||
}
|
||||
|
||||
|
@ -732,42 +732,42 @@ export default class RemoteBackend extends Backend {
|
||||
}
|
||||
}
|
||||
|
||||
/** Return a Data Link.
|
||||
/** Return a Datalink.
|
||||
* @throws An error if a non-successful status code (not 200-299) was received. */
|
||||
override async createConnector(
|
||||
body: backend.CreateConnectorRequestBody
|
||||
): Promise<backend.ConnectorInfo> {
|
||||
const path = remoteBackendPaths.CREATE_CONNECTOR_PATH
|
||||
const response = await this.post<backend.ConnectorInfo>(path, body)
|
||||
override async createDatalink(
|
||||
body: backend.CreateDatalinkRequestBody
|
||||
): Promise<backend.DatalinkInfo> {
|
||||
const path = remoteBackendPaths.CREATE_DATALINK_PATH
|
||||
const response = await this.post<backend.DatalinkInfo>(path, body)
|
||||
if (!responseIsSuccessful(response)) {
|
||||
return await this.throw(response, 'createConnectorBackendError', body.name)
|
||||
return await this.throw(response, 'createDatalinkBackendError', body.name)
|
||||
} else {
|
||||
return await response.json()
|
||||
}
|
||||
}
|
||||
|
||||
/** Return a Data Link.
|
||||
/** Return a Datalink.
|
||||
* @throws An error if a non-successful status code (not 200-299) was received. */
|
||||
override async getConnector(
|
||||
connectorId: backend.ConnectorId,
|
||||
override async getDatalink(
|
||||
datalinkId: backend.DatalinkId,
|
||||
title: string
|
||||
): Promise<backend.Connector> {
|
||||
const path = remoteBackendPaths.getConnectorPath(connectorId)
|
||||
const response = await this.get<backend.Connector>(path)
|
||||
): Promise<backend.Datalink> {
|
||||
const path = remoteBackendPaths.getDatalinkPath(datalinkId)
|
||||
const response = await this.get<backend.Datalink>(path)
|
||||
if (!responseIsSuccessful(response)) {
|
||||
return await this.throw(response, 'getConnectorBackendError', title)
|
||||
return await this.throw(response, 'getDatalinkBackendError', title)
|
||||
} else {
|
||||
return await response.json()
|
||||
}
|
||||
}
|
||||
|
||||
/** Delete a Data Link.
|
||||
/** Delete a Datalink.
|
||||
* @throws An error if a non-successful status code (not 200-299) was received. */
|
||||
override async deleteConnector(connectorId: backend.ConnectorId, title: string): Promise<void> {
|
||||
const path = remoteBackendPaths.getConnectorPath(connectorId)
|
||||
override async deleteDatalink(datalinkId: backend.DatalinkId, title: string): Promise<void> {
|
||||
const path = remoteBackendPaths.getDatalinkPath(datalinkId)
|
||||
const response = await this.delete(path)
|
||||
if (!responseIsSuccessful(response)) {
|
||||
return await this.throw(response, 'deleteConnectorBackendError', title)
|
||||
return await this.throw(response, 'deleteDatalinkBackendError', title)
|
||||
} else {
|
||||
return
|
||||
}
|
||||
|
@ -47,8 +47,8 @@ export const UPLOAD_FILE_PATH = 'files'
|
||||
export const CREATE_SECRET_PATH = 'secrets'
|
||||
/** Relative HTTP path to the "list secrets" endpoint of the Cloud backend API. */
|
||||
export const LIST_SECRETS_PATH = 'secrets'
|
||||
/** Relative HTTP path to the "create connector" endpoint of the Cloud backend API. */
|
||||
export const CREATE_CONNECTOR_PATH = 'connectors'
|
||||
/** Relative HTTP path to the "create datalink" endpoint of the Cloud backend API. */
|
||||
export const CREATE_DATALINK_PATH = 'datalinks'
|
||||
/** Relative HTTP path to the "create tag" endpoint of the Cloud backend API. */
|
||||
export const CREATE_TAG_PATH = 'tags'
|
||||
/** Relative HTTP path to the "list tags" endpoint of the Cloud backend API. */
|
||||
@ -125,9 +125,9 @@ export function updateSecretPath(secretId: backend.SecretId) {
|
||||
export function getSecretPath(secretId: backend.SecretId) {
|
||||
return `secrets/${secretId}`
|
||||
}
|
||||
/** Relative HTTP path to the "get connector" endpoint of the Cloud backend API. */
|
||||
export function getConnectorPath(connectorId: backend.ConnectorId) {
|
||||
return `connectors/${connectorId}`
|
||||
/** Relative HTTP path to the "get datalink" endpoint of the Cloud backend API. */
|
||||
export function getDatalinkPath(datalinkId: backend.DatalinkId) {
|
||||
return `datalinks/${datalinkId}`
|
||||
}
|
||||
/** Relative HTTP path to the "associate tag" endpoint of the Cloud backend API. */
|
||||
export function associateTagPath(assetId: backend.AssetId) {
|
||||
|
@ -96,7 +96,7 @@
|
||||
--context-menu-macos-width: 14.375rem;
|
||||
--context-menu-entry-padding-x: 0.75rem;
|
||||
--separator-margin-y: 0.125rem;
|
||||
/* The vertical gap between entries in a Data Link input. */
|
||||
/* The vertical gap between entries in a Datalink input. */
|
||||
--json-schema-gap: 0.25rem;
|
||||
--json-schema-text-input-width: 10rem;
|
||||
--json-schema-object-input-padding: 0.5rem;
|
||||
|
@ -2,7 +2,7 @@
|
||||
"submit": "Submit",
|
||||
"createFolderError": "Could not create new folder",
|
||||
"createProjectError": "Could not create new project",
|
||||
"createDataLinkError": "Could not create new Data Link",
|
||||
"createDatalinkError": "Could not create new Datalink",
|
||||
"createSecretError": "Could not create new secret",
|
||||
"renameFolderError": "Could not rename folder",
|
||||
"renameProjectError": "Could not rename project",
|
||||
@ -15,7 +15,7 @@
|
||||
"deleteAssetError": "Could not delete '$0'",
|
||||
"restoreAssetError": "Could not restore '$0'",
|
||||
|
||||
"localBackendDataLinkError": "Cannot create Data Links on the local drive",
|
||||
"localBackendDatalinkError": "Cannot create Datalinks on the local drive",
|
||||
"localBackendSecretError": "Cannot create secrets on the local drive",
|
||||
"offlineUploadFilesError": "Cannot upload files when offline",
|
||||
|
||||
@ -30,10 +30,10 @@
|
||||
"editDescriptionError": "Could not edit description",
|
||||
"canOnlyDownloadFilesError": "You currently can only download files.",
|
||||
"noProjectSelectedError": "First select a project to download.",
|
||||
"downloadInvalidTypeError": "You can only download files, projects, and Data Links",
|
||||
"downloadInvalidTypeError": "You can only download files, projects, and Datalinks",
|
||||
"downloadProjectError": "Could not download project '$0'",
|
||||
"downloadFileError": "Could not download file '$0'",
|
||||
"downloadDataLinkError": "Could not download Data Link '$0'",
|
||||
"downloadDatalinkError": "Could not download Datalink '$0'",
|
||||
"downloadSelectedFilesError": "Could not download selected files",
|
||||
"openEditorError": "Could not open editor",
|
||||
"setPermissionsError": "Could not set permissions",
|
||||
@ -109,9 +109,9 @@
|
||||
"uploadFileWithNameBackendError": "Could not upload file '$0'.",
|
||||
"getFileDetailsBackendError": "Could not get details of project '$0'.",
|
||||
"createSecretBackendError": "Could not create secret with name '$0'.",
|
||||
"createConnectorBackendError": "Could not create Data Link with name '$0'.",
|
||||
"getConnectorBackendError": "Could not get Data Link '$0'.",
|
||||
"deleteConnectorBackendError": "Could not delete Data Link '$0'.",
|
||||
"createDatalinkBackendError": "Could not create Datalink with name '$0'.",
|
||||
"getDatalinkBackendError": "Could not get Datalink '$0'.",
|
||||
"deleteDatalinkBackendError": "Could not delete Datalink '$0'.",
|
||||
"getSecretBackendError": "Could not get secret '$0'.",
|
||||
"updateSecretBackendError": "Could not update secret '$0'.",
|
||||
"listSecretsBackendError": "Could not list secrets.",
|
||||
@ -132,7 +132,7 @@
|
||||
"directoryAssetType": "folder",
|
||||
"projectAssetType": "project",
|
||||
"fileAssetType": "file",
|
||||
"connectorAssetType": "Data Link",
|
||||
"datalinkAssetType": "Datalink",
|
||||
"secretAssetType": "secret",
|
||||
"specialLoadingAssetType": "special loading asset",
|
||||
"specialEmptyAssetType": "special empty asset",
|
||||
@ -187,8 +187,8 @@
|
||||
"settingsFor": "Settings for ",
|
||||
"inviteMembers": "Invite Members",
|
||||
"versions": "Versions",
|
||||
"dataLink": "Data Link",
|
||||
"createDataLink": "Create Data Link",
|
||||
"datalink": "Datalink",
|
||||
"createDatalink": "Create Datalink",
|
||||
"resetAll": "Reset All",
|
||||
|
||||
"openHelpChat": "Open Help Chat",
|
||||
@ -242,7 +242,7 @@
|
||||
"newProject": "New Project",
|
||||
"uploadFiles": "Import",
|
||||
"downloadFiles": "Export",
|
||||
"newDataLink": "New Data Link",
|
||||
"newDatalink": "New Datalink",
|
||||
"newSecret": "New Secret",
|
||||
"newLabel": "New Label",
|
||||
|
||||
@ -326,7 +326,7 @@
|
||||
"clickForNewQuestion": "New question? Click to start a new thread!",
|
||||
"upgradeToProNag": "Click here to upgrade to Enso Pro and get access to high-priority, live support!",
|
||||
"projectNameCannotBeEmpty": "Project name cannot be empty.",
|
||||
"remoteBackendSearchPlaceholder": "Type to search for projects, Data Links, users, and more.",
|
||||
"remoteBackendSearchPlaceholder": "Type to search for projects, Datalinks, users, and more.",
|
||||
"localBackendSearchPlaceholder": "Type to search for projects.",
|
||||
"canOnlyEmptyTrashWhenInTrash": "Can only empty trash when in Trash",
|
||||
"upgradeTo": "Upgrade to $0",
|
||||
@ -361,7 +361,7 @@
|
||||
"secretValueHidden": "●●●●●●●●",
|
||||
"secretNamePlaceholder": "Enter the name of the secret",
|
||||
"secretValuePlaceholder": "Enter the value of the secret",
|
||||
"dataLinkNamePlaceholder": "Enter the name of the Data Link",
|
||||
"datalinkNamePlaceholder": "Enter the name of the Datalink",
|
||||
"labelNamePlaceholder": "Enter the name of the label",
|
||||
"labelSearchPlaceholder": "Type labels to search",
|
||||
"inviteUserPlaceholder": "Type usernames or emails to search or invite",
|
||||
@ -421,15 +421,15 @@
|
||||
"soloPlanName": "Solo",
|
||||
"soloPlanSubtitle": "For individuals",
|
||||
"soloPlanPricing": "$60 per user / month",
|
||||
"soloPlanFeatures": "10GB Cloud Storage; 1 User; Data Links; Version Control for files and workflows; Enso Copilot",
|
||||
"soloPlanFeatures": "10GB Cloud Storage; 1 User; Datalinks; Version Control for files and workflows; Enso Copilot",
|
||||
"teamPlanName": "Team",
|
||||
"teamPlanSubtitle": "For small teams",
|
||||
"teamPlanPricing": "$150 per user / month",
|
||||
"teamPlanFeatures": "100GB Cloud Storage; Up to 10 users sharing; Data Links; Version Control for files and workflows; Enso Copilot; Multiple Lifecycle Environments",
|
||||
"teamPlanFeatures": "100GB Cloud Storage; Up to 10 users sharing; Datalinks; Version Control for files and workflows; Enso Copilot; Multiple Lifecycle Environments",
|
||||
"enterprisePlanName": "Organization",
|
||||
"enterprisePlanSubtitle": "For large organizations",
|
||||
"enterprisePlanPricing": "Contact Sales",
|
||||
"enterprisePlanFeatures": "1000+GB Cloud Storage; Unlimited users sharing; Data Links; Version Control for files and workflows; Enso Copilot; Multiple Lifecycle Environments; Data access and modification logs; Priority Support; Fine-grained files and workflows permissions; Federated Log On",
|
||||
"enterprisePlanFeatures": "1000+GB Cloud Storage; Unlimited users sharing; Datalinks; Version Control for files and workflows; Enso Copilot; Multiple Lifecycle Environments; Data access and modification logs; Priority Support; Fine-grained files and workflows permissions; Federated Log On",
|
||||
"subscribe": "Subscribe",
|
||||
"learnMore": "Learn More",
|
||||
"returnToDashboard": "Return to Dashboard",
|
||||
@ -482,7 +482,7 @@
|
||||
"uploadFilesShortcut": "Upload Files",
|
||||
"newProjectShortcut": "New Project",
|
||||
"newFolderShortcut": "New Folder",
|
||||
"newDataLinkShortcut": "New Data Link",
|
||||
"newDatalinkShortcut": "New Datalink",
|
||||
"newSecretShortcut": "New Secret",
|
||||
"useInNewProjectShortcut": "Use In New Project",
|
||||
"closeModalShortcut": "Close",
|
||||
|
@ -59,7 +59,7 @@ interface PlaceholderOverrides {
|
||||
readonly enterTheNewKeyboardShortcutFor: [actionName: string]
|
||||
readonly downloadProjectError: [projectName: string]
|
||||
readonly downloadFileError: [fileName: string]
|
||||
readonly downloadDataLinkError: [dataLinkName: string]
|
||||
readonly downloadDatalinkError: [datalinkName: string]
|
||||
readonly deleteUserGroupError: [userGroupName: string]
|
||||
readonly removeUserFromUserGroupError: [userName: string, userGroupName: string]
|
||||
readonly deleteUserError: [userName: string]
|
||||
@ -84,9 +84,9 @@ interface PlaceholderOverrides {
|
||||
readonly checkResourcesBackendError: [string]
|
||||
readonly uploadFileWithNameBackendError: [string]
|
||||
readonly getFileDetailsBackendError: [string]
|
||||
readonly createConnectorBackendError: [string]
|
||||
readonly getConnectorBackendError: [string]
|
||||
readonly deleteConnectorBackendError: [string]
|
||||
readonly createDatalinkBackendError: [string]
|
||||
readonly getDatalinkBackendError: [string]
|
||||
readonly deleteDatalinkBackendError: [string]
|
||||
readonly createSecretBackendError: [string]
|
||||
readonly getSecretBackendError: [string]
|
||||
readonly updateSecretBackendError: [string]
|
||||
|
@ -9,7 +9,7 @@ import * as appConfig from 'enso-common/src/appConfig'
|
||||
|
||||
appConfig.loadTestEnvironmentVariables()
|
||||
// @ts-expect-error This is required, otherwise importing node modules is broken.
|
||||
// This is required for `dataLinkSchema.test.ts`.
|
||||
// This is required for `datalinkSchema.test.ts`.
|
||||
process.env.NODE_ENV = 'development'
|
||||
|
||||
const VITE_CONFIG = (await import('./vite.config')).default
|
||||
|
Loading…
Reference in New Issue
Block a user