mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-04-23 17:18:32 +02:00
Fixes for last commit
This commit is contained in:
@@ -38,14 +38,12 @@ impl<'a> DbContext<'a> {
|
|||||||
let mut stmt = self.conn.prepare(sql.as_str()).expect("Failed to prepare query");
|
let mut stmt = self.conn.prepare(sql.as_str()).expect("Failed to prepare query");
|
||||||
match stmt.query_row(&*params.as_params(), M::from_row) {
|
match stmt.query_row(&*params.as_params(), M::from_row) {
|
||||||
Ok(result) => Ok(result),
|
Ok(result) => Ok(result),
|
||||||
Err(rusqlite::Error::QueryReturnedNoRows) => {
|
Err(rusqlite::Error::QueryReturnedNoRows) => Err(ModelNotFound(format!(
|
||||||
Err(ModelNotFound(format!(
|
r#"table "{}" {} == {}"#,
|
||||||
r#"table "{}" {} == {}"#,
|
M::table_name().into_iden().to_string(),
|
||||||
M::table_name().into_iden().to_string(),
|
col.into_iden().to_string(),
|
||||||
col.into_iden().to_string(),
|
value_debug
|
||||||
value_debug
|
))),
|
||||||
)))
|
|
||||||
}
|
|
||||||
Err(e) => Err(crate::error::Error::SqlError(e)),
|
Err(e) => Err(crate::error::Error::SqlError(e)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,7 +67,7 @@ impl<'a> DbContext<'a> {
|
|||||||
.expect("Failed to run find on DB")
|
.expect("Failed to run find on DB")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_all<'s, M>(&self) -> crate::error::Result<Vec<M>>
|
pub fn find_all<'s, M>(&self) -> Result<Vec<M>>
|
||||||
where
|
where
|
||||||
M: Into<AnyModel> + Clone + UpsertModelInfo,
|
M: Into<AnyModel> + Clone + UpsertModelInfo,
|
||||||
{
|
{
|
||||||
@@ -117,7 +115,7 @@ impl<'a> DbContext<'a> {
|
|||||||
Ok(items.map(|v| v.unwrap()).collect())
|
Ok(items.map(|v| v.unwrap()).collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn upsert<M>(&self, model: &M, source: &UpdateSource) -> crate::error::Result<M>
|
pub fn upsert<M>(&self, model: &M, source: &UpdateSource) -> Result<M>
|
||||||
where
|
where
|
||||||
M: Into<AnyModel> + From<AnyModel> + UpsertModelInfo + Clone,
|
M: Into<AnyModel> + From<AnyModel> + UpsertModelInfo + Clone,
|
||||||
{
|
{
|
||||||
@@ -139,7 +137,7 @@ impl<'a> DbContext<'a> {
|
|||||||
other_values: Vec<(impl IntoIden + Eq, impl Into<SimpleExpr>)>,
|
other_values: Vec<(impl IntoIden + Eq, impl Into<SimpleExpr>)>,
|
||||||
update_columns: Vec<impl IntoIden>,
|
update_columns: Vec<impl IntoIden>,
|
||||||
source: &UpdateSource,
|
source: &UpdateSource,
|
||||||
) -> crate::error::Result<M>
|
) -> Result<M>
|
||||||
where
|
where
|
||||||
M: Into<AnyModel> + From<AnyModel> + UpsertModelInfo + Clone,
|
M: Into<AnyModel> + From<AnyModel> + UpsertModelInfo + Clone,
|
||||||
{
|
{
|
||||||
@@ -178,7 +176,7 @@ impl<'a> DbContext<'a> {
|
|||||||
Ok(m)
|
Ok(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn delete<'s, M>(&self, m: &M, source: &UpdateSource) -> crate::error::Result<M>
|
pub(crate) fn delete<'s, M>(&self, m: &M, source: &UpdateSource) -> Result<M>
|
||||||
where
|
where
|
||||||
M: Into<AnyModel> + Clone + UpsertModelInfo,
|
M: Into<AnyModel> + Clone + UpsertModelInfo,
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
import type { Environment, EnvironmentVariable, Workspace } from '@yaakapp-internal/models';
|
import type { Environment, Workspace } from '@yaakapp-internal/models';
|
||||||
import { duplicateModel, patchModel } from '@yaakapp-internal/models';
|
import { duplicateModel, patchModel } from '@yaakapp-internal/models';
|
||||||
import { atom, useAtomValue } from 'jotai';
|
import { atom, useAtomValue } from 'jotai';
|
||||||
import React, { useCallback, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
import React, { useCallback, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { createSubEnvironmentAndActivate } from '../commands/createEnvironment';
|
import { createSubEnvironmentAndActivate } from '../commands/createEnvironment';
|
||||||
import { activeWorkspaceAtom, activeWorkspaceIdAtom } from '../hooks/useActiveWorkspace';
|
import { activeWorkspaceAtom, activeWorkspaceIdAtom } from '../hooks/useActiveWorkspace';
|
||||||
import { environmentsBreakdownAtom, useEnvironmentsBreakdown, } from '../hooks/useEnvironmentsBreakdown';
|
import {
|
||||||
|
environmentsBreakdownAtom,
|
||||||
|
useEnvironmentsBreakdown,
|
||||||
|
} from '../hooks/useEnvironmentsBreakdown';
|
||||||
import { deleteModelWithConfirm } from '../lib/deleteModelWithConfirm';
|
import { deleteModelWithConfirm } from '../lib/deleteModelWithConfirm';
|
||||||
import { jotaiStore } from '../lib/jotai';
|
import { jotaiStore } from '../lib/jotai';
|
||||||
import { isBaseEnvironment } from '../lib/model_util';
|
import { isBaseEnvironment } from '../lib/model_util';
|
||||||
@@ -16,6 +19,7 @@ import { Icon } from './core/Icon';
|
|||||||
import { IconButton } from './core/IconButton';
|
import { IconButton } from './core/IconButton';
|
||||||
import { IconTooltip } from './core/IconTooltip';
|
import { IconTooltip } from './core/IconTooltip';
|
||||||
import { InlineCode } from './core/InlineCode';
|
import { InlineCode } from './core/InlineCode';
|
||||||
|
import type { PairEditorHandle } from './core/PairEditor';
|
||||||
import { SplitLayout } from './core/SplitLayout';
|
import { SplitLayout } from './core/SplitLayout';
|
||||||
import type { TreeNode } from './core/tree/common';
|
import type { TreeNode } from './core/tree/common';
|
||||||
import type { TreeHandle, TreeProps } from './core/tree/Tree';
|
import type { TreeHandle, TreeProps } from './core/tree/Tree';
|
||||||
@@ -26,12 +30,12 @@ import { EnvironmentSharableTooltip } from './EnvironmentSharableTooltip';
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
initialEnvironmentId: string | null;
|
initialEnvironmentId: string | null;
|
||||||
addOrFocusVariable?: EnvironmentVariable;
|
setRef?: (ref: PairEditorHandle | null) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
type TreeModel = Environment | Workspace;
|
type TreeModel = Environment | Workspace;
|
||||||
|
|
||||||
export function EnvironmentEditDialog({ initialEnvironmentId, addOrFocusVariable }: Props) {
|
export function EnvironmentEditDialog({ initialEnvironmentId, setRef }: Props) {
|
||||||
const { allEnvironments, baseEnvironment, baseEnvironments } = useEnvironmentsBreakdown();
|
const { allEnvironments, baseEnvironment, baseEnvironments } = useEnvironmentsBreakdown();
|
||||||
const [selectedEnvironmentId, setSelectedEnvironmentId] = useState<string | null>(
|
const [selectedEnvironmentId, setSelectedEnvironmentId] = useState<string | null>(
|
||||||
initialEnvironmentId ?? null,
|
initialEnvironmentId ?? null,
|
||||||
@@ -75,9 +79,9 @@ export function EnvironmentEditDialog({ initialEnvironmentId, addOrFocusVariable
|
|||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<EnvironmentEditor
|
<EnvironmentEditor
|
||||||
|
setRef={setRef}
|
||||||
className="pl-4 pt-3"
|
className="pl-4 pt-3"
|
||||||
environment={selectedEnvironment}
|
environment={selectedEnvironment}
|
||||||
addOrFocusVariable={addOrFocusVariable}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Environment, EnvironmentVariable } from '@yaakapp-internal/models';
|
import type { Environment } from '@yaakapp-internal/models';
|
||||||
import { patchModel } from '@yaakapp-internal/models';
|
import { patchModel } from '@yaakapp-internal/models';
|
||||||
import type { GenericCompletionOption } from '@yaakapp-internal/plugins';
|
import type { GenericCompletionOption } from '@yaakapp-internal/plugins';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
@@ -17,7 +17,7 @@ import { BadgeButton } from './core/BadgeButton';
|
|||||||
import { DismissibleBanner } from './core/DismissibleBanner';
|
import { DismissibleBanner } from './core/DismissibleBanner';
|
||||||
import type { GenericCompletionConfig } from './core/Editor/genericCompletion';
|
import type { GenericCompletionConfig } from './core/Editor/genericCompletion';
|
||||||
import { Heading } from './core/Heading';
|
import { Heading } from './core/Heading';
|
||||||
import type { Pair, PairEditorHandle, PairWithId } from './core/PairEditor';
|
import type { PairEditorHandle, PairWithId } from './core/PairEditor';
|
||||||
import { ensurePairId } from './core/PairEditor.util';
|
import { ensurePairId } from './core/PairEditor.util';
|
||||||
import { PairOrBulkEditor } from './core/PairOrBulkEditor';
|
import { PairOrBulkEditor } from './core/PairOrBulkEditor';
|
||||||
import { EnvironmentColorIndicator } from './EnvironmentColorIndicator';
|
import { EnvironmentColorIndicator } from './EnvironmentColorIndicator';
|
||||||
@@ -27,10 +27,10 @@ interface Props {
|
|||||||
environment: Environment;
|
environment: Environment;
|
||||||
hideName?: boolean;
|
hideName?: boolean;
|
||||||
className?: string;
|
className?: string;
|
||||||
addOrFocusVariable?: EnvironmentVariable;
|
setRef?: (n: PairEditorHandle | null) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function EnvironmentEditor({ environment, hideName, className, addOrFocusVariable }: Props) {
|
export function EnvironmentEditor({ environment, hideName, className, setRef }: Props) {
|
||||||
const workspaceId = environment.workspaceId;
|
const workspaceId = environment.workspaceId;
|
||||||
const isEncryptionEnabled = useIsEncryptionEnabled();
|
const isEncryptionEnabled = useIsEncryptionEnabled();
|
||||||
const valueVisibility = useKeyValue<boolean>({
|
const valueVisibility = useKeyValue<boolean>({
|
||||||
@@ -96,40 +96,6 @@ export function EnvironmentEditor({ environment, hideName, className, addOrFocus
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const { pairs, autoFocusValue } = useMemo<{
|
|
||||||
pairs: Pair[];
|
|
||||||
autoFocusValue?: string;
|
|
||||||
}>(() => {
|
|
||||||
if (addOrFocusVariable != null) {
|
|
||||||
const existing = environment.variables.find(
|
|
||||||
(v) => v.id === addOrFocusVariable.id || v.name === addOrFocusVariable.name,
|
|
||||||
);
|
|
||||||
if (existing) {
|
|
||||||
return {
|
|
||||||
pairs: environment.variables,
|
|
||||||
autoFocusValue: existing.id,
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
const newPair = ensurePairId(addOrFocusVariable);
|
|
||||||
return {
|
|
||||||
pairs: [...environment.variables, newPair],
|
|
||||||
autoFocusValue: newPair.id,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return { pairs: environment.variables };
|
|
||||||
}
|
|
||||||
}, [addOrFocusVariable, environment.variables]);
|
|
||||||
|
|
||||||
const initPairEditor = useCallback(
|
|
||||||
(n: PairEditorHandle | null) => {
|
|
||||||
if (n && autoFocusValue) {
|
|
||||||
n.focusValue(autoFocusValue);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[autoFocusValue],
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
@@ -188,7 +154,7 @@ export function EnvironmentEditor({ environment, hideName, className, addOrFocus
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<PairOrBulkEditor
|
<PairOrBulkEditor
|
||||||
setRef={initPairEditor}
|
setRef={setRef}
|
||||||
className="h-full"
|
className="h-full"
|
||||||
allowMultilineValues
|
allowMultilineValues
|
||||||
preferenceName="environment"
|
preferenceName="environment"
|
||||||
@@ -199,7 +165,7 @@ export function EnvironmentEditor({ environment, hideName, className, addOrFocus
|
|||||||
valueAutocompleteVariables="environment"
|
valueAutocompleteVariables="environment"
|
||||||
valueAutocompleteFunctions
|
valueAutocompleteFunctions
|
||||||
forceUpdateKey={`${environment.id}::${forceUpdateKey}`}
|
forceUpdateKey={`${environment.id}::${forceUpdateKey}`}
|
||||||
pairs={pairs}
|
pairs={environment.variables}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
stateKey={`environment.${environment.id}`}
|
stateKey={`environment.${environment.id}`}
|
||||||
forcedEnvironmentId={environment.id}
|
forcedEnvironmentId={environment.id}
|
||||||
|
|||||||
@@ -320,14 +320,14 @@ export function Editor({
|
|||||||
const onClickVariable = useCallback(
|
const onClickVariable = useCallback(
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
async (v: WrappedEnvironmentVariable, _tagValue: string, _startPos: number) => {
|
async (v: WrappedEnvironmentVariable, _tagValue: string, _startPos: number) => {
|
||||||
editEnvironment(v.environment, { addOrFocusVariable: v.variable });
|
await editEnvironment(v.environment, { addOrFocusVariable: v.variable });
|
||||||
},
|
},
|
||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
|
|
||||||
const onClickMissingVariable = useCallback(async (name: string) => {
|
const onClickMissingVariable = useCallback(async (name: string) => {
|
||||||
const activeEnvironment = jotaiStore.get(activeEnvironmentAtom);
|
const activeEnvironment = jotaiStore.get(activeEnvironmentAtom);
|
||||||
editEnvironment(activeEnvironment, { addOrFocusVariable: { name, value: '', enabled: true } });
|
await editEnvironment(activeEnvironment, { addOrFocusVariable: { name, value: '', enabled: true } });
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const [, { focusParamValue }] = useRequestEditor();
|
const [, { focusParamValue }] = useRequestEditor();
|
||||||
|
|||||||
@@ -131,42 +131,44 @@ function BaseInput({
|
|||||||
const [obscured, setObscured] = useStateWithDeps(type === 'password', [type]);
|
const [obscured, setObscured] = useStateWithDeps(type === 'password', [type]);
|
||||||
const [hasChanged, setHasChanged] = useStateWithDeps<boolean>(false, [forceUpdateKey]);
|
const [hasChanged, setHasChanged] = useStateWithDeps<boolean>(false, [forceUpdateKey]);
|
||||||
const editorRef = useRef<EditorView | null>(null);
|
const editorRef = useRef<EditorView | null>(null);
|
||||||
|
const skipNextFocus = useRef<boolean>(false);
|
||||||
|
|
||||||
const initEditorRef = useCallback(
|
const handle = useMemo<InputHandle>(
|
||||||
(cm: EditorView | null) => {
|
() => ({
|
||||||
editorRef.current = cm;
|
focus: () => {
|
||||||
if (cm == null) {
|
if (editorRef.current == null) return;
|
||||||
setRef?.(null);
|
const anchor = editorRef.current.state.doc.length;
|
||||||
return;
|
skipNextFocus.current = true;
|
||||||
}
|
editorRef.current.focus();
|
||||||
const handle: InputHandle = {
|
editorRef.current.dispatch({ selection: { anchor, head: anchor }, scrollIntoView: true });
|
||||||
focus: () => {
|
},
|
||||||
cm.focus();
|
isFocused: () => editorRef.current?.hasFocus ?? false,
|
||||||
cm.dispatch({ selection: { anchor: cm.state.doc.length, head: cm.state.doc.length } });
|
value: () => editorRef.current?.state.doc.toString() ?? '',
|
||||||
},
|
dispatch: (...args) => {
|
||||||
isFocused: () => cm.hasFocus ?? false,
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
value: () => cm.state.doc.toString() ?? '',
|
editorRef.current?.dispatch(...(args as any));
|
||||||
dispatch: (...args) => {
|
},
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
selectAll() {
|
||||||
cm.dispatch(...(args as any));
|
if (editorRef.current == null) return;
|
||||||
},
|
editorRef.current.focus();
|
||||||
selectAll() {
|
editorRef.current.dispatch({
|
||||||
cm.focus();
|
selection: { anchor: 0, head: editorRef.current.state.doc.length },
|
||||||
|
});
|
||||||
cm.dispatch({
|
},
|
||||||
selection: { anchor: 0, head: cm.state.doc.length },
|
}),
|
||||||
});
|
[],
|
||||||
},
|
);
|
||||||
};
|
|
||||||
|
const setEditorRef = useCallback(
|
||||||
setRef?.(handle);
|
(h: EditorView | null) => {
|
||||||
},
|
editorRef.current = h;
|
||||||
[setRef],
|
setRef?.(handle);
|
||||||
|
},
|
||||||
|
[handle, setRef],
|
||||||
);
|
);
|
||||||
|
|
||||||
const lastWindowFocus = useRef<number>(0);
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fn = () => (lastWindowFocus.current = Date.now());
|
const fn = () => (skipNextFocus.current = true);
|
||||||
window.addEventListener('focus', fn);
|
window.addEventListener('focus', fn);
|
||||||
return () => {
|
return () => {
|
||||||
window.removeEventListener('focus', fn);
|
window.removeEventListener('focus', fn);
|
||||||
@@ -176,11 +178,7 @@ function BaseInput({
|
|||||||
const handleFocus = useCallback(() => {
|
const handleFocus = useCallback(() => {
|
||||||
if (readOnly) return;
|
if (readOnly) return;
|
||||||
|
|
||||||
// Select all text of input when it's focused to match standard browser behavior.
|
if (!skipNextFocus.current) {
|
||||||
// This should not, however, select when the input is focused due to a window focus event, so
|
|
||||||
// we handle that case as well.
|
|
||||||
const windowJustFocused = Date.now() - lastWindowFocus.current < 200;
|
|
||||||
if (!windowJustFocused) {
|
|
||||||
editorRef.current?.dispatch({
|
editorRef.current?.dispatch({
|
||||||
selection: { anchor: 0, head: editorRef.current.state.doc.length },
|
selection: { anchor: 0, head: editorRef.current.state.doc.length },
|
||||||
});
|
});
|
||||||
@@ -188,6 +186,7 @@ function BaseInput({
|
|||||||
|
|
||||||
setFocused(true);
|
setFocused(true);
|
||||||
onFocus?.();
|
onFocus?.();
|
||||||
|
skipNextFocus.current = false;
|
||||||
}, [onFocus, readOnly]);
|
}, [onFocus, readOnly]);
|
||||||
|
|
||||||
const handleBlur = useCallback(async () => {
|
const handleBlur = useCallback(async () => {
|
||||||
@@ -299,7 +298,7 @@ function BaseInput({
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<Editor
|
<Editor
|
||||||
setRef={initEditorRef}
|
setRef={setEditorRef}
|
||||||
id={id.current}
|
id={id.current}
|
||||||
hideGutter
|
hideGutter
|
||||||
singleLine={!multiLine}
|
singleLine={!multiLine}
|
||||||
@@ -402,6 +401,7 @@ function EncryptionInput({
|
|||||||
setState({ fieldType: 'encrypted', security, value, obscured: true, error: null });
|
setState({ fieldType: 'encrypted', security, value, obscured: true, error: null });
|
||||||
// We're calling this here because we want the input to be fully initialized so the caller
|
// We're calling this here because we want the input to be fully initialized so the caller
|
||||||
// can do stuff like change the selection.
|
// can do stuff like change the selection.
|
||||||
|
console.log('INIT FIRST');
|
||||||
setRef?.(inputRef.current);
|
setRef?.(inputRef.current);
|
||||||
},
|
},
|
||||||
onError: (value) => {
|
onError: (value) => {
|
||||||
@@ -415,10 +415,12 @@ function EncryptionInput({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
} else if (isEncryptionEnabled && !defaultValue) {
|
} else if (isEncryptionEnabled && !defaultValue) {
|
||||||
|
console.log('INIT SECOND');
|
||||||
// Default to encrypted field for new encrypted inputs
|
// Default to encrypted field for new encrypted inputs
|
||||||
setState({ fieldType: 'encrypted', security, value: '', obscured: true, error: null });
|
setState({ fieldType: 'encrypted', security, value: '', obscured: true, error: null });
|
||||||
setRef?.(inputRef.current);
|
requestAnimationFrame(() => setRef?.(inputRef.current));
|
||||||
} else if (isEncryptionEnabled) {
|
} else if (isEncryptionEnabled) {
|
||||||
|
console.log('INIT THIRD');
|
||||||
// Don't obscure plain text when encryption is enabled
|
// Don't obscure plain text when encryption is enabled
|
||||||
setState({
|
setState({
|
||||||
fieldType: 'text',
|
fieldType: 'text',
|
||||||
@@ -427,7 +429,9 @@ function EncryptionInput({
|
|||||||
obscured: false,
|
obscured: false,
|
||||||
error: null,
|
error: null,
|
||||||
});
|
});
|
||||||
|
requestAnimationFrame(() => setRef?.(inputRef.current));
|
||||||
} else {
|
} else {
|
||||||
|
console.log('INIT FOURTH');
|
||||||
// Don't obscure plain text when encryption is disabled
|
// Don't obscure plain text when encryption is disabled
|
||||||
setState({
|
setState({
|
||||||
fieldType: 'text',
|
fieldType: 'text',
|
||||||
@@ -436,7 +440,7 @@ function EncryptionInput({
|
|||||||
obscured: true,
|
obscured: true,
|
||||||
error: null,
|
error: null,
|
||||||
});
|
});
|
||||||
setRef?.(inputRef.current);
|
requestAnimationFrame(() => setRef?.(inputRef.current));
|
||||||
}
|
}
|
||||||
}, [defaultValue, isEncryptionEnabled, setRef, setState, state.value]);
|
}, [defaultValue, isEncryptionEnabled, setRef, setState, state.value]);
|
||||||
|
|
||||||
@@ -467,7 +471,7 @@ function EncryptionInput({
|
|||||||
[handleChange, state],
|
[handleChange, state],
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleSetInputRef = useCallback((h: InputHandle | null) => {
|
const setInputRef = useCallback((h: InputHandle | null) => {
|
||||||
inputRef.current = h;
|
inputRef.current = h;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@@ -580,7 +584,7 @@ function EncryptionInput({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<BaseInput
|
<BaseInput
|
||||||
setRef={handleSetInputRef}
|
setRef={setInputRef}
|
||||||
disableObscureToggle
|
disableObscureToggle
|
||||||
autocompleteFunctions={autocompleteFunctions}
|
autocompleteFunctions={autocompleteFunctions}
|
||||||
autocompleteVariables={autocompleteVariables}
|
autocompleteVariables={autocompleteVariables}
|
||||||
|
|||||||
@@ -1,16 +1,44 @@
|
|||||||
import type { Environment, EnvironmentVariable } from '@yaakapp-internal/models';
|
import type { Environment, EnvironmentVariable } from '@yaakapp-internal/models';
|
||||||
|
import { updateModel } from '@yaakapp-internal/models';
|
||||||
import { openFolderSettings } from '../commands/openFolderSettings';
|
import { openFolderSettings } from '../commands/openFolderSettings';
|
||||||
|
import type { PairEditorHandle } from '../components/core/PairEditor';
|
||||||
|
import { ensurePairId } from '../components/core/PairEditor.util';
|
||||||
import { EnvironmentEditDialog } from '../components/EnvironmentEditDialog';
|
import { EnvironmentEditDialog } from '../components/EnvironmentEditDialog';
|
||||||
|
import { environmentsBreakdownAtom } from '../hooks/useEnvironmentsBreakdown';
|
||||||
import { toggleDialog } from './dialog';
|
import { toggleDialog } from './dialog';
|
||||||
|
import { jotaiStore } from './jotai';
|
||||||
|
|
||||||
interface Options {
|
interface Options {
|
||||||
addOrFocusVariable?: EnvironmentVariable;
|
addOrFocusVariable?: EnvironmentVariable;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function editEnvironment(environment: Environment | null, options: Options = {}) {
|
export async function editEnvironment(
|
||||||
if (environment?.parentModel === 'folder' && environment.parentId != null) {
|
initialEnvironment: Environment | null,
|
||||||
openFolderSettings(environment.parentId, 'variables');
|
options: Options = {},
|
||||||
|
) {
|
||||||
|
if (initialEnvironment?.parentModel === 'folder' && initialEnvironment.parentId != null) {
|
||||||
|
openFolderSettings(initialEnvironment.parentId, 'variables');
|
||||||
} else {
|
} else {
|
||||||
|
const { addOrFocusVariable } = options;
|
||||||
|
const { baseEnvironment } = jotaiStore.get(environmentsBreakdownAtom);
|
||||||
|
let environment = initialEnvironment ?? baseEnvironment;
|
||||||
|
let focusId: string | null = null;
|
||||||
|
|
||||||
|
if (addOrFocusVariable && environment != null) {
|
||||||
|
const existing = environment.variables.find(
|
||||||
|
(v) => v.id === addOrFocusVariable.id || v.name === addOrFocusVariable.name,
|
||||||
|
);
|
||||||
|
if (existing) {
|
||||||
|
focusId = existing.id ?? null;
|
||||||
|
} else {
|
||||||
|
const newVar = ensurePairId(addOrFocusVariable);
|
||||||
|
environment = { ...environment, variables: [...environment.variables, newVar] };
|
||||||
|
await updateModel(environment);
|
||||||
|
environment.variables.push(newVar);
|
||||||
|
focusId = newVar.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
toggleDialog({
|
toggleDialog({
|
||||||
id: 'environment-editor',
|
id: 'environment-editor',
|
||||||
noPadding: true,
|
noPadding: true,
|
||||||
@@ -19,7 +47,11 @@ export function editEnvironment(environment: Environment | null, options: Option
|
|||||||
render: () => (
|
render: () => (
|
||||||
<EnvironmentEditDialog
|
<EnvironmentEditDialog
|
||||||
initialEnvironmentId={environment?.id ?? null}
|
initialEnvironmentId={environment?.id ?? null}
|
||||||
addOrFocusVariable={options.addOrFocusVariable}
|
setRef={(pairEditor: PairEditorHandle | null) => {
|
||||||
|
if (focusId) {
|
||||||
|
pairEditor?.focusValue(focusId);
|
||||||
|
}
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user