mirror of
https://github.com/n8n-io/n8n.git
synced 2025-02-02 07:01:30 -08:00
fix(editor): Refine push modal layout (#12886)
Co-authored-by: Csaba Tuncsik <csaba.tuncsik@gmail.com>
This commit is contained in:
parent
9446304d66
commit
212a5bf23e
|
@ -41,8 +41,8 @@
|
|||
"@n8n/codemirror-lang-sql": "^1.0.2",
|
||||
"@n8n/permissions": "workspace:*",
|
||||
"@replit/codemirror-indentation-markers": "^6.5.3",
|
||||
"@typescript/vfs": "^1.6.0",
|
||||
"@sentry/vue": "catalog:frontend",
|
||||
"@typescript/vfs": "^1.6.0",
|
||||
"@vue-flow/background": "^1.3.2",
|
||||
"@vue-flow/controls": "^1.1.2",
|
||||
"@vue-flow/core": "^1.41.6",
|
||||
|
@ -56,6 +56,7 @@
|
|||
"chart.js": "^4.4.0",
|
||||
"codemirror-lang-html-n8n": "^1.0.0",
|
||||
"comlink": "^4.4.1",
|
||||
"core-js": "^3.40.0",
|
||||
"dateformat": "^3.0.3",
|
||||
"email-providers": "^2.0.1",
|
||||
"esprima-next": "5.8.4",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import '@testing-library/jest-dom';
|
||||
import { configure } from '@testing-library/vue';
|
||||
import 'core-js/proposals/set-methods-v2';
|
||||
|
||||
configure({ testIdAttribute: 'data-test-id' });
|
||||
|
||||
|
|
|
@ -24,17 +24,25 @@ vi.mock('vue-router', () => ({
|
|||
|
||||
let route: ReturnType<typeof useRoute>;
|
||||
|
||||
const RecycleScroller = {
|
||||
const DynamicScrollerStub = {
|
||||
props: {
|
||||
items: Array,
|
||||
},
|
||||
template: '<div><template v-for="item in items"><slot v-bind="{ item }"></slot></template></div>',
|
||||
methods: {
|
||||
scrollToItem: vi.fn(),
|
||||
},
|
||||
};
|
||||
|
||||
const DynamicScrollerItemStub = {
|
||||
template: '<slot></slot>',
|
||||
};
|
||||
|
||||
const renderModal = createComponentRenderer(SourceControlPushModal, {
|
||||
global: {
|
||||
stubs: {
|
||||
RecycleScroller,
|
||||
DynamicScroller: DynamicScrollerStub,
|
||||
DynamicScrollerItem: DynamicScrollerItemStub,
|
||||
Modal: {
|
||||
template: `
|
||||
<div>
|
||||
|
@ -195,7 +203,7 @@ describe('SourceControlPushModal', () => {
|
|||
|
||||
const sourceControlStore = mockedStore(useSourceControlStore);
|
||||
|
||||
const { getByTestId, getByText } = renderModal({
|
||||
const { getByTestId, getByRole } = renderModal({
|
||||
props: {
|
||||
data: {
|
||||
eventBus,
|
||||
|
@ -207,9 +215,9 @@ describe('SourceControlPushModal', () => {
|
|||
const submitButton = getByTestId('source-control-push-modal-submit');
|
||||
const commitMessage = 'commit message';
|
||||
expect(submitButton).toBeDisabled();
|
||||
expect(getByText('1 new credentials added, 0 deleted and 0 changed')).toBeInTheDocument();
|
||||
expect(getByText('At least one new variable has been added or modified')).toBeInTheDocument();
|
||||
expect(getByText('At least one new tag has been added or modified')).toBeInTheDocument();
|
||||
expect(getByRole('alert').textContent).toContain('Credentials: 1 added.');
|
||||
expect(getByRole('alert').textContent).toContain('Variables: at least one new or modified.');
|
||||
expect(getByRole('alert').textContent).toContain('Tags: at least one new or modified.');
|
||||
|
||||
await userEvent.type(getByTestId('source-control-push-modal-commit'), commitMessage);
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script lang="ts" setup>
|
||||
import Modal from './Modal.vue';
|
||||
import { SOURCE_CONTROL_PUSH_MODAL_KEY, VIEWS } from '@/constants';
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import { computed, onMounted, ref, toRaw } from 'vue';
|
||||
import type { EventBus } from 'n8n-design-system/utils';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
import { useLoadingService } from '@/composables/useLoadingService';
|
||||
|
@ -10,7 +10,7 @@ import { useSourceControlStore } from '@/stores/sourceControl.store';
|
|||
import { useUIStore } from '@/stores/ui.store';
|
||||
import { useRoute } from 'vue-router';
|
||||
import dateformat from 'dateformat';
|
||||
import { RecycleScroller } from 'vue-virtual-scroller';
|
||||
import { DynamicScroller, DynamicScrollerItem } from 'vue-virtual-scroller';
|
||||
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css';
|
||||
import { refDebounced } from '@vueuse/core';
|
||||
import {
|
||||
|
@ -49,6 +49,9 @@ const i18n = useI18n();
|
|||
const sourceControlStore = useSourceControlStore();
|
||||
const route = useRoute();
|
||||
|
||||
const concatenateWithAnd = (messages: string[]) =>
|
||||
new Intl.ListFormat(i18n.locale, { style: 'long', type: 'conjunction' }).format(messages);
|
||||
|
||||
type SourceControlledFileStatus = SourceControlledFile['status'];
|
||||
|
||||
type Changes = {
|
||||
|
@ -101,22 +104,33 @@ const classifyFilesByType = (files: SourceControlledFile[], currentWorkflowId?:
|
|||
);
|
||||
|
||||
const userNotices = computed(() => {
|
||||
const messages: string[] = [];
|
||||
const messages: Array<{ title: string; content: string }> = [];
|
||||
|
||||
if (changes.value.credentials.length) {
|
||||
const { created, deleted, modified } = groupBy(changes.value.credentials, 'status');
|
||||
|
||||
messages.push(
|
||||
`${created?.length ?? 0} new credentials added, ${deleted?.length ?? 0} deleted and ${modified?.length ?? 0} changed`,
|
||||
);
|
||||
messages.push({
|
||||
title: 'Credentials',
|
||||
content: concatenateWithAnd([
|
||||
...(created?.length ? [`${created.length} added`] : []),
|
||||
...(deleted?.length ? [`${deleted.length} deleted`] : []),
|
||||
...(modified?.length ? [`${modified.length} changed`] : []),
|
||||
]),
|
||||
});
|
||||
}
|
||||
|
||||
if (changes.value.variables.length) {
|
||||
messages.push('At least one new variable has been added or modified');
|
||||
messages.push({
|
||||
title: 'Variables',
|
||||
content: 'at least one new or modified',
|
||||
});
|
||||
}
|
||||
|
||||
if (changes.value.tags.length) {
|
||||
messages.push('At least one new tag has been added or modified');
|
||||
messages.push({
|
||||
title: 'Tags',
|
||||
content: 'at least one new or modified',
|
||||
});
|
||||
}
|
||||
|
||||
return messages;
|
||||
|
@ -218,20 +232,38 @@ const isSubmitDisabled = computed(() => {
|
|||
return false;
|
||||
});
|
||||
|
||||
const selectAll = computed(
|
||||
() =>
|
||||
selectedChanges.value.size > 0 && selectedChanges.value.size === sortedWorkflows.value.length,
|
||||
);
|
||||
const sortedWorkflowsSet = computed(() => new Set(sortedWorkflows.value.map(({ id }) => id)));
|
||||
|
||||
const selectAllIndeterminate = computed(
|
||||
() => selectedChanges.value.size > 0 && selectedChanges.value.size < sortedWorkflows.value.length,
|
||||
);
|
||||
const selectAll = computed(() => {
|
||||
if (!selectedChanges.value.size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const notSelectedVisibleItems = toRaw(sortedWorkflowsSet.value).difference(selectedChanges.value);
|
||||
|
||||
return !Boolean(notSelectedVisibleItems.size);
|
||||
});
|
||||
|
||||
const selectAllIndeterminate = computed(() => {
|
||||
if (!selectedChanges.value.size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const selectedVisibleItems = toRaw(selectedChanges.value).intersection(sortedWorkflowsSet.value);
|
||||
|
||||
if (selectedVisibleItems.size === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !selectAll.value;
|
||||
});
|
||||
|
||||
function onToggleSelectAll() {
|
||||
const selected = toRaw(selectedChanges.value);
|
||||
if (selectAll.value) {
|
||||
selectedChanges.value.clear();
|
||||
selectedChanges.value = selected.difference(sortedWorkflowsSet.value);
|
||||
} else {
|
||||
selectedChanges.value = new Set(changes.value.workflows.map((file) => file.id));
|
||||
selectedChanges.value = selected.union(sortedWorkflowsSet.value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -289,7 +321,7 @@ const successNotificationMessage = () => {
|
|||
}
|
||||
|
||||
return [
|
||||
new Intl.ListFormat(i18n.locale, { style: 'long', type: 'conjunction' }).format(messages),
|
||||
concatenateWithAnd(messages),
|
||||
i18n.baseText('settings.sourceControl.modals.push.success.description'),
|
||||
].join(' ');
|
||||
};
|
||||
|
@ -320,6 +352,8 @@ async function commitAndPush() {
|
|||
loadingService.stopLoading();
|
||||
}
|
||||
}
|
||||
|
||||
const modalHeight = computed(() => (changes.value.workflows.length ? 'min(80vh, 850px)' : 'auto'));
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -327,161 +361,190 @@ async function commitAndPush() {
|
|||
width="812px"
|
||||
:event-bus="data.eventBus"
|
||||
:name="SOURCE_CONTROL_PUSH_MODAL_KEY"
|
||||
max-height="80%"
|
||||
:height="modalHeight"
|
||||
:custom-class="$style.sourceControlPush"
|
||||
>
|
||||
<template #header>
|
||||
<N8nHeading tag="h1" size="xlarge">
|
||||
{{ i18n.baseText('settings.sourceControl.modals.push.title') }}
|
||||
</N8nHeading>
|
||||
<div class="mt-l">
|
||||
<N8nText tag="div">
|
||||
{{ i18n.baseText('settings.sourceControl.modals.push.description') }}
|
||||
<N8nLink :to="i18n.baseText('settings.sourceControl.docs.using.pushPull.url')">
|
||||
{{ i18n.baseText('settings.sourceControl.modals.push.description.learnMore') }}
|
||||
</N8nLink>
|
||||
</N8nText>
|
||||
|
||||
<N8nNotice v-if="userNotices.length" class="mt-xs" :compact="false">
|
||||
<ul class="ml-m">
|
||||
<li v-for="notice in userNotices" :key="notice">{{ notice }}</li>
|
||||
</ul>
|
||||
</N8nNotice>
|
||||
</div>
|
||||
<div v-if="changes.workflows.length" :class="[$style.filtersRow]" class="mt-l">
|
||||
<div :class="[$style.filters]">
|
||||
<N8nInput
|
||||
v-model="search"
|
||||
data-test-id="source-control-push-search"
|
||||
placeholder="Filter by title"
|
||||
clearable
|
||||
style="width: 234px"
|
||||
>
|
||||
<template #prefix>
|
||||
<N8nIcon icon="search" />
|
||||
</template>
|
||||
</N8nInput>
|
||||
<N8nPopover trigger="click" width="304" style="align-self: normal">
|
||||
<template #reference>
|
||||
<N8nButton
|
||||
icon="filter"
|
||||
type="tertiary"
|
||||
style="height: 100%"
|
||||
:active="Boolean(filterCount)"
|
||||
data-test-id="source-control-filter-dropdown"
|
||||
>
|
||||
<N8nBadge v-if="filterCount" theme="primary" class="mr-4xs">
|
||||
{{ filterCount }}
|
||||
</N8nBadge>
|
||||
</N8nButton>
|
||||
</template>
|
||||
<N8nInputLabel
|
||||
:label="i18n.baseText('workflows.filters.status')"
|
||||
:bold="false"
|
||||
size="small"
|
||||
color="text-base"
|
||||
class="mb-3xs"
|
||||
/>
|
||||
<N8nSelect
|
||||
v-model="filters.status"
|
||||
data-test-id="source-control-status-filter"
|
||||
clearable
|
||||
>
|
||||
<N8nOption
|
||||
v-for="option in statusFilterOptions"
|
||||
:key="option.label"
|
||||
data-test-id="source-control-status-filter-option"
|
||||
v-bind="option"
|
||||
>
|
||||
</N8nOption>
|
||||
</N8nSelect>
|
||||
</N8nPopover>
|
||||
</div>
|
||||
|
||||
<div v-if="changes.workflows.length" :class="[$style.filers]" class="mt-l">
|
||||
<N8nCheckbox
|
||||
:class="$style.selectAll"
|
||||
:indeterminate="selectAllIndeterminate"
|
||||
:model-value="selectAll"
|
||||
data-test-id="source-control-push-modal-toggle-all"
|
||||
@update:model-value="onToggleSelectAll"
|
||||
>
|
||||
<N8nText bold tag="strong">
|
||||
{{ i18n.baseText('settings.sourceControl.modals.push.workflowsToCommit') }}
|
||||
<div>
|
||||
<N8nText bold color="text-base" size="small">
|
||||
{{ selectedChanges.size }} of {{ changes.workflows.length }}
|
||||
</N8nText>
|
||||
<N8nText tag="strong">
|
||||
({{ selectedChanges.size }}/{{ sortedWorkflows.length }})
|
||||
</N8nText>
|
||||
</N8nCheckbox>
|
||||
<N8nPopover trigger="click" width="304" style="align-self: normal">
|
||||
<template #reference>
|
||||
<N8nButton
|
||||
icon="filter"
|
||||
type="tertiary"
|
||||
style="height: 100%"
|
||||
:active="Boolean(filterCount)"
|
||||
data-test-id="source-control-filter-dropdown"
|
||||
>
|
||||
<N8nBadge v-show="filterCount" theme="primary" class="mr-4xs">
|
||||
{{ filterCount }}
|
||||
</N8nBadge>
|
||||
{{ i18n.baseText('forms.resourceFiltersDropdown.filters') }}
|
||||
</N8nButton>
|
||||
</template>
|
||||
<N8nInputLabel
|
||||
:label="i18n.baseText('workflows.filters.status')"
|
||||
:bold="false"
|
||||
size="small"
|
||||
color="text-base"
|
||||
class="mb-3xs"
|
||||
/>
|
||||
<N8nSelect v-model="filters.status" data-test-id="source-control-status-filter" clearable>
|
||||
<N8nOption
|
||||
v-for="option in statusFilterOptions"
|
||||
:key="option.label"
|
||||
data-test-id="source-control-status-filter-option"
|
||||
v-bind="option"
|
||||
>
|
||||
</N8nOption>
|
||||
</N8nSelect>
|
||||
</N8nPopover>
|
||||
<N8nInput
|
||||
v-model="search"
|
||||
data-test-id="source-control-push-search"
|
||||
:placeholder="i18n.baseText('workflows.search.placeholder')"
|
||||
clearable
|
||||
>
|
||||
<template #prefix>
|
||||
<N8nIcon icon="search" />
|
||||
</template>
|
||||
</N8nInput>
|
||||
<N8nText color="text-base" size="small"> workflows selected</N8nText>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #content>
|
||||
<N8nInfoTip v-if="filtersApplied && !sortedWorkflows.length" :bold="false">
|
||||
{{ i18n.baseText('workflows.filters.active') }}
|
||||
<N8nLink size="small" data-test-id="source-control-filters-reset" @click="resetFilters">
|
||||
{{ i18n.baseText('workflows.filters.active.reset') }}
|
||||
</N8nLink>
|
||||
</N8nInfoTip>
|
||||
<RecycleScroller
|
||||
v-if="sortedWorkflows.length"
|
||||
:class="[$style.scroller]"
|
||||
:items="sortedWorkflows"
|
||||
:item-size="69"
|
||||
key-field="id"
|
||||
>
|
||||
<template #default="{ item: file }">
|
||||
<div :class="[$style.table]" v-if="changes.workflows.length">
|
||||
<div :class="[$style.tableHeader]">
|
||||
<N8nCheckbox
|
||||
:class="['scopedListItem', $style.listItem]"
|
||||
data-test-id="source-control-push-modal-file-checkbox"
|
||||
:model-value="selectedChanges.has(file.id)"
|
||||
@update:model-value="toggleSelected(file.id)"
|
||||
:class="$style.selectAll"
|
||||
:indeterminate="selectAllIndeterminate"
|
||||
:model-value="selectAll"
|
||||
data-test-id="source-control-push-modal-toggle-all"
|
||||
@update:model-value="onToggleSelectAll"
|
||||
>
|
||||
<span>
|
||||
<N8nText v-if="file.status === SOURCE_CONTROL_FILE_STATUS.deleted" color="text-light">
|
||||
<span v-if="file.type === SOURCE_CONTROL_FILE_TYPE.workflow">
|
||||
Deleted Workflow:
|
||||
</span>
|
||||
<span v-if="file.type === SOURCE_CONTROL_FILE_TYPE.credential">
|
||||
Deleted Credential:
|
||||
</span>
|
||||
<strong>{{ file.name || file.id }}</strong>
|
||||
</N8nText>
|
||||
<N8nText v-else bold> {{ file.name }} </N8nText>
|
||||
<N8nText v-if="file.updatedAt" tag="p" class="mt-0" color="text-light" size="small">
|
||||
{{ renderUpdatedAt(file) }}
|
||||
</N8nText>
|
||||
</span>
|
||||
<span :class="[$style.badges]">
|
||||
<N8nBadge
|
||||
v-if="changes.currentWorkflow && file.id === changes.currentWorkflow.id"
|
||||
class="mr-2xs"
|
||||
>
|
||||
Current workflow
|
||||
</N8nBadge>
|
||||
<N8nBadge :theme="getStatusTheme(file.status)">
|
||||
{{ getStatusText(file.status) }}
|
||||
</N8nBadge>
|
||||
</span>
|
||||
<N8nText> Title </N8nText>
|
||||
</N8nCheckbox>
|
||||
</template>
|
||||
</RecycleScroller>
|
||||
</div>
|
||||
<div style="flex: 1; overflow: hidden">
|
||||
<N8nInfoTip v-if="filtersApplied && !sortedWorkflows.length" :bold="false">
|
||||
{{ i18n.baseText('workflows.filters.active') }}
|
||||
<N8nLink size="small" data-test-id="source-control-filters-reset" @click="resetFilters">
|
||||
{{ i18n.baseText('workflows.filters.active.reset') }}
|
||||
</N8nLink>
|
||||
</N8nInfoTip>
|
||||
<DynamicScroller
|
||||
v-if="sortedWorkflows.length"
|
||||
:class="[$style.scroller]"
|
||||
:items="sortedWorkflows"
|
||||
:min-item-size="58"
|
||||
item-class="scrollerItem"
|
||||
>
|
||||
<template #default="{ item: file, active, index }">
|
||||
<DynamicScrollerItem
|
||||
:item="file"
|
||||
:active="active"
|
||||
:size-dependencies="[file.name, file.id]"
|
||||
:data-index="index"
|
||||
>
|
||||
<N8nCheckbox
|
||||
:class="[$style.listItem]"
|
||||
data-test-id="source-control-push-modal-file-checkbox"
|
||||
:model-value="selectedChanges.has(file.id)"
|
||||
@update:model-value="toggleSelected(file.id)"
|
||||
>
|
||||
<span>
|
||||
<N8nText
|
||||
v-if="file.status === SOURCE_CONTROL_FILE_STATUS.deleted"
|
||||
color="text-light"
|
||||
>
|
||||
<span v-if="file.type === SOURCE_CONTROL_FILE_TYPE.workflow">
|
||||
Deleted Workflow:
|
||||
</span>
|
||||
<span v-if="file.type === SOURCE_CONTROL_FILE_TYPE.credential">
|
||||
Deleted Credential:
|
||||
</span>
|
||||
<strong>{{ file.name || file.id }}</strong>
|
||||
</N8nText>
|
||||
<N8nText v-else tag="div" bold color="text-dark" :class="[$style.listItemName]">
|
||||
{{ file.name }}
|
||||
</N8nText>
|
||||
<N8nText
|
||||
v-if="file.updatedAt"
|
||||
tag="p"
|
||||
class="mt-0"
|
||||
color="text-light"
|
||||
size="small"
|
||||
>
|
||||
{{ renderUpdatedAt(file) }}
|
||||
</N8nText>
|
||||
</span>
|
||||
<span :class="[$style.badges]">
|
||||
<N8nBadge
|
||||
v-if="changes.currentWorkflow && file.id === changes.currentWorkflow.id"
|
||||
class="mr-2xs"
|
||||
>
|
||||
Current workflow
|
||||
</N8nBadge>
|
||||
<N8nBadge :theme="getStatusTheme(file.status)">
|
||||
{{ getStatusText(file.status) }}
|
||||
</N8nBadge>
|
||||
</span>
|
||||
</N8nCheckbox>
|
||||
</DynamicScrollerItem>
|
||||
</template>
|
||||
</DynamicScroller>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #footer>
|
||||
<N8nText bold tag="p" class="mb-2xs">
|
||||
<N8nNotice v-if="userNotices.length" :compact="false" class="mt-0">
|
||||
<N8nText bold size="medium">Changes to credentials, variables and tags </N8nText>
|
||||
<br />
|
||||
<template v-for="{ title, content } in userNotices" :key="title">
|
||||
<N8nText bold size="small">{{ title }}</N8nText>
|
||||
<N8nText size="small">: {{ content }}. </N8nText>
|
||||
</template>
|
||||
</N8nNotice>
|
||||
|
||||
<N8nText bold tag="p">
|
||||
{{ i18n.baseText('settings.sourceControl.modals.push.commitMessage') }}
|
||||
</N8nText>
|
||||
<N8nInput
|
||||
v-model="commitMessage"
|
||||
data-test-id="source-control-push-modal-commit"
|
||||
:placeholder="i18n.baseText('settings.sourceControl.modals.push.commitMessage.placeholder')"
|
||||
@keydown.enter="onCommitKeyDownEnter"
|
||||
/>
|
||||
|
||||
<div :class="$style.footer">
|
||||
<N8nButton type="tertiary" class="mr-2xs" @click="close">
|
||||
{{ i18n.baseText('settings.sourceControl.modals.push.buttons.cancel') }}
|
||||
</N8nButton>
|
||||
<N8nInput
|
||||
v-model="commitMessage"
|
||||
class="mr-2xs"
|
||||
data-test-id="source-control-push-modal-commit"
|
||||
:placeholder="
|
||||
i18n.baseText('settings.sourceControl.modals.push.commitMessage.placeholder')
|
||||
"
|
||||
@keydown.enter="onCommitKeyDownEnter"
|
||||
/>
|
||||
<N8nButton
|
||||
data-test-id="source-control-push-modal-submit"
|
||||
type="primary"
|
||||
:disabled="isSubmitDisabled"
|
||||
size="large"
|
||||
@click="commitAndPush"
|
||||
>
|
||||
{{ i18n.baseText('settings.sourceControl.modals.push.buttons.save') }}
|
||||
{{ selectedChanges.size ? `(${selectedChanges.size})` : undefined }}
|
||||
</N8nButton>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -489,7 +552,14 @@ async function commitAndPush() {
|
|||
</template>
|
||||
|
||||
<style module lang="scss">
|
||||
.filers {
|
||||
.filtersRow {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.filters {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
|
@ -501,18 +571,33 @@ async function commitAndPush() {
|
|||
}
|
||||
|
||||
.scroller {
|
||||
max-height: 380px;
|
||||
max-height: 100%;
|
||||
scrollbar-color: var(--color-foreground-base) transparent;
|
||||
outline: var(--border-base);
|
||||
|
||||
:global(.scrollerItem) {
|
||||
&:last-child {
|
||||
.listItem {
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.listItem {
|
||||
align-items: center;
|
||||
padding: var(--spacing-xs);
|
||||
transition: border 0.3s ease;
|
||||
border-radius: var(--border-radius-large);
|
||||
border: var(--border-base);
|
||||
padding: 10px 16px;
|
||||
margin: 0;
|
||||
border-bottom: var(--border-base);
|
||||
|
||||
&:hover {
|
||||
border-color: var(--color-foreground-dark);
|
||||
.listItemName {
|
||||
line-clamp: 2;
|
||||
-webkit-line-clamp: 2;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
word-wrap: break-word; /* Important for long words! */
|
||||
}
|
||||
|
||||
:global(.el-checkbox__label) {
|
||||
|
@ -520,6 +605,7 @@ async function commitAndPush() {
|
|||
width: 100%;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 30px;
|
||||
}
|
||||
|
||||
:global(.el-checkbox__inner) {
|
||||
|
@ -535,12 +621,30 @@ async function commitAndPush() {
|
|||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-end;
|
||||
margin-top: 20px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.sourceControlPush {
|
||||
&:global(.el-dialog) {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
:global(.el-dialog__header) {
|
||||
padding-bottom: var(--spacing-xs);
|
||||
}
|
||||
}
|
||||
|
||||
.table {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border: var(--border-base);
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.tableHeader {
|
||||
border-bottom: var(--border-base);
|
||||
padding: 10px 16px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -443,7 +443,7 @@ importers:
|
|||
version: 3.666.0(@aws-sdk/client-sts@3.666.0)
|
||||
'@getzep/zep-cloud':
|
||||
specifier: 1.0.12
|
||||
version: 1.0.12(@langchain/core@0.3.30(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)(langchain@0.3.11(uhxpxbd3xjubkjdqqkxxpkezmi))
|
||||
version: 1.0.12(@langchain/core@0.3.30(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)(langchain@0.3.11(ilqk5sp4kmqg6yh3rv76amkknm))
|
||||
'@getzep/zep-js':
|
||||
specifier: 0.9.0
|
||||
version: 0.9.0
|
||||
|
@ -470,7 +470,7 @@ importers:
|
|||
version: 0.3.2(@aws-sdk/client-sso-oidc@3.666.0(@aws-sdk/client-sts@3.666.0))(@langchain/core@0.3.30(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)
|
||||
'@langchain/community':
|
||||
specifier: 0.3.24
|
||||
version: 0.3.24(xbnzedcvjhnriori3dst4asz2q)
|
||||
version: 0.3.24(knkgly4tvsbdesqmuf53sm5qpe)
|
||||
'@langchain/core':
|
||||
specifier: 'catalog:'
|
||||
version: 0.3.30(openai@4.78.1(encoding@0.1.13)(zod@3.24.1))
|
||||
|
@ -557,7 +557,7 @@ importers:
|
|||
version: 23.0.1
|
||||
langchain:
|
||||
specifier: 0.3.11
|
||||
version: 0.3.11(uhxpxbd3xjubkjdqqkxxpkezmi)
|
||||
version: 0.3.11(ilqk5sp4kmqg6yh3rv76amkknm)
|
||||
lodash:
|
||||
specifier: 'catalog:'
|
||||
version: 4.17.21
|
||||
|
@ -1480,6 +1480,9 @@ importers:
|
|||
comlink:
|
||||
specifier: ^4.4.1
|
||||
version: 4.4.1
|
||||
core-js:
|
||||
specifier: ^3.40.0
|
||||
version: 3.40.0
|
||||
dateformat:
|
||||
specifier: ^3.0.3
|
||||
version: 3.0.3
|
||||
|
@ -7412,12 +7415,12 @@ packages:
|
|||
core-js-compat@3.39.0:
|
||||
resolution: {integrity: sha512-VgEUx3VwlExr5no0tXlBt+silBvhTryPwCXRI2Id1PN8WTKu7MreethvddqOubrYxkFdv/RnYrqlv1sFNAUelw==}
|
||||
|
||||
core-js@3.35.0:
|
||||
resolution: {integrity: sha512-ntakECeqg81KqMueeGJ79Q5ZgQNR+6eaE8sxGCx62zMbAIj65q+uYvatToew3m6eAGdU4gNZwpZ34NMe4GYswg==}
|
||||
|
||||
core-js@3.39.0:
|
||||
resolution: {integrity: sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g==}
|
||||
|
||||
core-js@3.40.0:
|
||||
resolution: {integrity: sha512-7vsMc/Lty6AGnn7uFpYT56QesI5D2Y/UkgKounk87OP9Z2H9Z8kj6jzcSGAxFmUtDOS0ntK6lbQz+Nsa0Jj6mQ==}
|
||||
|
||||
core-util-is@1.0.2:
|
||||
resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==}
|
||||
|
||||
|
@ -9992,6 +9995,7 @@ packages:
|
|||
|
||||
lodash.get@4.4.2:
|
||||
resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==}
|
||||
deprecated: This package is deprecated. Use the optional chaining (?.) operator instead.
|
||||
|
||||
lodash.includes@4.3.0:
|
||||
resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==}
|
||||
|
@ -10004,6 +10008,7 @@ packages:
|
|||
|
||||
lodash.isequal@4.5.0:
|
||||
resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==}
|
||||
deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead.
|
||||
|
||||
lodash.isinteger@4.0.4:
|
||||
resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==}
|
||||
|
@ -16042,7 +16047,7 @@ snapshots:
|
|||
'@gar/promisify@1.1.3':
|
||||
optional: true
|
||||
|
||||
'@getzep/zep-cloud@1.0.12(@langchain/core@0.3.30(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)(langchain@0.3.11(uhxpxbd3xjubkjdqqkxxpkezmi))':
|
||||
'@getzep/zep-cloud@1.0.12(@langchain/core@0.3.30(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)(langchain@0.3.11(ilqk5sp4kmqg6yh3rv76amkknm))':
|
||||
dependencies:
|
||||
form-data: 4.0.0
|
||||
node-fetch: 2.7.0(encoding@0.1.13)
|
||||
|
@ -16051,7 +16056,7 @@ snapshots:
|
|||
zod: 3.24.1
|
||||
optionalDependencies:
|
||||
'@langchain/core': 0.3.30(openai@4.78.1(encoding@0.1.13)(zod@3.24.1))
|
||||
langchain: 0.3.11(uhxpxbd3xjubkjdqqkxxpkezmi)
|
||||
langchain: 0.3.11(ilqk5sp4kmqg6yh3rv76amkknm)
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
|
||||
|
@ -16590,7 +16595,7 @@ snapshots:
|
|||
- aws-crt
|
||||
- encoding
|
||||
|
||||
'@langchain/community@0.3.24(xbnzedcvjhnriori3dst4asz2q)':
|
||||
'@langchain/community@0.3.24(knkgly4tvsbdesqmuf53sm5qpe)':
|
||||
dependencies:
|
||||
'@browserbasehq/stagehand': 1.9.0(@playwright/test@1.49.1)(deepmerge@4.3.1)(dotenv@16.4.5)(encoding@0.1.13)(openai@4.78.1(encoding@0.1.13)(zod@3.24.1))(zod@3.24.1)
|
||||
'@ibm-cloud/watsonx-ai': 1.1.2
|
||||
|
@ -16601,7 +16606,7 @@ snapshots:
|
|||
flat: 5.0.2
|
||||
ibm-cloud-sdk-core: 5.1.0
|
||||
js-yaml: 4.1.0
|
||||
langchain: 0.3.11(uhxpxbd3xjubkjdqqkxxpkezmi)
|
||||
langchain: 0.3.11(ilqk5sp4kmqg6yh3rv76amkknm)
|
||||
langsmith: 0.2.15(openai@4.78.1(encoding@0.1.13)(zod@3.24.1))
|
||||
openai: 4.78.1(encoding@0.1.13)(zod@3.24.1)
|
||||
uuid: 10.0.0
|
||||
|
@ -16616,7 +16621,7 @@ snapshots:
|
|||
'@aws-sdk/credential-provider-node': 3.666.0(@aws-sdk/client-sso-oidc@3.666.0(@aws-sdk/client-sts@3.666.0))(@aws-sdk/client-sts@3.666.0)
|
||||
'@azure/storage-blob': 12.18.0(encoding@0.1.13)
|
||||
'@browserbasehq/sdk': 2.0.0(encoding@0.1.13)
|
||||
'@getzep/zep-cloud': 1.0.12(@langchain/core@0.3.30(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)(langchain@0.3.11(uhxpxbd3xjubkjdqqkxxpkezmi))
|
||||
'@getzep/zep-cloud': 1.0.12(@langchain/core@0.3.30(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)(langchain@0.3.11(ilqk5sp4kmqg6yh3rv76amkknm))
|
||||
'@getzep/zep-js': 0.9.0
|
||||
'@google-ai/generativelanguage': 2.6.0(encoding@0.1.13)
|
||||
'@google-cloud/storage': 7.12.1(encoding@0.1.13)
|
||||
|
@ -17521,7 +17526,7 @@ snapshots:
|
|||
abort-controller: 3.0.0
|
||||
chokidar: 4.0.1
|
||||
colorette: 1.4.0
|
||||
core-js: 3.35.0
|
||||
core-js: 3.39.0
|
||||
form-data: 4.0.0
|
||||
get-port-please: 3.1.2
|
||||
glob: 7.2.3
|
||||
|
@ -17531,7 +17536,7 @@ snapshots:
|
|||
pluralize: 8.0.0
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
redoc: 2.1.5(core-js@3.35.0)(encoding@0.1.13)(enzyme@3.11.0)(mobx@6.12.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(styled-components@6.1.8(react-dom@18.2.0(react@18.2.0))(react@18.2.0))
|
||||
redoc: 2.1.5(core-js@3.39.0)(encoding@0.1.13)(enzyme@3.11.0)(mobx@6.12.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(styled-components@6.1.8(react-dom@18.2.0(react@18.2.0))(react@18.2.0))
|
||||
semver: 7.6.0
|
||||
simple-websocket: 9.1.0
|
||||
styled-components: 6.1.8(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
|
@ -19275,7 +19280,7 @@ snapshots:
|
|||
'@babel/preset-env': 7.26.0(@babel/core@7.26.0)
|
||||
browserslist: 4.24.2
|
||||
browserslist-to-esbuild: 2.1.1(browserslist@4.24.2)
|
||||
core-js: 3.39.0
|
||||
core-js: 3.40.0
|
||||
magic-string: 0.30.14
|
||||
regenerator-runtime: 0.14.1
|
||||
systemjs: 6.15.1
|
||||
|
@ -19963,14 +19968,6 @@ snapshots:
|
|||
transitivePeerDependencies:
|
||||
- debug
|
||||
|
||||
axios@1.7.4(debug@4.4.0):
|
||||
dependencies:
|
||||
follow-redirects: 1.15.6(debug@4.4.0)
|
||||
form-data: 4.0.0
|
||||
proxy-from-env: 1.1.0
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
|
||||
axios@1.7.7:
|
||||
dependencies:
|
||||
follow-redirects: 1.15.6(debug@4.3.6)
|
||||
|
@ -20737,10 +20734,10 @@ snapshots:
|
|||
dependencies:
|
||||
browserslist: 4.24.2
|
||||
|
||||
core-js@3.35.0: {}
|
||||
|
||||
core-js@3.39.0: {}
|
||||
|
||||
core-js@3.40.0: {}
|
||||
|
||||
core-util-is@1.0.2: {}
|
||||
|
||||
core-util-is@1.0.3: {}
|
||||
|
@ -21707,7 +21704,7 @@ snapshots:
|
|||
|
||||
eslint-import-resolver-node@0.3.9:
|
||||
dependencies:
|
||||
debug: 3.2.7(supports-color@5.5.0)
|
||||
debug: 3.2.7(supports-color@8.1.1)
|
||||
is-core-module: 2.13.1
|
||||
resolve: 1.22.8
|
||||
transitivePeerDependencies:
|
||||
|
@ -21732,7 +21729,7 @@ snapshots:
|
|||
|
||||
eslint-module-utils@2.8.0(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0):
|
||||
dependencies:
|
||||
debug: 3.2.7(supports-color@5.5.0)
|
||||
debug: 3.2.7(supports-color@8.1.1)
|
||||
optionalDependencies:
|
||||
'@typescript-eslint/parser': 7.2.0(eslint@8.57.0)(typescript@5.7.2)
|
||||
eslint: 8.57.0
|
||||
|
@ -21752,7 +21749,7 @@ snapshots:
|
|||
array.prototype.findlastindex: 1.2.3
|
||||
array.prototype.flat: 1.3.2
|
||||
array.prototype.flatmap: 1.3.2
|
||||
debug: 3.2.7(supports-color@5.5.0)
|
||||
debug: 3.2.7(supports-color@8.1.1)
|
||||
doctrine: 2.1.0
|
||||
eslint: 8.57.0
|
||||
eslint-import-resolver-node: 0.3.9
|
||||
|
@ -22241,10 +22238,6 @@ snapshots:
|
|||
optionalDependencies:
|
||||
debug: 4.3.7
|
||||
|
||||
follow-redirects@1.15.6(debug@4.4.0):
|
||||
optionalDependencies:
|
||||
debug: 4.4.0
|
||||
|
||||
for-each@0.3.3:
|
||||
dependencies:
|
||||
is-callable: 1.2.7
|
||||
|
@ -22538,7 +22531,7 @@ snapshots:
|
|||
array-parallel: 0.1.3
|
||||
array-series: 0.1.5
|
||||
cross-spawn: 4.0.2
|
||||
debug: 3.2.7(supports-color@5.5.0)
|
||||
debug: 3.2.7(supports-color@8.1.1)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
|
@ -22844,7 +22837,7 @@ snapshots:
|
|||
'@types/debug': 4.1.12
|
||||
'@types/node': 18.16.16
|
||||
'@types/tough-cookie': 4.0.2
|
||||
axios: 1.7.4(debug@4.4.0)
|
||||
axios: 1.7.4
|
||||
camelcase: 6.3.0
|
||||
debug: 4.4.0
|
||||
dotenv: 16.4.5
|
||||
|
@ -22854,7 +22847,7 @@ snapshots:
|
|||
isstream: 0.1.2
|
||||
jsonwebtoken: 9.0.2
|
||||
mime-types: 2.1.35
|
||||
retry-axios: 2.6.0(axios@1.7.4)
|
||||
retry-axios: 2.6.0(axios@1.7.4(debug@4.4.0))
|
||||
tough-cookie: 4.1.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
@ -23861,7 +23854,7 @@ snapshots:
|
|||
|
||||
kuler@2.0.0: {}
|
||||
|
||||
langchain@0.3.11(uhxpxbd3xjubkjdqqkxxpkezmi):
|
||||
langchain@0.3.11(ilqk5sp4kmqg6yh3rv76amkknm):
|
||||
dependencies:
|
||||
'@langchain/core': 0.3.30(openai@4.78.1(encoding@0.1.13)(zod@3.24.1))
|
||||
'@langchain/openai': 0.3.17(@langchain/core@0.3.30(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)
|
||||
|
@ -25436,7 +25429,7 @@ snapshots:
|
|||
|
||||
pdf-parse@1.1.1:
|
||||
dependencies:
|
||||
debug: 3.2.7(supports-color@5.5.0)
|
||||
debug: 3.2.7(supports-color@8.1.1)
|
||||
node-ensure: 0.0.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
@ -26109,12 +26102,12 @@ snapshots:
|
|||
'@redis/search': 1.1.6(@redis/client@1.5.16)
|
||||
'@redis/time-series': 1.0.5(@redis/client@1.5.16)
|
||||
|
||||
redoc@2.1.5(core-js@3.35.0)(encoding@0.1.13)(enzyme@3.11.0)(mobx@6.12.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(styled-components@6.1.8(react-dom@18.2.0(react@18.2.0))(react@18.2.0)):
|
||||
redoc@2.1.5(core-js@3.39.0)(encoding@0.1.13)(enzyme@3.11.0)(mobx@6.12.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(styled-components@6.1.8(react-dom@18.2.0(react@18.2.0))(react@18.2.0)):
|
||||
dependencies:
|
||||
'@cfaester/enzyme-adapter-react-18': 0.8.0(enzyme@3.11.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
'@redocly/openapi-core': 1.25.5(encoding@0.1.13)
|
||||
classnames: 2.5.1
|
||||
core-js: 3.35.0
|
||||
core-js: 3.39.0
|
||||
decko: 1.2.0
|
||||
dompurify: 3.1.7
|
||||
eventemitter3: 5.0.1
|
||||
|
@ -26266,7 +26259,7 @@ snapshots:
|
|||
|
||||
ret@0.1.15: {}
|
||||
|
||||
retry-axios@2.6.0(axios@1.7.4):
|
||||
retry-axios@2.6.0(axios@1.7.4(debug@4.4.0)):
|
||||
dependencies:
|
||||
axios: 1.7.4
|
||||
|
||||
|
@ -26293,7 +26286,7 @@ snapshots:
|
|||
|
||||
rhea@1.0.24:
|
||||
dependencies:
|
||||
debug: 3.2.7(supports-color@5.5.0)
|
||||
debug: 3.2.7(supports-color@8.1.1)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
|
|
Loading…
Reference in a new issue