Skip to content
Snippets Groups Projects
Verified Commit e7413508 authored by Daniel Göbel's avatar Daniel Göbel
Browse files

Support updating private workflows

#61
parent 2a0b3cb9
No related branches found
No related tags found
1 merge request!55Resolve "Support private Git Repositories"
Showing
with 131 additions and 94 deletions
......@@ -12,9 +12,11 @@ export type { DevWorkflowExecutionIn } from './models/DevWorkflowExecutionIn';
export { DocumentationEnum } from './models/DocumentationEnum';
export type { ErrorDetail } from './models/ErrorDetail';
export type { HTTPValidationError } from './models/HTTPValidationError';
export type { IconUpdateOut } from './models/IconUpdateOut';
export { Status } from './models/Status';
export type { ValidationError } from './models/ValidationError';
export type { WorkflowCredentialsIn } from './models/WorkflowCredentialsIn';
export type { WorkflowCredentialsOut } from './models/WorkflowCredentialsOut';
export type { WorkflowExecutionIn } from './models/WorkflowExecutionIn';
export type { WorkflowExecutionOut } from './models/WorkflowExecutionOut';
export { WorkflowExecutionStatus } from './models/WorkflowExecutionStatus';
......
......@@ -26,10 +26,6 @@ export type DevWorkflowExecutionIn = {
* Token to access the content git repository
*/
token?: (string | null);
/**
* Username belonging to the token. If not provided, it will be parsed from the git repository URL
*/
username?: (string | null);
/**
* Mode of the workflow with an alternative entrypoint
*/
......
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type IconUpdateOut = {
/**
* URL to the uploaded icon
*/
icon_url: string;
};
......@@ -8,9 +8,5 @@ export type WorkflowCredentialsIn = {
* Token to access the content git repository
*/
token: string;
/**
* Username belonging to the token. If not provided, it will be parsed from the git repository URL
*/
username?: (string | null);
};
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type WorkflowCredentialsOut = {
/**
* Token to access the content git repository
*/
token: (string | null);
};
......@@ -30,10 +30,6 @@ export type WorkflowIn = {
* Token to access the content git repository
*/
token?: (string | null);
/**
* Username belonging to the token. If not provided, it will be parsed from the git repository URL
*/
username?: (string | null);
/**
* List of modes with alternative entrypoint the new workflow has
*/
......
......@@ -3,6 +3,7 @@
/* tslint:disable */
/* eslint-disable */
import type { WorkflowCredentialsIn } from '../models/WorkflowCredentialsIn';
import type { WorkflowCredentialsOut } from '../models/WorkflowCredentialsOut';
import type { CancelablePromise } from '../core/CancelablePromise';
import { OpenAPI } from '../core/OpenAPI';
......@@ -11,19 +12,19 @@ import { request as __request } from '../core/request';
export class WorkflowCredentialsService {
/**
* Delete the credentials of a workflow
* Delete the credentials for the repository of a workflow.
* Get the credentials of a workflow
* Get the credentials for the repository of a workflow. Only the developer of a workflow can do this.
*
* Permission "workflow:delete" required.
* Permission "workflow:update" required.
* @param wid ID of a workflow
* @returns void
* @returns WorkflowCredentialsOut Successful Response
* @throws ApiError
*/
public static workflowCredentialsDeleteWorkflowCredentials(
public static workflowCredentialsGetWorkflowCredentials(
wid: string,
): CancelablePromise<void> {
): CancelablePromise<WorkflowCredentialsOut> {
return __request(OpenAPI, {
method: 'DELETE',
method: 'GET',
url: '/workflows/{wid}/credentials',
path: {
'wid': wid,
......@@ -38,7 +39,7 @@ export class WorkflowCredentialsService {
}
/**
* Delete the credentials of a workflow
* Update the credentials of a workflow
* Update the credentials for the repository of a workflow.
*
* Permission "workflow:update" required.
......@@ -68,4 +69,31 @@ export class WorkflowCredentialsService {
});
}
/**
* Delete the credentials of a workflow
* Delete the credentials for the repository of a workflow.
*
* Permission "workflow:delete" required.
* @param wid ID of a workflow
* @returns void
* @throws ApiError
*/
public static workflowCredentialsDeleteWorkflowCredentials(
wid: string,
): CancelablePromise<void> {
return __request(OpenAPI, {
method: 'DELETE',
url: '/workflows/{wid}/credentials',
path: {
'wid': wid,
},
errors: {
400: `Error decoding JWT Token`,
403: `Not authenticated`,
404: `Entity not Found`,
422: `Validation Error`,
},
});
}
}
......@@ -4,6 +4,7 @@
/* eslint-disable */
import type { Body_Workflow_Version_upload_workflow_version_icon } from '../models/Body_Workflow_Version_upload_workflow_version_icon';
import type { DocumentationEnum } from '../models/DocumentationEnum';
import type { IconUpdateOut } from '../models/IconUpdateOut';
import type { Status } from '../models/Status';
import type { WorkflowIn } from '../models/WorkflowIn';
import type { WorkflowOut } from '../models/WorkflowOut';
......@@ -365,20 +366,20 @@ export class WorkflowService {
/**
* Upload icon for workflow version
* Upload an icon for the workflow version.
* Upload an icon for the workflow version and returns the new icon URL.
*
* Permission "workflow:update" required.
* @param wid ID of a workflow
* @param gitCommitHash Git commit git_commit_hash of specific version.
* @param formData
* @returns string Successful Response
* @returns IconUpdateOut Successful Response
* @throws ApiError
*/
public static workflowVersionUploadWorkflowVersionIcon(
wid: string,
gitCommitHash: string,
formData: Body_Workflow_Version_upload_workflow_version_icon,
): CancelablePromise<string> {
): CancelablePromise<IconUpdateOut> {
return __request(OpenAPI, {
method: 'POST',
url: '/workflows/{wid}/versions/{git_commit_hash}/icon',
......
......@@ -4,6 +4,7 @@
/* eslint-disable */
import type { Body_Workflow_Version_upload_workflow_version_icon } from '../models/Body_Workflow_Version_upload_workflow_version_icon';
import type { DocumentationEnum } from '../models/DocumentationEnum';
import type { IconUpdateOut } from '../models/IconUpdateOut';
import type { Status } from '../models/Status';
import type { WorkflowVersion } from '../models/WorkflowVersion';
import type { WorkflowVersionStatus } from '../models/WorkflowVersionStatus';
......@@ -183,20 +184,20 @@ export class WorkflowVersionService {
/**
* Upload icon for workflow version
* Upload an icon for the workflow version.
* Upload an icon for the workflow version and returns the new icon URL.
*
* Permission "workflow:update" required.
* @param wid ID of a workflow
* @param gitCommitHash Git commit git_commit_hash of specific version.
* @param formData
* @returns string Successful Response
* @returns IconUpdateOut Successful Response
* @throws ApiError
*/
public static workflowVersionUploadWorkflowVersionIcon(
wid: string,
gitCommitHash: string,
formData: Body_Workflow_Version_upload_workflow_version_icon,
): CancelablePromise<string> {
): CancelablePromise<IconUpdateOut> {
return __request(OpenAPI, {
method: 'POST',
url: '/workflows/{wid}/versions/{git_commit_hash}/icon',
......
......@@ -54,7 +54,6 @@ const workflow = reactive<WorkflowIn>({
git_commit_hash: "",
initial_version: undefined,
token: undefined,
username: undefined,
modes: [],
});
......
......@@ -33,7 +33,6 @@ const props = defineProps<{
// =============================================================================
const credentials = reactive<WorkflowCredentialsIn>({
token: "",
username: undefined,
});
const formState = reactive<{
......
......@@ -9,7 +9,7 @@ import type {
} from "@/client/workflow";
import BootstrapModal from "@/components/modals/BootstrapModal.vue";
import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
import { WorkflowService } from "@/client/workflow";
import { WorkflowService, WorkflowCredentialsService } from "@/client/workflow";
import {
GitRepository,
requiredRepositoryFiles,
......@@ -59,18 +59,39 @@ const formState = reactive<{
loading: boolean;
checkRepoLoading: boolean;
allowUpload: boolean;
loadCredentials: boolean;
workflowToken?: string;
}>({
loading: false,
checkRepoLoading: false,
allowUpload: false,
validated: false,
missingFiles: [],
loadCredentials: false,
workflowToken: undefined,
});
watch(
() => props.workflow,
() => {
resetForm();
if (props.workflow.private) {
formState.loadCredentials = true;
WorkflowCredentialsService.workflowCredentialsGetWorkflowCredentials(
props.workflow.workflow_id,
)
.then((credentials) => {
formState.workflowToken = credentials.token ?? undefined;
})
.catch(() => {
formState.workflowToken = undefined;
})
.finally(() => {
formState.loadCredentials = false;
});
} else {
formState.workflowToken = undefined;
}
},
);
......@@ -96,21 +117,6 @@ const emit = defineEmits<{
// Functions
// =============================================================================
/*
function iconChanged() {
workflowUpdate.icon = workflowIconInputElement.value?.files?.[0].slice();
if (workflowUpdate.icon != undefined) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
workflowIconElement.value!.src = URL.createObjectURL(
workflowUpdate.icon.slice(),
);
} else {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
workflowIconElement.value!.src = latestVersion.value.icon_url ?? "";
}
}
*/
function modalClosed() {
formState.validated = false;
formState.missingFiles = [];
......@@ -134,12 +140,13 @@ function checkVersionValidity() {
function checkRepository() {
formState.validated = true;
workflowGitCommitHashElement.value?.setCustomValidity("");
if (workflowUpdateForm.value?.checkValidity() && !formState.allowUpload) {
formState.missingFiles = [];
workflowGitCommitHashElement.value?.setCustomValidity("");
const repo = GitRepository.buildRepository(
props.workflow.repository_url,
workflowUpdate.git_commit_hash,
formState.workflowToken,
);
repo
.checkFilesExist(requiredRepositoryFiles, true)
......@@ -250,6 +257,11 @@ onMounted(() => {
target="_blank"
>{{ props.workflow.repository_url }}</a
>
<font-awesome-icon
v-if="props.workflow.private"
class="ms-2"
icon="fa-solid fa-lock"
/>
<img
:src="latestVersion.icon_url ?? undefined"
ref="workflowIconElement"
......@@ -257,37 +269,37 @@ onMounted(() => {
:hidden="!showIcon"
/>
</div>
<div class="mb-3">
<label for="workflowGitCommitInput" class="form-label"
>Git Commit Hash</label
>
<div class="input-group">
<div class="input-group-text">
<font-awesome-icon icon="fa-solid fa-code-commit" />
<div class="row">
<div class="col-8">
<label for="workflowGitCommitInput" class="form-label"
>Git Commit Hash</label
>
<div class="input-group">
<div class="input-group-text">
<font-awesome-icon icon="fa-solid fa-code-commit" />
</div>
<input
type="text"
class="form-control text-lowercase"
id="workflowGitCommitInput"
placeholder="ba8bcd9..."
required
ref="workflowGitCommitHashElement"
maxlength="40"
pattern="[0-9a-f]{40}"
v-model="workflowUpdate.git_commit_hash"
@change="formState.allowUpload = false"
/>
</div>
<div v-if="formState.missingFiles.length > 0" class="text-danger">
The following files are missing in the repository
<ul>
<li v-for="file in formState.missingFiles" :key="file">
{{ file }}
</li>
</ul>
</div>
<input
type="text"
class="form-control text-lowercase"
id="workflowGitCommitInput"
placeholder="ba8bcd9..."
required
ref="workflowGitCommitHashElement"
maxlength="40"
pattern="[0-9a-f]{40}"
v-model="workflowUpdate.git_commit_hash"
@change="formState.allowUpload = false"
/>
</div>
</div>
<div v-if="formState.missingFiles.length > 0" class="text-danger">
The following files are missing in the repository
<ul>
<li v-for="file in formState.missingFiles" :key="file">
{{ file }}
</li>
</ul>
</div>
<div class="row mb-3">
<div class="col-4">
<label for="workflowVersionInput" class="form-label">Version</label>
<div class="input-group">
......@@ -311,22 +323,6 @@ onMounted(() => {
Previous Version: {{ latestVersion.version }}
</div>
</div>
<div class="col-8">
<label for="workflowIconInput" class="form-label"
>Optional Icon</label
>
<input
type="file"
ref="workflowIconInputElement"
accept="image/*"
class="form-control"
id="workflowIconInput"
aria-describedby="iconHelp"
/>
<div id="iconHelp" class="form-text">
If not set, the previous icon will be used
</div>
</div>
</div>
</form>
</template>
......@@ -335,7 +331,7 @@ onMounted(() => {
type="button"
class="btn btn-info me-auto"
@click="checkRepository"
:disabled="formState.allowUpload"
:disabled="formState.allowUpload || formState.loadCredentials"
>
<span
v-if="formState.checkRepoLoading"
......
......@@ -98,9 +98,9 @@ function updateIcon() {
icon: iconUpdate.icon,
},
)
.then((icon_url) => {
.then((response) => {
formState.uploadIcon = true;
emit("icon-updated", props.version, icon_url);
emit("icon-updated", props.version, response.icon_url);
successToast?.show();
updateIconModal?.hide();
})
......
......@@ -100,7 +100,6 @@ function confirmedWorkflowVersionIconUpdate(
version: WorkflowVersion,
icon_url?: string,
) {
console.log("New Url", icon_url);
const wIndex = workflowsState.workflows.findIndex(
(w) => w.workflow_id == version.workflow_id,
);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment