feat: Add variables feature (#5602)
* feat: add variables db models and migrations * feat: variables api endpoints * feat: add $variables to expressions * test: fix ActiveWorkflowRunner tests failing * test: a different fix for the tests broken by $variables * feat: variables licensing * fix: could create one extra variable than licensed for * feat: Add Variables UI page and $vars global property (#5750) * feat: add support for row slot to datatable * feat: add variables create, read, update, delete * feat: add vars autocomplete * chore: remove alert * feat: add variables autocomplete for code and expressions * feat: add tests for variable components * feat: add variables search and sort * test: update tests for variables view * chore: fix test and linting issue * refactor: review changes * feat: add variable creation telemetry * fix: Improve variables listing and disabled case, fix resource sorting (no-changelog) (#5903) * fix: Improve variables disabled experience and fix sorting * fix: update action box margin * test: update tests for variables row and datatable * fix: Add ee controller to base controller * fix: variables.ee routes not being added * feat: add variables validation * fix: fix vue-fragment bug that breaks everything * chore: Update lock * feat: Add variables input validation and permissions (no-changelog) (#5910) * feat: add input validation * feat: handle variables view for non-instance-owner users * test: update variables tests * fix: fix data-testid pattern * feat: improve overflow styles * test: fix variables row snapshot * feat: update sorting to take newly created variables into account * fix: fix list layout overflow * fix: fix adding variables on page other than 1. fix validation * feat: add docs link * fix: fix default displayName function for resource-list-layout * feat: improve vars expressions ux, cm-tooltip * test: fix datatable test * feat: add MATCH_REGEX validation rule * fix: overhaul how datatable pagination selector works * feat: update completer description * fix: conditionally update usage syntax based on key validation * test: update datatable snapshot * fix: fix variables-row button margins * fix: fix pagination overflow * test: Fix broken test * test: Update snapshot * fix: Remove duplicate declaration * feat: add custom variables icon --------- Co-authored-by: Alex Grozav <alex@grozav.com> Co-authored-by: Omar Ajoue <krynble@gmail.com>
This commit is contained in:
@@ -1,12 +1,16 @@
|
||||
import { Server } from 'miragejs';
|
||||
import { routesForUsers } from './user';
|
||||
import { routesForCredentials } from './credential';
|
||||
import { Server } from 'miragejs';
|
||||
import { routesForCredentialTypes } from '@/__tests__/server/endpoints/credentialType';
|
||||
import { routesForCredentialTypes } from './credentialType';
|
||||
import { routesForVariables } from './variable';
|
||||
import { routesForSettings } from './settings';
|
||||
|
||||
const endpoints: Array<(server: Server) => void> = [
|
||||
routesForCredentials,
|
||||
routesForCredentialTypes,
|
||||
routesForUsers,
|
||||
routesForVariables,
|
||||
routesForSettings,
|
||||
];
|
||||
|
||||
export { endpoints };
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
import { Response, Server } from 'miragejs';
|
||||
import { AppSchema } from '../types';
|
||||
import { IN8nUISettings, ISettingsState } from '@/Interface';
|
||||
|
||||
const defaultSettings: IN8nUISettings = {
|
||||
allowedModules: {},
|
||||
communityNodesEnabled: false,
|
||||
defaultLocale: '',
|
||||
endpointWebhook: '',
|
||||
endpointWebhookTest: '',
|
||||
enterprise: {
|
||||
variables: true,
|
||||
},
|
||||
executionMode: '',
|
||||
executionTimeout: 0,
|
||||
hideUsagePage: false,
|
||||
hiringBannerEnabled: false,
|
||||
instanceId: '',
|
||||
isNpmAvailable: false,
|
||||
license: { environment: 'development' },
|
||||
logLevel: 'info',
|
||||
maxExecutionTimeout: 0,
|
||||
oauthCallbackUrls: { oauth1: '', oauth2: '' },
|
||||
onboardingCallPromptEnabled: false,
|
||||
personalizationSurveyEnabled: false,
|
||||
posthog: {
|
||||
apiHost: '',
|
||||
apiKey: '',
|
||||
autocapture: false,
|
||||
debug: false,
|
||||
disableSessionRecording: false,
|
||||
enabled: false,
|
||||
},
|
||||
publicApi: { enabled: false, latestVersion: 0, path: '', swaggerUi: { enabled: false } },
|
||||
pushBackend: 'websocket',
|
||||
saveDataErrorExecution: '',
|
||||
saveDataSuccessExecution: '',
|
||||
saveManualExecutions: false,
|
||||
sso: {
|
||||
ldap: { loginEnabled: false, loginLabel: '' },
|
||||
saml: { loginEnabled: false, loginLabel: '' },
|
||||
},
|
||||
telemetry: {
|
||||
enabled: false,
|
||||
},
|
||||
templates: { enabled: false, host: '' },
|
||||
timezone: '',
|
||||
urlBaseEditor: '',
|
||||
urlBaseWebhook: '',
|
||||
userManagement: {
|
||||
enabled: true,
|
||||
showSetupOnFirstLoad: true,
|
||||
smtpSetup: true,
|
||||
},
|
||||
versionCli: '',
|
||||
versionNotifications: {
|
||||
enabled: true,
|
||||
endpoint: '',
|
||||
infoUrl: '',
|
||||
},
|
||||
workflowCallerPolicyDefaultOption: 'any',
|
||||
workflowTagsDisabled: false,
|
||||
};
|
||||
|
||||
export function routesForSettings(server: Server) {
|
||||
server.get('/rest/settings', (schema: AppSchema) => {
|
||||
return new Response(
|
||||
200,
|
||||
{},
|
||||
{
|
||||
data: defaultSettings,
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -7,4 +7,12 @@ export function routesForUsers(server: Server) {
|
||||
|
||||
return new Response(200, {}, { data });
|
||||
});
|
||||
|
||||
server.get('/rest/login', (schema: AppSchema) => {
|
||||
const model = schema.findBy('user', {
|
||||
isDefaultUser: true,
|
||||
});
|
||||
|
||||
return new Response(200, {}, { data: model?.attrs });
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import { Request, Response, Server } from 'miragejs';
|
||||
import { AppSchema } from '../types';
|
||||
import { jsonParse } from 'n8n-workflow';
|
||||
import { EnvironmentVariable } from '@/Interface';
|
||||
|
||||
export function routesForVariables(server: Server) {
|
||||
server.get('/rest/variables', (schema: AppSchema) => {
|
||||
const { models: data } = schema.all('variable');
|
||||
|
||||
return new Response(200, {}, { data });
|
||||
});
|
||||
|
||||
server.post('/rest/variables', (schema: AppSchema, request: Request) => {
|
||||
const data = schema.create('variable', jsonParse(request.requestBody));
|
||||
|
||||
return new Response(200, {}, { data });
|
||||
});
|
||||
|
||||
server.patch('/rest/variables/:id', (schema: AppSchema, request: Request) => {
|
||||
const data: EnvironmentVariable = jsonParse(request.requestBody);
|
||||
const id = request.params.id;
|
||||
|
||||
const model = schema.find('variable', id);
|
||||
if (model) {
|
||||
model.update(data);
|
||||
}
|
||||
|
||||
return new Response(200, {}, { data: model?.attrs });
|
||||
});
|
||||
|
||||
server.delete('/rest/variables/:id', (schema: AppSchema, request: Request) => {
|
||||
const id = request.params.id;
|
||||
|
||||
const model = schema.find('variable', id);
|
||||
if (model) {
|
||||
model.destroy();
|
||||
}
|
||||
|
||||
return new Response(200, {}, {});
|
||||
});
|
||||
}
|
||||
@@ -1,13 +1,16 @@
|
||||
import { userFactory } from './user';
|
||||
import { credentialFactory } from './credential';
|
||||
import { credentialTypeFactory } from './credentialType';
|
||||
import { variableFactory } from './variable';
|
||||
|
||||
export * from './user';
|
||||
export * from './credential';
|
||||
export * from './credentialType';
|
||||
export * from './variable';
|
||||
|
||||
export const factories = {
|
||||
credential: credentialFactory,
|
||||
credentialType: credentialTypeFactory,
|
||||
user: userFactory,
|
||||
variable: variableFactory,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import { Factory } from 'miragejs';
|
||||
import { faker } from '@faker-js/faker';
|
||||
import type { EnvironmentVariable } from '@/Interface';
|
||||
|
||||
export const variableFactory = Factory.extend<EnvironmentVariable>({
|
||||
id(i: number) {
|
||||
return i;
|
||||
},
|
||||
key() {
|
||||
return `${faker.lorem.word()}`.toUpperCase();
|
||||
},
|
||||
value() {
|
||||
return faker.internet.password(10);
|
||||
},
|
||||
});
|
||||
@@ -10,6 +10,8 @@ export function setupServer() {
|
||||
seeds(server) {
|
||||
server.createList('credentialType', 8);
|
||||
server.create('user', {
|
||||
firstName: 'Nathan',
|
||||
lastName: 'Doe',
|
||||
isDefaultUser: true,
|
||||
});
|
||||
},
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { UserModel } from './user';
|
||||
import { CredentialModel } from './credential';
|
||||
import { CredentialTypeModel } from './credentialType';
|
||||
import { VariableModel } from './variable';
|
||||
|
||||
export const models = {
|
||||
credential: CredentialModel,
|
||||
credentialType: CredentialTypeModel,
|
||||
user: UserModel,
|
||||
variable: VariableModel,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import { EnvironmentVariable } from '@/Interface';
|
||||
import { Model } from 'miragejs';
|
||||
import type { ModelDefinition } from 'miragejs/-types';
|
||||
|
||||
export const VariableModel: ModelDefinition<EnvironmentVariable> = Model.extend({});
|
||||
Reference in New Issue
Block a user