mirror of
https://github.com/n8n-io/n8n.git
synced 2025-02-02 07:01:30 -08:00
refactor(editor): Migrate WorkflowSettings to setup script and composition API (no-changelog) (#11580)
This commit is contained in:
parent
5c69ba2c44
commit
7326487ab3
|
@ -1,13 +1,10 @@
|
||||||
<script lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { ref, computed, onMounted } from 'vue';
|
||||||
import { mapStores } from 'pinia';
|
import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
import { useToast } from '@/composables/useToast';
|
import { useToast } from '@/composables/useToast';
|
||||||
import type {
|
import type {
|
||||||
ITimeoutHMS,
|
ITimeoutHMS,
|
||||||
IUser,
|
|
||||||
IWorkflowDataUpdate,
|
IWorkflowDataUpdate,
|
||||||
IWorkflowDb,
|
|
||||||
IWorkflowSettings,
|
IWorkflowSettings,
|
||||||
IWorkflowShortResponse,
|
IWorkflowShortResponse,
|
||||||
} from '@/Interface';
|
} from '@/Interface';
|
||||||
|
@ -17,11 +14,9 @@ import {
|
||||||
PLACEHOLDER_EMPTY_WORKFLOW_ID,
|
PLACEHOLDER_EMPTY_WORKFLOW_ID,
|
||||||
WORKFLOW_SETTINGS_MODAL_KEY,
|
WORKFLOW_SETTINGS_MODAL_KEY,
|
||||||
} from '@/constants';
|
} from '@/constants';
|
||||||
|
|
||||||
import type { WorkflowSettings } from 'n8n-workflow';
|
import type { WorkflowSettings } from 'n8n-workflow';
|
||||||
import { deepCopy } from 'n8n-workflow';
|
import { deepCopy } from 'n8n-workflow';
|
||||||
import { useSettingsStore } from '@/stores/settings.store';
|
import { useSettingsStore } from '@/stores/settings.store';
|
||||||
import { useUsersStore } from '@/stores/users.store';
|
|
||||||
import { useRootStore } from '@/stores/root.store';
|
import { useRootStore } from '@/stores/root.store';
|
||||||
import { useWorkflowsEEStore } from '@/stores/workflows.ee.store';
|
import { useWorkflowsEEStore } from '@/stores/workflows.ee.store';
|
||||||
import { useWorkflowsStore } from '@/stores/workflows.store';
|
import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||||
|
@ -30,501 +25,445 @@ import { useExternalHooks } from '@/composables/useExternalHooks';
|
||||||
import { useSourceControlStore } from '@/stores/sourceControl.store';
|
import { useSourceControlStore } from '@/stores/sourceControl.store';
|
||||||
import { ProjectTypes } from '@/types/projects.types';
|
import { ProjectTypes } from '@/types/projects.types';
|
||||||
import { getResourcePermissions } from '@/permissions';
|
import { getResourcePermissions } from '@/permissions';
|
||||||
|
import { useI18n } from '@/composables/useI18n';
|
||||||
|
import { useTelemetry } from '@/composables/useTelemetry';
|
||||||
|
|
||||||
export default defineComponent({
|
const route = useRoute();
|
||||||
name: 'WorkflowSettings',
|
const i18n = useI18n();
|
||||||
components: {
|
const externalHooks = useExternalHooks();
|
||||||
Modal,
|
const toast = useToast();
|
||||||
},
|
const modalBus = createEventBus();
|
||||||
setup() {
|
const telemetry = useTelemetry();
|
||||||
const externalHooks = useExternalHooks();
|
|
||||||
|
|
||||||
return {
|
const rootStore = useRootStore();
|
||||||
externalHooks,
|
const settingsStore = useSettingsStore();
|
||||||
...useToast(),
|
const sourceControlStore = useSourceControlStore();
|
||||||
};
|
const workflowsStore = useWorkflowsStore();
|
||||||
},
|
const workflowsEEStore = useWorkflowsEEStore();
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
isLoading: true,
|
|
||||||
helpTexts: {
|
|
||||||
errorWorkflow: this.$locale.baseText('workflowSettings.helpTexts.errorWorkflow'),
|
|
||||||
timezone: this.$locale.baseText('workflowSettings.helpTexts.timezone'),
|
|
||||||
saveDataErrorExecution: this.$locale.baseText(
|
|
||||||
'workflowSettings.helpTexts.saveDataErrorExecution',
|
|
||||||
),
|
|
||||||
saveDataSuccessExecution: this.$locale.baseText(
|
|
||||||
'workflowSettings.helpTexts.saveDataSuccessExecution',
|
|
||||||
),
|
|
||||||
saveExecutionProgress: this.$locale.baseText(
|
|
||||||
'workflowSettings.helpTexts.saveExecutionProgress',
|
|
||||||
),
|
|
||||||
saveManualExecutions: this.$locale.baseText(
|
|
||||||
'workflowSettings.helpTexts.saveManualExecutions',
|
|
||||||
),
|
|
||||||
executionTimeoutToggle: this.$locale.baseText(
|
|
||||||
'workflowSettings.helpTexts.executionTimeoutToggle',
|
|
||||||
),
|
|
||||||
executionTimeout: this.$locale.baseText('workflowSettings.helpTexts.executionTimeout'),
|
|
||||||
workflowCallerPolicy: this.$locale.baseText(
|
|
||||||
'workflowSettings.helpTexts.workflowCallerPolicy',
|
|
||||||
),
|
|
||||||
workflowCallerIds: this.$locale.baseText('workflowSettings.helpTexts.workflowCallerIds'),
|
|
||||||
},
|
|
||||||
defaultValues: {
|
|
||||||
timezone: 'America/New_York',
|
|
||||||
saveDataErrorExecution: 'all',
|
|
||||||
saveDataSuccessExecution: 'all',
|
|
||||||
saveExecutionProgress: false,
|
|
||||||
saveManualExecutions: false,
|
|
||||||
workflowCallerPolicy: 'workflowsFromSameOwner',
|
|
||||||
},
|
|
||||||
workflowCallerPolicyOptions: [] as Array<{ key: string; value: string }>,
|
|
||||||
saveDataErrorExecutionOptions: [] as Array<{ key: string; value: string }>,
|
|
||||||
saveDataSuccessExecutionOptions: [] as Array<{ key: string; value: string }>,
|
|
||||||
saveExecutionProgressOptions: [] as Array<{ key: string | boolean; value: string }>,
|
|
||||||
saveManualOptions: [] as Array<{ key: string | boolean; value: string }>,
|
|
||||||
executionOrderOptions: [
|
|
||||||
{ key: 'v0', value: 'v0 (legacy)' },
|
|
||||||
{ key: 'v1', value: 'v1 (recommended)' },
|
|
||||||
] as Array<{ key: string; value: string }>,
|
|
||||||
timezones: [] as Array<{ key: string; value: string }>,
|
|
||||||
workflowSettings: {} as IWorkflowSettings,
|
|
||||||
workflows: [] as IWorkflowShortResponse[],
|
|
||||||
executionOrder: 'v0',
|
|
||||||
executionTimeout: 0,
|
|
||||||
maxExecutionTimeout: 0,
|
|
||||||
timeoutHMS: { hours: 0, minutes: 0, seconds: 0 } as ITimeoutHMS,
|
|
||||||
modalBus: createEventBus(),
|
|
||||||
WORKFLOW_SETTINGS_MODAL_KEY,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
computed: {
|
const isLoading = ref(true);
|
||||||
...mapStores(
|
const workflowCallerPolicyOptions = ref<Array<{ key: string; value: string }>>([]);
|
||||||
useRootStore,
|
const saveDataErrorExecutionOptions = ref<Array<{ key: string; value: string }>>([]);
|
||||||
useUsersStore,
|
const saveDataSuccessExecutionOptions = ref<Array<{ key: string; value: string }>>([]);
|
||||||
useSettingsStore,
|
const saveExecutionProgressOptions = ref<Array<{ key: string | boolean; value: string }>>([]);
|
||||||
useSourceControlStore,
|
const saveManualOptions = ref<Array<{ key: string | boolean; value: string }>>([]);
|
||||||
useWorkflowsStore,
|
const executionOrderOptions = ref<Array<{ key: string; value: string }>>([
|
||||||
useWorkflowsEEStore,
|
{ key: 'v0', value: 'v0 (legacy)' },
|
||||||
),
|
{ key: 'v1', value: 'v1 (recommended)' },
|
||||||
readOnlyEnv(): boolean {
|
]);
|
||||||
return this.sourceControlStore.preferences.branchReadOnly;
|
const timezones = ref<Array<{ key: string; value: string }>>([]);
|
||||||
},
|
const workflowSettings = ref<IWorkflowSettings>({} as IWorkflowSettings);
|
||||||
workflowName(): string {
|
const workflows = ref<IWorkflowShortResponse[]>([]);
|
||||||
return this.workflowsStore.workflowName;
|
const executionTimeout = ref(0);
|
||||||
},
|
const maxExecutionTimeout = ref(0);
|
||||||
workflowId(): string {
|
const timeoutHMS = ref<ITimeoutHMS>({ hours: 0, minutes: 0, seconds: 0 });
|
||||||
return this.workflowsStore.workflowId;
|
|
||||||
},
|
|
||||||
workflow(): IWorkflowDb {
|
|
||||||
return this.workflowsStore.getWorkflowById(this.workflowId);
|
|
||||||
},
|
|
||||||
currentUser(): IUser | null {
|
|
||||||
return this.usersStore.currentUser;
|
|
||||||
},
|
|
||||||
isSharingEnabled(): boolean {
|
|
||||||
return this.settingsStore.isEnterpriseFeatureEnabled[EnterpriseEditionFeature.Sharing];
|
|
||||||
},
|
|
||||||
workflowOwnerName(): string {
|
|
||||||
const fallback = this.$locale.baseText(
|
|
||||||
'workflowSettings.callerPolicy.options.workflowsFromSameProject',
|
|
||||||
);
|
|
||||||
|
|
||||||
return this.workflowsEEStore.getWorkflowOwnerName(`${this.workflowId}`, fallback);
|
const helpTexts = computed(() => ({
|
||||||
},
|
errorWorkflow: i18n.baseText('workflowSettings.helpTexts.errorWorkflow'),
|
||||||
workflowPermissions() {
|
timezone: i18n.baseText('workflowSettings.helpTexts.timezone'),
|
||||||
return getResourcePermissions(this.workflow?.scopes).workflow;
|
saveDataErrorExecution: i18n.baseText('workflowSettings.helpTexts.saveDataErrorExecution'),
|
||||||
},
|
saveDataSuccessExecution: i18n.baseText('workflowSettings.helpTexts.saveDataSuccessExecution'),
|
||||||
},
|
saveExecutionProgress: i18n.baseText('workflowSettings.helpTexts.saveExecutionProgress'),
|
||||||
async mounted() {
|
saveManualExecutions: i18n.baseText('workflowSettings.helpTexts.saveManualExecutions'),
|
||||||
this.executionTimeout = this.rootStore.executionTimeout;
|
executionTimeoutToggle: i18n.baseText('workflowSettings.helpTexts.executionTimeoutToggle'),
|
||||||
this.maxExecutionTimeout = this.rootStore.maxExecutionTimeout;
|
executionTimeout: i18n.baseText('workflowSettings.helpTexts.executionTimeout'),
|
||||||
|
workflowCallerPolicy: i18n.baseText('workflowSettings.helpTexts.workflowCallerPolicy'),
|
||||||
|
workflowCallerIds: i18n.baseText('workflowSettings.helpTexts.workflowCallerIds'),
|
||||||
|
}));
|
||||||
|
const defaultValues = computed(() => ({
|
||||||
|
timezone: 'America/New_York',
|
||||||
|
saveDataErrorExecution: 'all',
|
||||||
|
saveDataSuccessExecution: 'all',
|
||||||
|
saveExecutionProgress: false,
|
||||||
|
saveManualExecutions: false,
|
||||||
|
workflowCallerPolicy: 'workflowsFromSameOwner',
|
||||||
|
}));
|
||||||
|
const readOnlyEnv = computed(() => sourceControlStore.preferences.branchReadOnly);
|
||||||
|
const workflowName = computed(() => workflowsStore.workflowName);
|
||||||
|
const workflowId = computed(() => workflowsStore.workflowId);
|
||||||
|
const workflow = computed(() => workflowsStore.getWorkflowById(workflowId.value));
|
||||||
|
const isSharingEnabled = computed(
|
||||||
|
() => settingsStore.isEnterpriseFeatureEnabled[EnterpriseEditionFeature.Sharing],
|
||||||
|
);
|
||||||
|
const workflowOwnerName = computed(() => {
|
||||||
|
const fallback = i18n.baseText('workflowSettings.callerPolicy.options.workflowsFromSameProject');
|
||||||
|
|
||||||
if (!this.workflowId || this.workflowId === PLACEHOLDER_EMPTY_WORKFLOW_ID) {
|
return workflowsEEStore.getWorkflowOwnerName(`${workflowId.value}`, fallback);
|
||||||
this.showMessage({
|
});
|
||||||
title: 'No workflow active',
|
const workflowPermissions = computed(() => getResourcePermissions(workflow.value?.scopes).workflow);
|
||||||
message: 'No workflow active to display settings of.',
|
|
||||||
type: 'error',
|
|
||||||
duration: 0,
|
|
||||||
});
|
|
||||||
this.closeDialog();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.defaultValues.saveDataErrorExecution = this.settingsStore.saveDataErrorExecution;
|
const onCallerIdsInput = (str: string) => {
|
||||||
this.defaultValues.saveDataSuccessExecution = this.settingsStore.saveDataSuccessExecution;
|
workflowSettings.value.callerIds = /^[a-zA-Z0-9,\s]+$/.test(str)
|
||||||
this.defaultValues.saveManualExecutions = this.settingsStore.saveManualExecutions;
|
? str
|
||||||
this.defaultValues.timezone = this.rootStore.timezone;
|
: str.replace(/[^a-zA-Z0-9,\s]/g, '');
|
||||||
this.defaultValues.workflowCallerPolicy = this.settingsStore.workflowCallerPolicyDefaultOption;
|
};
|
||||||
|
|
||||||
this.isLoading = true;
|
const closeDialog = () => {
|
||||||
|
modalBus.emit('close');
|
||||||
|
void externalHooks.run('workflowSettings.dialogVisibleChanged', {
|
||||||
|
dialogVisible: false,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
try {
|
const setTheTimeout = (key: string, value: string) => {
|
||||||
await Promise.all([
|
const time = value ? parseInt(value, 10) : 0;
|
||||||
this.loadWorkflows(),
|
|
||||||
this.loadSaveDataErrorExecutionOptions(),
|
|
||||||
this.loadSaveDataSuccessExecutionOptions(),
|
|
||||||
this.loadSaveExecutionProgressOptions(),
|
|
||||||
this.loadSaveManualOptions(),
|
|
||||||
this.loadTimezones(),
|
|
||||||
this.loadWorkflowCallerPolicyOptions(),
|
|
||||||
]);
|
|
||||||
} catch (error) {
|
|
||||||
this.showError(
|
|
||||||
error,
|
|
||||||
'Problem loading settings',
|
|
||||||
'The following error occurred loading the data:',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const workflowSettings = deepCopy(this.workflowsStore.workflowSettings) as IWorkflowSettings;
|
timeoutHMS.value = {
|
||||||
|
...timeoutHMS.value,
|
||||||
|
[key]: time,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
if (workflowSettings.timezone === undefined) {
|
const loadWorkflowCallerPolicyOptions = async () => {
|
||||||
workflowSettings.timezone = 'DEFAULT';
|
workflowCallerPolicyOptions.value = [
|
||||||
}
|
{
|
||||||
if (workflowSettings.saveDataErrorExecution === undefined) {
|
key: 'none',
|
||||||
workflowSettings.saveDataErrorExecution = 'DEFAULT';
|
value: i18n.baseText('workflowSettings.callerPolicy.options.none'),
|
||||||
}
|
|
||||||
if (workflowSettings.saveDataSuccessExecution === undefined) {
|
|
||||||
workflowSettings.saveDataSuccessExecution = 'DEFAULT';
|
|
||||||
}
|
|
||||||
if (workflowSettings.saveExecutionProgress === undefined) {
|
|
||||||
workflowSettings.saveExecutionProgress = 'DEFAULT';
|
|
||||||
}
|
|
||||||
if (workflowSettings.saveManualExecutions === undefined) {
|
|
||||||
workflowSettings.saveManualExecutions = this.defaultValues.saveManualExecutions;
|
|
||||||
}
|
|
||||||
if (workflowSettings.callerPolicy === undefined) {
|
|
||||||
workflowSettings.callerPolicy = this.defaultValues
|
|
||||||
.workflowCallerPolicy as WorkflowSettings.CallerPolicy;
|
|
||||||
}
|
|
||||||
if (workflowSettings.executionTimeout === undefined) {
|
|
||||||
workflowSettings.executionTimeout = this.rootStore.executionTimeout;
|
|
||||||
}
|
|
||||||
if (workflowSettings.maxExecutionTimeout === undefined) {
|
|
||||||
workflowSettings.maxExecutionTimeout = this.rootStore.maxExecutionTimeout;
|
|
||||||
}
|
|
||||||
if (workflowSettings.executionOrder === undefined) {
|
|
||||||
workflowSettings.executionOrder = 'v0';
|
|
||||||
}
|
|
||||||
|
|
||||||
this.workflowSettings = workflowSettings;
|
|
||||||
this.timeoutHMS = this.convertToHMS(workflowSettings.executionTimeout);
|
|
||||||
this.isLoading = false;
|
|
||||||
|
|
||||||
void this.externalHooks.run('workflowSettings.dialogVisibleChanged', {
|
|
||||||
dialogVisible: true,
|
|
||||||
});
|
|
||||||
this.$telemetry.track('User opened workflow settings', {
|
|
||||||
workflow_id: this.workflowsStore.workflowId,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
onCallerIdsInput(str: string) {
|
|
||||||
this.workflowSettings.callerIds = /^[a-zA-Z0-9,\s]+$/.test(str)
|
|
||||||
? str
|
|
||||||
: str.replace(/[^a-zA-Z0-9,\s]/g, '');
|
|
||||||
},
|
},
|
||||||
closeDialog() {
|
{
|
||||||
this.modalBus.emit('close');
|
key: 'workflowsFromSameOwner',
|
||||||
void this.externalHooks.run('workflowSettings.dialogVisibleChanged', {
|
value: i18n.baseText(
|
||||||
dialogVisible: false,
|
workflow.value.homeProject?.type === ProjectTypes.Personal
|
||||||
});
|
? 'workflowSettings.callerPolicy.options.workflowsFromPersonalProject'
|
||||||
},
|
: 'workflowSettings.callerPolicy.options.workflowsFromTeamProject',
|
||||||
setTimeout(key: string, value: string) {
|
|
||||||
const time = value ? parseInt(value, 10) : 0;
|
|
||||||
|
|
||||||
this.timeoutHMS = {
|
|
||||||
...this.timeoutHMS,
|
|
||||||
[key]: time,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
async loadWorkflowCallerPolicyOptions() {
|
|
||||||
this.workflowCallerPolicyOptions = [
|
|
||||||
{
|
{
|
||||||
key: 'none',
|
|
||||||
value: this.$locale.baseText('workflowSettings.callerPolicy.options.none'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'workflowsFromSameOwner',
|
|
||||||
value: this.$locale.baseText(
|
|
||||||
this.workflow.homeProject?.type === ProjectTypes.Personal
|
|
||||||
? 'workflowSettings.callerPolicy.options.workflowsFromPersonalProject'
|
|
||||||
: 'workflowSettings.callerPolicy.options.workflowsFromTeamProject',
|
|
||||||
{
|
|
||||||
interpolate: {
|
|
||||||
projectName: this.workflowOwnerName,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'workflowsFromAList',
|
|
||||||
value: this.$locale.baseText('workflowSettings.callerPolicy.options.workflowsFromAList'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'any',
|
|
||||||
value: this.$locale.baseText('workflowSettings.callerPolicy.options.any'),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
},
|
|
||||||
async loadSaveDataErrorExecutionOptions() {
|
|
||||||
this.saveDataErrorExecutionOptions.length = 0;
|
|
||||||
this.saveDataErrorExecutionOptions.push.apply(this.saveDataErrorExecutionOptions, [
|
|
||||||
{
|
|
||||||
key: 'DEFAULT',
|
|
||||||
value: this.$locale.baseText(
|
|
||||||
'workflowSettings.saveDataErrorExecutionOptions.defaultSave',
|
|
||||||
{
|
|
||||||
interpolate: {
|
|
||||||
defaultValue:
|
|
||||||
this.defaultValues.saveDataErrorExecution === 'all'
|
|
||||||
? this.$locale.baseText('workflowSettings.saveDataErrorExecutionOptions.save')
|
|
||||||
: this.$locale.baseText(
|
|
||||||
'workflowSettings.saveDataErrorExecutionOptions.doNotSave',
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'all',
|
|
||||||
value: this.$locale.baseText('workflowSettings.saveDataErrorExecutionOptions.save'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'none',
|
|
||||||
value: this.$locale.baseText('workflowSettings.saveDataErrorExecutionOptions.doNotSave'),
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
},
|
|
||||||
async loadSaveDataSuccessExecutionOptions() {
|
|
||||||
this.saveDataSuccessExecutionOptions.length = 0;
|
|
||||||
this.saveDataSuccessExecutionOptions.push.apply(this.saveDataSuccessExecutionOptions, [
|
|
||||||
{
|
|
||||||
key: 'DEFAULT',
|
|
||||||
value: this.$locale.baseText(
|
|
||||||
'workflowSettings.saveDataSuccessExecutionOptions.defaultSave',
|
|
||||||
{
|
|
||||||
interpolate: {
|
|
||||||
defaultValue:
|
|
||||||
this.defaultValues.saveDataSuccessExecution === 'all'
|
|
||||||
? this.$locale.baseText('workflowSettings.saveDataSuccessExecutionOptions.save')
|
|
||||||
: this.$locale.baseText(
|
|
||||||
'workflowSettings.saveDataSuccessExecutionOptions.doNotSave',
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'all',
|
|
||||||
value: this.$locale.baseText('workflowSettings.saveDataSuccessExecutionOptions.save'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'none',
|
|
||||||
value: this.$locale.baseText(
|
|
||||||
'workflowSettings.saveDataSuccessExecutionOptions.doNotSave',
|
|
||||||
),
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
},
|
|
||||||
async loadSaveExecutionProgressOptions() {
|
|
||||||
this.saveExecutionProgressOptions.length = 0;
|
|
||||||
this.saveExecutionProgressOptions.push.apply(this.saveExecutionProgressOptions, [
|
|
||||||
{
|
|
||||||
key: 'DEFAULT',
|
|
||||||
value: this.$locale.baseText(
|
|
||||||
'workflowSettings.saveExecutionProgressOptions.defaultSave',
|
|
||||||
{
|
|
||||||
interpolate: {
|
|
||||||
defaultValue: this.defaultValues.saveExecutionProgress
|
|
||||||
? this.$locale.baseText('workflowSettings.saveExecutionProgressOptions.save')
|
|
||||||
: this.$locale.baseText(
|
|
||||||
'workflowSettings.saveExecutionProgressOptions.doNotSave',
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: true,
|
|
||||||
value: this.$locale.baseText('workflowSettings.saveExecutionProgressOptions.save'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: false,
|
|
||||||
value: this.$locale.baseText('workflowSettings.saveExecutionProgressOptions.doNotSave'),
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
},
|
|
||||||
async loadSaveManualOptions() {
|
|
||||||
this.saveManualOptions.length = 0;
|
|
||||||
this.saveManualOptions.push({
|
|
||||||
key: 'DEFAULT',
|
|
||||||
value: this.$locale.baseText('workflowSettings.saveManualOptions.defaultSave', {
|
|
||||||
interpolate: {
|
interpolate: {
|
||||||
defaultValue: this.defaultValues.saveManualExecutions
|
projectName: workflowOwnerName.value,
|
||||||
? this.$locale.baseText('workflowSettings.saveManualOptions.save')
|
},
|
||||||
: this.$locale.baseText('workflowSettings.saveManualOptions.doNotSave'),
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'workflowsFromAList',
|
||||||
|
value: i18n.baseText('workflowSettings.callerPolicy.options.workflowsFromAList'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'any',
|
||||||
|
value: i18n.baseText('workflowSettings.callerPolicy.options.any'),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
const loadSaveDataErrorExecutionOptions = async () => {
|
||||||
|
saveDataErrorExecutionOptions.value.length = 0;
|
||||||
|
saveDataErrorExecutionOptions.value.push.apply(saveDataErrorExecutionOptions.value, [
|
||||||
|
{
|
||||||
|
key: 'DEFAULT',
|
||||||
|
value: i18n.baseText('workflowSettings.saveDataErrorExecutionOptions.defaultSave', {
|
||||||
|
interpolate: {
|
||||||
|
defaultValue:
|
||||||
|
defaultValues.value.saveDataErrorExecution === 'all'
|
||||||
|
? i18n.baseText('workflowSettings.saveDataErrorExecutionOptions.save')
|
||||||
|
: i18n.baseText('workflowSettings.saveDataErrorExecutionOptions.doNotSave'),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'all',
|
||||||
|
value: i18n.baseText('workflowSettings.saveDataErrorExecutionOptions.save'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'none',
|
||||||
|
value: i18n.baseText('workflowSettings.saveDataErrorExecutionOptions.doNotSave'),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const loadSaveDataSuccessExecutionOptions = async () => {
|
||||||
|
saveDataSuccessExecutionOptions.value.length = 0;
|
||||||
|
saveDataSuccessExecutionOptions.value.push.apply(saveDataSuccessExecutionOptions.value, [
|
||||||
|
{
|
||||||
|
key: 'DEFAULT',
|
||||||
|
value: i18n.baseText('workflowSettings.saveDataSuccessExecutionOptions.defaultSave', {
|
||||||
|
interpolate: {
|
||||||
|
defaultValue:
|
||||||
|
defaultValues.value.saveDataSuccessExecution === 'all'
|
||||||
|
? i18n.baseText('workflowSettings.saveDataSuccessExecutionOptions.save')
|
||||||
|
: i18n.baseText('workflowSettings.saveDataSuccessExecutionOptions.doNotSave'),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'all',
|
||||||
|
value: i18n.baseText('workflowSettings.saveDataSuccessExecutionOptions.save'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'none',
|
||||||
|
value: i18n.baseText('workflowSettings.saveDataSuccessExecutionOptions.doNotSave'),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const loadSaveExecutionProgressOptions = async () => {
|
||||||
|
saveExecutionProgressOptions.value.length = 0;
|
||||||
|
saveExecutionProgressOptions.value.push.apply(saveExecutionProgressOptions.value, [
|
||||||
|
{
|
||||||
|
key: 'DEFAULT',
|
||||||
|
value: i18n.baseText('workflowSettings.saveExecutionProgressOptions.defaultSave', {
|
||||||
|
interpolate: {
|
||||||
|
defaultValue: defaultValues.value.saveExecutionProgress
|
||||||
|
? i18n.baseText('workflowSettings.saveExecutionProgressOptions.save')
|
||||||
|
: i18n.baseText('workflowSettings.saveExecutionProgressOptions.doNotSave'),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: true,
|
||||||
|
value: i18n.baseText('workflowSettings.saveExecutionProgressOptions.save'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: false,
|
||||||
|
value: i18n.baseText('workflowSettings.saveExecutionProgressOptions.doNotSave'),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const loadSaveManualOptions = async () => {
|
||||||
|
saveManualOptions.value.length = 0;
|
||||||
|
saveManualOptions.value.push({
|
||||||
|
key: 'DEFAULT',
|
||||||
|
value: i18n.baseText('workflowSettings.saveManualOptions.defaultSave', {
|
||||||
|
interpolate: {
|
||||||
|
defaultValue: defaultValues.value.saveManualExecutions
|
||||||
|
? i18n.baseText('workflowSettings.saveManualOptions.save')
|
||||||
|
: i18n.baseText('workflowSettings.saveManualOptions.doNotSave'),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
saveManualOptions.value.push({
|
||||||
|
key: true,
|
||||||
|
value: i18n.baseText('workflowSettings.saveManualOptions.save'),
|
||||||
|
});
|
||||||
|
saveManualOptions.value.push({
|
||||||
|
key: false,
|
||||||
|
value: i18n.baseText('workflowSettings.saveManualOptions.doNotSave'),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const loadTimezones = async () => {
|
||||||
|
if (timezones.value.length !== 0) {
|
||||||
|
// Data got already loaded
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const timezonesData = await settingsStore.getTimezones();
|
||||||
|
|
||||||
|
let defaultTimezoneValue = timezonesData[defaultValues.value.timezone] as string | undefined;
|
||||||
|
if (defaultTimezoneValue === undefined) {
|
||||||
|
defaultTimezoneValue = i18n.baseText('workflowSettings.defaultTimezoneNotValid');
|
||||||
|
}
|
||||||
|
|
||||||
|
timezones.value.push({
|
||||||
|
key: 'DEFAULT',
|
||||||
|
value: i18n.baseText('workflowSettings.defaultTimezone', {
|
||||||
|
interpolate: { defaultTimezoneValue },
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
for (const timezone of Object.keys(timezonesData)) {
|
||||||
|
timezones.value.push({
|
||||||
|
key: timezone,
|
||||||
|
value: timezonesData[timezone] as string,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const loadWorkflows = async () => {
|
||||||
|
const workflowsData = (await workflowsStore.fetchAllWorkflows(
|
||||||
|
workflow.value.homeProject?.id,
|
||||||
|
)) as IWorkflowShortResponse[];
|
||||||
|
workflowsData.sort((a, b) => {
|
||||||
|
if (a.name.toLowerCase() < b.name.toLowerCase()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (a.name.toLowerCase() > b.name.toLowerCase()) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
workflowsData.unshift({
|
||||||
|
id: undefined as unknown as string,
|
||||||
|
name: i18n.baseText('workflowSettings.noWorkflow'),
|
||||||
|
} as IWorkflowShortResponse);
|
||||||
|
|
||||||
|
workflows.value = workflowsData;
|
||||||
|
};
|
||||||
|
|
||||||
|
const convertToHMS = (num: number): ITimeoutHMS => {
|
||||||
|
if (num > 0) {
|
||||||
|
const hours = Math.floor(num / 3600);
|
||||||
|
const remainder = num % 3600;
|
||||||
|
const minutes = Math.floor(remainder / 60);
|
||||||
|
const seconds = remainder % 60;
|
||||||
|
return { hours, minutes, seconds };
|
||||||
|
}
|
||||||
|
return { hours: 0, minutes: 0, seconds: 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
const saveSettings = async () => {
|
||||||
|
// Set that the active state should be changed
|
||||||
|
const data: IWorkflowDataUpdate & { settings: IWorkflowSettings } = {
|
||||||
|
settings: workflowSettings.value,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Convert hours, minutes, seconds into seconds for the workflow timeout
|
||||||
|
const { hours, minutes, seconds } = timeoutHMS.value;
|
||||||
|
data.settings.executionTimeout =
|
||||||
|
data.settings.executionTimeout !== -1 ? hours * 3600 + minutes * 60 + seconds : -1;
|
||||||
|
|
||||||
|
if (data.settings.executionTimeout === 0) {
|
||||||
|
toast.showError(
|
||||||
|
new Error(i18n.baseText('workflowSettings.showError.saveSettings1.errorMessage')),
|
||||||
|
i18n.baseText('workflowSettings.showError.saveSettings1.title'),
|
||||||
|
i18n.baseText('workflowSettings.showError.saveSettings1.message') + ':',
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
workflowSettings.value?.maxExecutionTimeout &&
|
||||||
|
data.settings.executionTimeout > workflowSettings.value?.maxExecutionTimeout
|
||||||
|
) {
|
||||||
|
const convertedMaxExecutionTimeout = convertToHMS(workflowSettings.value.maxExecutionTimeout);
|
||||||
|
toast.showError(
|
||||||
|
new Error(
|
||||||
|
i18n.baseText('workflowSettings.showError.saveSettings2.errorMessage', {
|
||||||
|
interpolate: {
|
||||||
|
hours: convertedMaxExecutionTimeout.hours.toString(),
|
||||||
|
minutes: convertedMaxExecutionTimeout.minutes.toString(),
|
||||||
|
seconds: convertedMaxExecutionTimeout.seconds.toString(),
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
});
|
),
|
||||||
this.saveManualOptions.push({
|
i18n.baseText('workflowSettings.showError.saveSettings2.title'),
|
||||||
key: true,
|
i18n.baseText('workflowSettings.showError.saveSettings2.message') + ':',
|
||||||
value: this.$locale.baseText('workflowSettings.saveManualOptions.save'),
|
);
|
||||||
});
|
return;
|
||||||
this.saveManualOptions.push({
|
}
|
||||||
key: false,
|
delete data.settings.maxExecutionTimeout;
|
||||||
value: this.$locale.baseText('workflowSettings.saveManualOptions.doNotSave'),
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
async loadTimezones() {
|
isLoading.value = true;
|
||||||
if (this.timezones.length !== 0) {
|
data.versionId = workflowsStore.workflowVersionId;
|
||||||
// Data got already loaded
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const timezones = await this.settingsStore.getTimezones();
|
try {
|
||||||
|
const workflowData = await workflowsStore.updateWorkflow(String(route.params.name), data);
|
||||||
|
workflowsStore.setWorkflowVersionId(workflowData.versionId);
|
||||||
|
} catch (error) {
|
||||||
|
toast.showError(error, i18n.baseText('workflowSettings.showError.saveSettings3.title'));
|
||||||
|
isLoading.value = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let defaultTimezoneValue = timezones[this.defaultValues.timezone] as string | undefined;
|
// Get the settings without the defaults set for local workflow settings
|
||||||
if (defaultTimezoneValue === undefined) {
|
const localWorkflowSettings = Object.fromEntries(
|
||||||
defaultTimezoneValue = this.$locale.baseText('workflowSettings.defaultTimezoneNotValid');
|
Object.entries(workflowSettings.value).filter(([, value]) => value !== 'DEFAULT'),
|
||||||
}
|
);
|
||||||
|
|
||||||
this.timezones.push({
|
const oldSettings = deepCopy(workflowsStore.workflowSettings);
|
||||||
key: 'DEFAULT',
|
|
||||||
value: this.$locale.baseText('workflowSettings.defaultTimezone', {
|
|
||||||
interpolate: { defaultTimezoneValue },
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
for (const timezone of Object.keys(timezones)) {
|
|
||||||
this.timezones.push({
|
|
||||||
key: timezone,
|
|
||||||
value: timezones[timezone] as string,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async loadWorkflows() {
|
|
||||||
const workflows = (await this.workflowsStore.fetchAllWorkflows(
|
|
||||||
this.workflow.homeProject?.id,
|
|
||||||
)) as IWorkflowShortResponse[];
|
|
||||||
workflows.sort((a, b) => {
|
|
||||||
if (a.name.toLowerCase() < b.name.toLowerCase()) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (a.name.toLowerCase() > b.name.toLowerCase()) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
});
|
|
||||||
|
|
||||||
workflows.unshift({
|
workflowsStore.setWorkflowSettings(localWorkflowSettings);
|
||||||
id: undefined as unknown as string,
|
|
||||||
name: this.$locale.baseText('workflowSettings.noWorkflow'),
|
|
||||||
} as IWorkflowShortResponse);
|
|
||||||
|
|
||||||
this.workflows = workflows;
|
isLoading.value = false;
|
||||||
},
|
|
||||||
async saveSettings() {
|
|
||||||
// Set that the active state should be changed
|
|
||||||
const data: IWorkflowDataUpdate = {
|
|
||||||
settings: this.workflowSettings,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Convert hours, minutes, seconds into seconds for the workflow timeout
|
toast.showMessage({
|
||||||
const { hours, minutes, seconds } = this.timeoutHMS;
|
title: i18n.baseText('workflowSettings.showMessage.saveSettings.title'),
|
||||||
data.settings!.executionTimeout =
|
type: 'success',
|
||||||
data.settings!.executionTimeout !== -1 ? hours * 3600 + minutes * 60 + seconds : -1;
|
});
|
||||||
|
|
||||||
if (data.settings!.executionTimeout === 0) {
|
closeDialog();
|
||||||
this.showError(
|
|
||||||
new Error(this.$locale.baseText('workflowSettings.showError.saveSettings1.errorMessage')),
|
|
||||||
this.$locale.baseText('workflowSettings.showError.saveSettings1.title'),
|
|
||||||
this.$locale.baseText('workflowSettings.showError.saveSettings1.message') + ':',
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// @ts-ignore
|
void externalHooks.run('workflowSettings.saveSettings', { oldSettings });
|
||||||
if (data.settings!.executionTimeout > this.workflowSettings.maxExecutionTimeout) {
|
telemetry.track('User updated workflow settings', {
|
||||||
const { hours, minutes, seconds } = this.convertToHMS(
|
workflow_id: workflowsStore.workflowId,
|
||||||
this.workflowSettings.maxExecutionTimeout as number,
|
});
|
||||||
);
|
};
|
||||||
this.showError(
|
|
||||||
new Error(
|
|
||||||
this.$locale.baseText('workflowSettings.showError.saveSettings2.errorMessage', {
|
|
||||||
interpolate: {
|
|
||||||
hours: hours.toString(),
|
|
||||||
minutes: minutes.toString(),
|
|
||||||
seconds: seconds.toString(),
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
this.$locale.baseText('workflowSettings.showError.saveSettings2.title'),
|
|
||||||
this.$locale.baseText('workflowSettings.showError.saveSettings2.message') + ':',
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
delete data.settings!.maxExecutionTimeout;
|
|
||||||
|
|
||||||
this.isLoading = true;
|
const toggleTimeout = () => {
|
||||||
data.versionId = this.workflowsStore.workflowVersionId;
|
workflowSettings.value.executionTimeout = workflowSettings.value.executionTimeout === -1 ? 0 : -1;
|
||||||
|
};
|
||||||
|
|
||||||
try {
|
onMounted(async () => {
|
||||||
const workflow = await this.workflowsStore.updateWorkflow(
|
executionTimeout.value = rootStore.executionTimeout;
|
||||||
String(this.$route.params.name),
|
maxExecutionTimeout.value = rootStore.maxExecutionTimeout;
|
||||||
data,
|
|
||||||
);
|
|
||||||
this.workflowsStore.setWorkflowVersionId(workflow.versionId);
|
|
||||||
} catch (error) {
|
|
||||||
this.showError(
|
|
||||||
error,
|
|
||||||
this.$locale.baseText('workflowSettings.showError.saveSettings3.title'),
|
|
||||||
);
|
|
||||||
this.isLoading = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the settings without the defaults set for local workflow settings
|
if (!workflowId.value || workflowId.value === PLACEHOLDER_EMPTY_WORKFLOW_ID) {
|
||||||
const localWorkflowSettings = Object.fromEntries(
|
toast.showMessage({
|
||||||
Object.entries(this.workflowSettings).filter(([, value]) => value !== 'DEFAULT'),
|
title: 'No workflow active',
|
||||||
);
|
message: 'No workflow active to display settings of.',
|
||||||
|
type: 'error',
|
||||||
|
duration: 0,
|
||||||
|
});
|
||||||
|
closeDialog();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const oldSettings = deepCopy(this.workflowsStore.workflowSettings);
|
defaultValues.value.saveDataErrorExecution = settingsStore.saveDataErrorExecution;
|
||||||
|
defaultValues.value.saveDataSuccessExecution = settingsStore.saveDataSuccessExecution;
|
||||||
|
defaultValues.value.saveManualExecutions = settingsStore.saveManualExecutions;
|
||||||
|
defaultValues.value.timezone = rootStore.timezone;
|
||||||
|
defaultValues.value.workflowCallerPolicy = settingsStore.workflowCallerPolicyDefaultOption;
|
||||||
|
|
||||||
this.workflowsStore.setWorkflowSettings(localWorkflowSettings);
|
isLoading.value = true;
|
||||||
|
|
||||||
this.isLoading = false;
|
try {
|
||||||
|
await Promise.all([
|
||||||
|
loadWorkflows(),
|
||||||
|
loadSaveDataErrorExecutionOptions(),
|
||||||
|
loadSaveDataSuccessExecutionOptions(),
|
||||||
|
loadSaveExecutionProgressOptions(),
|
||||||
|
loadSaveManualOptions(),
|
||||||
|
loadTimezones(),
|
||||||
|
loadWorkflowCallerPolicyOptions(),
|
||||||
|
]);
|
||||||
|
} catch (error) {
|
||||||
|
toast.showError(
|
||||||
|
error,
|
||||||
|
'Problem loading settings',
|
||||||
|
'The following error occurred loading the data:',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
this.showMessage({
|
const workflowSettingsData = deepCopy(workflowsStore.workflowSettings) as IWorkflowSettings;
|
||||||
title: this.$locale.baseText('workflowSettings.showMessage.saveSettings.title'),
|
|
||||||
type: 'success',
|
|
||||||
});
|
|
||||||
|
|
||||||
this.closeDialog();
|
if (workflowSettingsData.timezone === undefined) {
|
||||||
|
workflowSettingsData.timezone = 'DEFAULT';
|
||||||
|
}
|
||||||
|
if (workflowSettingsData.saveDataErrorExecution === undefined) {
|
||||||
|
workflowSettingsData.saveDataErrorExecution = 'DEFAULT';
|
||||||
|
}
|
||||||
|
if (workflowSettingsData.saveDataSuccessExecution === undefined) {
|
||||||
|
workflowSettingsData.saveDataSuccessExecution = 'DEFAULT';
|
||||||
|
}
|
||||||
|
if (workflowSettingsData.saveExecutionProgress === undefined) {
|
||||||
|
workflowSettingsData.saveExecutionProgress = 'DEFAULT';
|
||||||
|
}
|
||||||
|
if (workflowSettingsData.saveManualExecutions === undefined) {
|
||||||
|
workflowSettingsData.saveManualExecutions = defaultValues.value.saveManualExecutions;
|
||||||
|
}
|
||||||
|
if (workflowSettingsData.callerPolicy === undefined) {
|
||||||
|
workflowSettingsData.callerPolicy = defaultValues.value
|
||||||
|
.workflowCallerPolicy as WorkflowSettings.CallerPolicy;
|
||||||
|
}
|
||||||
|
if (workflowSettingsData.executionTimeout === undefined) {
|
||||||
|
workflowSettingsData.executionTimeout = rootStore.executionTimeout;
|
||||||
|
}
|
||||||
|
if (workflowSettingsData.maxExecutionTimeout === undefined) {
|
||||||
|
workflowSettingsData.maxExecutionTimeout = rootStore.maxExecutionTimeout;
|
||||||
|
}
|
||||||
|
if (workflowSettingsData.executionOrder === undefined) {
|
||||||
|
workflowSettingsData.executionOrder = 'v0';
|
||||||
|
}
|
||||||
|
|
||||||
void this.externalHooks.run('workflowSettings.saveSettings', { oldSettings });
|
workflowSettings.value = workflowSettingsData;
|
||||||
this.$telemetry.track('User updated workflow settings', {
|
timeoutHMS.value = convertToHMS(workflowSettingsData.executionTimeout);
|
||||||
workflow_id: this.workflowsStore.workflowId,
|
isLoading.value = false;
|
||||||
});
|
|
||||||
},
|
void externalHooks.run('workflowSettings.dialogVisibleChanged', {
|
||||||
toggleTimeout() {
|
dialogVisible: true,
|
||||||
this.workflowSettings.executionTimeout =
|
});
|
||||||
this.workflowSettings.executionTimeout === -1 ? 0 : -1;
|
telemetry.track('User opened workflow settings', {
|
||||||
},
|
workflow_id: workflowsStore.workflowId,
|
||||||
convertToHMS(num: number): ITimeoutHMS {
|
});
|
||||||
if (num > 0) {
|
|
||||||
const hours = Math.floor(num / 3600);
|
|
||||||
const remainder = num % 3600;
|
|
||||||
const minutes = Math.floor(remainder / 60);
|
|
||||||
const seconds = remainder % 60;
|
|
||||||
return { hours, minutes, seconds };
|
|
||||||
}
|
|
||||||
return { hours: 0, minutes: 0, seconds: 0 };
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -836,7 +775,7 @@ export default defineComponent({
|
||||||
:disabled="readOnlyEnv || !workflowPermissions.update"
|
:disabled="readOnlyEnv || !workflowPermissions.update"
|
||||||
:model-value="timeoutHMS.hours"
|
:model-value="timeoutHMS.hours"
|
||||||
:min="0"
|
:min="0"
|
||||||
@update:model-value="(value: string) => setTimeout('hours', value)"
|
@update:model-value="(value: string) => setTheTimeout('hours', value)"
|
||||||
>
|
>
|
||||||
<template #append>{{ $locale.baseText('workflowSettings.hours') }}</template>
|
<template #append>{{ $locale.baseText('workflowSettings.hours') }}</template>
|
||||||
</n8n-input>
|
</n8n-input>
|
||||||
|
@ -847,7 +786,7 @@ export default defineComponent({
|
||||||
:model-value="timeoutHMS.minutes"
|
:model-value="timeoutHMS.minutes"
|
||||||
:min="0"
|
:min="0"
|
||||||
:max="60"
|
:max="60"
|
||||||
@update:model-value="(value: string) => setTimeout('minutes', value)"
|
@update:model-value="(value: string) => setTheTimeout('minutes', value)"
|
||||||
>
|
>
|
||||||
<template #append>{{ $locale.baseText('workflowSettings.minutes') }}</template>
|
<template #append>{{ $locale.baseText('workflowSettings.minutes') }}</template>
|
||||||
</n8n-input>
|
</n8n-input>
|
||||||
|
@ -858,7 +797,7 @@ export default defineComponent({
|
||||||
:model-value="timeoutHMS.seconds"
|
:model-value="timeoutHMS.seconds"
|
||||||
:min="0"
|
:min="0"
|
||||||
:max="60"
|
:max="60"
|
||||||
@update:model-value="(value: string) => setTimeout('seconds', value)"
|
@update:model-value="(value: string) => setTheTimeout('seconds', value)"
|
||||||
>
|
>
|
||||||
<template #append>{{ $locale.baseText('workflowSettings.seconds') }}</template>
|
<template #append>{{ $locale.baseText('workflowSettings.seconds') }}</template>
|
||||||
</n8n-input>
|
</n8n-input>
|
||||||
|
|
Loading…
Reference in a new issue