diff --git a/client/src/api/configTemplates.ts b/client/src/api/configTemplates.ts new file mode 100644 index 00000000000..5ca51cf7e2e --- /dev/null +++ b/client/src/api/configTemplates.ts @@ -0,0 +1,25 @@ +import type { components } from "@/api/schema/schema"; + +export type Instance = + | components["schemas"]["UserFileSourceModel"] + | components["schemas"]["UserConcreteObjectStoreModel"]; + +export type TemplateVariable = + | components["schemas"]["TemplateVariableString"] + | components["schemas"]["TemplateVariableInteger"] + | components["schemas"]["TemplateVariablePathComponent"] + | components["schemas"]["TemplateVariableBoolean"]; +export type TemplateSecret = components["schemas"]["TemplateSecret"]; +export type VariableValueType = (string | boolean | number) | undefined; +export type VariableData = { [key: string]: VariableValueType }; +export type SecretData = { [key: string]: string }; + +export interface TemplateSummary { + description: string | null; + hidden?: boolean; + id: string; + name: string | null; + secrets?: TemplateSecret[] | null; + variables?: TemplateVariable[] | null; + version?: number; +} diff --git a/client/src/api/fileSources.ts b/client/src/api/fileSources.ts new file mode 100644 index 00000000000..68935db4573 --- /dev/null +++ b/client/src/api/fileSources.ts @@ -0,0 +1,6 @@ +import { type components } from "@/api/schema"; + +export type FileSourceTemplateSummary = components["schemas"]["FileSourceTemplateSummary"]; +export type FileSourceTemplateSummaries = FileSourceTemplateSummary[]; + +export type UserFileSourceModel = components["schemas"]["UserFileSourceModel"]; diff --git a/client/src/api/objectStores.ts b/client/src/api/objectStores.ts index 0a9089e5df4..b6c1f6c59f7 100644 --- a/client/src/api/objectStores.ts +++ b/client/src/api/objectStores.ts @@ -1,4 +1,9 @@ import { fetcher } from "@/api/schema"; +import type { components } from "@/api/schema/schema"; + +export type UserConcreteObjectStore = components["schemas"]["UserConcreteObjectStoreModel"]; + +export type ObjectStoreTemplateType = "aws_s3" | "azure_blob" | "boto3" | "disk" | "generic_s3"; const getObjectStores = fetcher.path("/api/object_stores").method("get").create(); diff --git a/client/src/api/schema/schema.ts b/client/src/api/schema/schema.ts index 08dc0ec7402..4f98526ffec 100644 --- a/client/src/api/schema/schema.ts +++ b/client/src/api/schema/schema.ts @@ -318,6 +318,24 @@ export interface paths { /** Download */ get: operations["download_api_drs_download__object_id__get"]; }; + "/api/file_source_instances": { + /** Get a list of persisted file source instances defined by the requesting user. */ + get: operations["file_sources__instances_index"]; + /** Create a user-bound object store. */ + post: operations["file_sources__create_instance"]; + }; + "/api/file_source_instances/{user_file_source_id}": { + /** Get a list of persisted file source instances defined by the requesting user. */ + get: operations["file_sources__instances_get"]; + /** Update or upgrade user file source instance. */ + put: operations["file_sources__instances_update"]; + /** Purge user file source instance. */ + delete: operations["file_sources__instances_purge"]; + }; + "/api/file_source_templates": { + /** Get a list of file source templates available to build user defined file sources from */ + get: operations["file_sources__templates_index"]; + }; "/api/folders/{folder_id}/contents": { /** * Returns a list of a folder's contents (files and sub-folders) with additional metadata about the folder. @@ -1256,6 +1274,8 @@ export interface paths { get: operations["object_stores__instances_get"]; /** Update or upgrade user object store instance. */ put: operations["object_stores__instances_update"]; + /** Purge user object store instance. */ + delete: operations["object_stores__instances_purge"]; }; "/api/object_store_templates": { /** Get a list of object store templates available to build user defined object stores from */ @@ -5238,6 +5258,43 @@ export interface components { */ update_time: string; }; + /** FileSourceTemplateSummaries */ + FileSourceTemplateSummaries: components["schemas"]["FileSourceTemplateSummary"][]; + /** FileSourceTemplateSummary */ + FileSourceTemplateSummary: { + /** Description */ + description: string | null; + /** + * Hidden + * @default false + */ + hidden?: boolean; + /** Id */ + id: string; + /** Name */ + name: string | null; + /** Secrets */ + secrets?: components["schemas"]["TemplateSecret"][] | null; + /** + * Type + * @enum {string} + */ + type: "ftp" | "posix" | "s3fs" | "azure"; + /** Variables */ + variables?: + | ( + | components["schemas"]["TemplateVariableString"] + | components["schemas"]["TemplateVariableInteger"] + | components["schemas"]["TemplateVariablePathComponent"] + | components["schemas"]["TemplateVariableBoolean"] + )[] + | null; + /** + * Version + * @default 0 + */ + version?: number; + }; /** FilesSourcePlugin */ FilesSourcePlugin: { /** @@ -9929,13 +9986,6 @@ export interface components { */ up_to_date: boolean; }; - /** ObjectStoreTemplateSecret */ - ObjectStoreTemplateSecret: { - /** Help */ - help: string | null; - /** Name */ - name: string; - }; /** ObjectStoreTemplateSummaries */ ObjectStoreTemplateSummaries: components["schemas"]["ObjectStoreTemplateSummary"][]; /** ObjectStoreTemplateSummary */ @@ -9954,32 +10004,27 @@ export interface components { /** Name */ name: string | null; /** Secrets */ - secrets?: components["schemas"]["ObjectStoreTemplateSecret"][] | null; + secrets?: components["schemas"]["TemplateSecret"][] | null; /** * Type * @enum {string} */ - type: "s3" | "azure_blob" | "disk" | "generic_s3"; + type: "aws_s3" | "azure_blob" | "boto3" | "disk" | "generic_s3"; /** Variables */ - variables?: components["schemas"]["ObjectStoreTemplateVariable"][] | null; + variables?: + | ( + | components["schemas"]["TemplateVariableString"] + | components["schemas"]["TemplateVariableInteger"] + | components["schemas"]["TemplateVariablePathComponent"] + | components["schemas"]["TemplateVariableBoolean"] + )[] + | null; /** * Version * @default 0 */ version?: number; }; - /** ObjectStoreTemplateVariable */ - ObjectStoreTemplateVariable: { - /** Help */ - help: string | null; - /** Name */ - name: string; - /** - * Type - * @enum {string} - */ - type: "string" | "boolean" | "integer"; - }; /** OutputReferenceByLabel */ OutputReferenceByLabel: { /** @@ -11856,6 +11901,92 @@ export interface components { * @enum {string} */ TaskState: "PENDING" | "STARTED" | "RETRY" | "FAILURE" | "SUCCESS"; + /** TemplateSecret */ + TemplateSecret: { + /** Help */ + help: string | null; + /** Label */ + label?: string | null; + /** Name */ + name: string; + }; + /** TemplateVariableBoolean */ + TemplateVariableBoolean: { + /** + * Default + * @default false + */ + default?: boolean; + /** Help */ + help: string | null; + /** Label */ + label?: string | null; + /** Name */ + name: string; + /** + * Type + * @constant + * @enum {string} + */ + type: "boolean"; + }; + /** TemplateVariableInteger */ + TemplateVariableInteger: { + /** + * Default + * @default 0 + */ + default?: number; + /** Help */ + help: string | null; + /** Label */ + label?: string | null; + /** Name */ + name: string; + /** + * Type + * @constant + * @enum {string} + */ + type: "integer"; + }; + /** TemplateVariablePathComponent */ + TemplateVariablePathComponent: { + /** Default */ + default?: string | null; + /** Help */ + help: string | null; + /** Label */ + label?: string | null; + /** Name */ + name: string; + /** + * Type + * @constant + * @enum {string} + */ + type: "path_component"; + }; + /** TemplateVariableString */ + TemplateVariableString: { + /** + * Default + * @default + */ + default?: string; + /** Help */ + help: string | null; + /** Label */ + label?: string | null; + /** Name */ + name: string; + /** + * Type + * @constant + * @enum {string} + */ + type: "string"; + }; /** ToolDataDetails */ ToolDataDetails: { /** @@ -12200,8 +12331,12 @@ export interface components { }; /** UpdateInstancePayload */ UpdateInstancePayload: { + /** Active */ + active?: boolean | null; /** Description */ description?: string | null; + /** Hidden */ + hidden?: boolean | null; /** Name */ name?: string | null; /** Variables */ @@ -12513,12 +12648,16 @@ export interface components { }; /** UserConcreteObjectStoreModel */ UserConcreteObjectStoreModel: { + /** Active */ + active: boolean; /** Badges */ badges: components["schemas"]["BadgeDict"][]; /** Description */ description?: string | null; /** Device */ device?: string | null; + /** Hidden */ + hidden: boolean; /** Id */ id: number | string; /** Name */ @@ -12527,6 +12666,8 @@ export interface components { object_store_id?: string | null; /** Private */ private: boolean; + /** Purged */ + purged: boolean; quota: components["schemas"]["QuotaModel"]; /** Secrets */ secrets: string[]; @@ -12538,7 +12679,7 @@ export interface components { * Type * @enum {string} */ - type: "s3" | "azure_blob" | "disk" | "generic_s3"; + type: "aws_s3" | "azure_blob" | "boto3" | "disk" | "generic_s3"; /** Uuid */ uuid: string; /** Variables */ @@ -12588,6 +12729,40 @@ export interface components { */ id: string; }; + /** UserFileSourceModel */ + UserFileSourceModel: { + /** Active */ + active: boolean; + /** Description */ + description: string | null; + /** Hidden */ + hidden: boolean; + /** Id */ + id: string | number; + /** Name */ + name: string; + /** Purged */ + purged: boolean; + /** Secrets */ + secrets: string[]; + /** Template Id */ + template_id: string; + /** Template Version */ + template_version: number; + /** + * Type + * @enum {string} + */ + type: "ftp" | "posix" | "s3fs" | "azure"; + /** Uri Root */ + uri_root: string; + /** Uuid */ + uuid: string; + /** Variables */ + variables: { + [key: string]: (string | boolean | number) | undefined; + } | null; + }; /** * UserModel * @description User in a transaction context. @@ -14777,6 +14952,169 @@ export interface operations { }; }; }; + file_sources__instances_index: { + /** Get a list of persisted file source instances defined by the requesting user. */ + parameters?: { + /** @description The user ID that will be used to effectively make this API call. Only admins and designated users can make API calls on behalf of other users. */ + header?: { + "run-as"?: string | null; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + content: { + "application/json": components["schemas"]["UserFileSourceModel"][]; + }; + }; + /** @description Validation Error */ + 422: { + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + file_sources__create_instance: { + /** Create a user-bound object store. */ + parameters?: { + /** @description The user ID that will be used to effectively make this API call. Only admins and designated users can make API calls on behalf of other users. */ + header?: { + "run-as"?: string | null; + }; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CreateInstancePayload"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + content: { + "application/json": components["schemas"]["UserFileSourceModel"]; + }; + }; + /** @description Validation Error */ + 422: { + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + file_sources__instances_get: { + /** Get a list of persisted file source instances defined by the requesting user. */ + parameters: { + /** @description The user ID that will be used to effectively make this API call. Only admins and designated users can make API calls on behalf of other users. */ + header?: { + "run-as"?: string | null; + }; + /** @description The index for a persisted UserFileSourceStore object. */ + path: { + user_file_source_id: string; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + content: { + "application/json": components["schemas"]["UserFileSourceModel"]; + }; + }; + /** @description Validation Error */ + 422: { + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + file_sources__instances_update: { + /** Update or upgrade user file source instance. */ + parameters: { + /** @description The user ID that will be used to effectively make this API call. Only admins and designated users can make API calls on behalf of other users. */ + header?: { + "run-as"?: string | null; + }; + /** @description The index for a persisted UserFileSourceStore object. */ + path: { + user_file_source_id: string; + }; + }; + requestBody: { + content: { + "application/json": + | components["schemas"]["UpdateInstanceSecretPayload"] + | components["schemas"]["UpgradeInstancePayload"] + | components["schemas"]["UpdateInstancePayload"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + content: { + "application/json": components["schemas"]["UserFileSourceModel"]; + }; + }; + /** @description Validation Error */ + 422: { + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + file_sources__instances_purge: { + /** Purge user file source instance. */ + parameters: { + /** @description The user ID that will be used to effectively make this API call. Only admins and designated users can make API calls on behalf of other users. */ + header?: { + "run-as"?: string | null; + }; + /** @description The index for a persisted UserFileSourceStore object. */ + path: { + user_file_source_id: string; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + content: { + "application/json": Record; + }; + }; + /** @description Validation Error */ + 422: { + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + file_sources__templates_index: { + /** Get a list of file source templates available to build user defined file sources from */ + parameters?: { + /** @description The user ID that will be used to effectively make this API call. Only admins and designated users can make API calls on behalf of other users. */ + header?: { + "run-as"?: string | null; + }; + }; + responses: { + /** @description A list of the configured file source templates. */ + 200: { + content: { + "application/json": components["schemas"]["FileSourceTemplateSummaries"]; + }; + }; + /** @description Validation Error */ + 422: { + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; index_api_folders__folder_id__contents_get: { /** * Returns a list of a folder's contents (files and sub-folders) with additional metadata about the folder. @@ -20608,6 +20946,33 @@ export interface operations { }; }; }; + object_stores__instances_purge: { + /** Purge user object store instance. */ + parameters: { + /** @description The user ID that will be used to effectively make this API call. Only admins and designated users can make API calls on behalf of other users. */ + header?: { + "run-as"?: string | null; + }; + /** @description The identifier used to index a persisted UserObjectStore object. */ + path: { + user_object_store_id: string; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + content: { + "application/json": Record; + }; + }; + /** @description Validation Error */ + 422: { + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; object_stores__templates_index: { /** Get a list of object store templates available to build user defined object stores from */ parameters?: { @@ -20647,7 +21012,10 @@ export interface operations { /** @description A list of the configured object stores. */ 200: { content: { - "application/json": components["schemas"]["ConcreteObjectStoreModel"][]; + "application/json": ( + | components["schemas"]["ConcreteObjectStoreModel"] + | components["schemas"]["UserConcreteObjectStoreModel"] + )[]; }; }; /** @description Validation Error */ diff --git a/client/src/components/ConfigTemplates/CreateInstance.test.ts b/client/src/components/ConfigTemplates/CreateInstance.test.ts new file mode 100644 index 00000000000..fe4e59ad4a5 --- /dev/null +++ b/client/src/components/ConfigTemplates/CreateInstance.test.ts @@ -0,0 +1,32 @@ +import { shallowMount } from "@vue/test-utils"; +import { getLocalVue } from "tests/jest/helpers"; + +import CreateInstance from "./CreateInstance.vue"; + +const localVue = getLocalVue(true); + +describe("CreateInstance", () => { + it("should render a loading message during loading", async () => { + const wrapper = shallowMount(CreateInstance, { + propsData: { + loading: true, + loadingMessage: "component loading...", + }, + localVue, + }); + const loadingSpan = wrapper.findComponent({ name: "LoadingSpan" }).exists(); + expect(loadingSpan).toBeTruthy(); + }); + + it("should hide a loading message after loading", async () => { + const wrapper = shallowMount(CreateInstance, { + propsData: { + loading: false, + loadingMessage: "component loading...", + }, + localVue, + }); + const loadingSpan = wrapper.findComponent({ name: "LoadingSpan" }).exists(); + expect(loadingSpan).toBeFalsy(); + }); +}); diff --git a/client/src/components/ConfigTemplates/CreateInstance.vue b/client/src/components/ConfigTemplates/CreateInstance.vue new file mode 100644 index 00000000000..334d341bc59 --- /dev/null +++ b/client/src/components/ConfigTemplates/CreateInstance.vue @@ -0,0 +1,21 @@ + + + diff --git a/client/src/components/ConfigTemplates/EditSecretsForm.test.ts b/client/src/components/ConfigTemplates/EditSecretsForm.test.ts new file mode 100644 index 00000000000..3a6252da0e2 --- /dev/null +++ b/client/src/components/ConfigTemplates/EditSecretsForm.test.ts @@ -0,0 +1,36 @@ +import { mount } from "@vue/test-utils"; +import { getLocalVue } from "tests/jest/helpers"; + +import { STANDARD_FILE_SOURCE_TEMPLATE, STANDARD_OBJECT_STORE_TEMPLATE } from "./test_fixtures"; + +import EditSecretsForm from "./EditSecretsForm.vue"; + +const localVue = getLocalVue(true); + +describe("EditSecretsForm", () => { + it("should render a secrets for for file source templates", async () => { + const wrapper = mount(EditSecretsForm, { + propsData: { + template: STANDARD_FILE_SOURCE_TEMPLATE, + title: "Secrets FORM for file source", + }, + localVue, + }); + const titleText = wrapper.find(".portlet-title-text"); + expect(titleText.exists()).toBeTruthy(); + expect(titleText.text()).toEqual("Secrets FORM for file source"); + }); + + it("should render a secrets for for object store templates", async () => { + const wrapper = mount(EditSecretsForm, { + propsData: { + template: STANDARD_OBJECT_STORE_TEMPLATE, + title: "Secrets FORM for object store", + }, + localVue, + }); + const titleText = wrapper.find(".portlet-title-text"); + expect(titleText.exists()).toBeTruthy(); + expect(titleText.text()).toEqual("Secrets FORM for object store"); + }); +}); diff --git a/client/src/components/ConfigTemplates/EditSecretsForm.vue b/client/src/components/ConfigTemplates/EditSecretsForm.vue new file mode 100644 index 00000000000..9baa7ac5f7c --- /dev/null +++ b/client/src/components/ConfigTemplates/EditSecretsForm.vue @@ -0,0 +1,39 @@ + + + diff --git a/client/src/components/ConfigTemplates/InstanceDropdown.test.ts b/client/src/components/ConfigTemplates/InstanceDropdown.test.ts new file mode 100644 index 00000000000..2d41abb5b34 --- /dev/null +++ b/client/src/components/ConfigTemplates/InstanceDropdown.test.ts @@ -0,0 +1,40 @@ +import { shallowMount } from "@vue/test-utils"; +import { getLocalVue } from "tests/jest/helpers"; + +import InstanceDropdown from "./InstanceDropdown.vue"; + +const localVue = getLocalVue(true); + +describe("InstanceDropdown", () => { + it("should render a drop down without upgrade if upgrade unavailable as an option", async () => { + const wrapper = shallowMount(InstanceDropdown, { + propsData: { + prefix: "file-source", + name: "my cool instance", + routeEdit: "/object_store_instance/edit", + routeUpgrade: "/object_store_instance/upgrade", + isUpgradable: false, + }, + localVue, + }); + const menu = wrapper.find(".dropdown-menu"); + const links = menu.findAll("a"); + expect(links.length).toBe(2); + }); + + it("should render a drop down with upgrade if upgrade available as an option", async () => { + const wrapper = shallowMount(InstanceDropdown, { + propsData: { + prefix: "file-source", + name: "my cool instance", + routeEdit: "/object_store_instance/edit", + routeUpgrade: "/object_store_instance/upgrade", + isUpgradable: true, + }, + localVue, + }); + const menu = wrapper.find(".dropdown-menu"); + const links = menu.findAll("a"); + expect(links.length).toBe(3); + }); +}); diff --git a/client/src/components/ConfigTemplates/InstanceDropdown.vue b/client/src/components/ConfigTemplates/InstanceDropdown.vue new file mode 100644 index 00000000000..72089a4e086 --- /dev/null +++ b/client/src/components/ConfigTemplates/InstanceDropdown.vue @@ -0,0 +1,58 @@ + + + diff --git a/client/src/components/ConfigTemplates/InstanceForm.test.ts b/client/src/components/ConfigTemplates/InstanceForm.test.ts new file mode 100644 index 00000000000..546a6670d68 --- /dev/null +++ b/client/src/components/ConfigTemplates/InstanceForm.test.ts @@ -0,0 +1,42 @@ +import { shallowMount } from "@vue/test-utils"; +import { getLocalVue } from "tests/jest/helpers"; + +import InstanceForm from "./InstanceForm.vue"; + +const localVue = getLocalVue(true); + +const inputs: any[] = []; +const SUBMIT_TITLE = "Submit the form!"; + +describe("InstanceForm", () => { + it("should render a loading message and not submit button if inputs is null", async () => { + const wrapper = shallowMount(InstanceForm, { + propsData: { + title: "MY FORM", + loading: true, + inputs: null, + submitTitle: SUBMIT_TITLE, + }, + localVue, + }); + const loadingSpan = wrapper.findComponent({ name: "LoadingSpan" }).exists(); + expect(loadingSpan).toBeTruthy(); + expect(wrapper.find("#submit").exists()).toBeFalsy(); + }); + + it("should hide a loading message after loading", async () => { + const wrapper = shallowMount(InstanceForm, { + propsData: { + title: "MY FORM", + loading: false, + inputs: inputs, + submitTitle: SUBMIT_TITLE, + }, + localVue, + }); + const loadingSpan = wrapper.findComponent({ name: "LoadingSpan" }).exists(); + expect(loadingSpan).toBeFalsy(); + expect(wrapper.find("#submit").exists()).toBeTruthy(); + expect(wrapper.find("#submit").text()).toEqual(SUBMIT_TITLE); + }); +}); diff --git a/client/src/components/ObjectStore/Instances/InstanceForm.vue b/client/src/components/ConfigTemplates/InstanceForm.vue similarity index 79% rename from client/src/components/ObjectStore/Instances/InstanceForm.vue rename to client/src/components/ConfigTemplates/InstanceForm.vue index 97d4525aa4c..7e9bba13e4a 100644 --- a/client/src/components/ObjectStore/Instances/InstanceForm.vue +++ b/client/src/components/ConfigTemplates/InstanceForm.vue @@ -1,4 +1,6 @@ diff --git a/client/src/components/ObjectStore/Instances/UpgradeForm.test.ts b/client/src/components/ObjectStore/Instances/UpgradeForm.test.ts index e15a005edb4..4d6c01f6627 100644 --- a/client/src/components/ObjectStore/Instances/UpgradeForm.test.ts +++ b/client/src/components/ObjectStore/Instances/UpgradeForm.test.ts @@ -15,7 +15,7 @@ const localVue = getLocalVue(true); const router = injectTestRouter(localVue); const STANDARD_TEMPLATE: ObjectStoreTemplateSummary = { - type: "s3", + type: "aws_s3", name: "moo", description: null, variables: [ @@ -46,7 +46,7 @@ const STANDARD_TEMPLATE: ObjectStoreTemplateSummary = { }; const INSTANCE: UserConcreteObjectStore = { - type: "s3", + type: "aws_s3", name: "moo", description: undefined, template_id: "moo", @@ -61,6 +61,9 @@ const INSTANCE: UserConcreteObjectStore = { private: false, id: 4, uuid: "112f889f-72d7-4619-a8e8-510a8c685aa7", + active: true, + hidden: false, + purged: false, }; describe("UpgradeForm", () => { diff --git a/client/src/components/ObjectStore/Instances/UpgradeForm.vue b/client/src/components/ObjectStore/Instances/UpgradeForm.vue index 3b405cc3660..c3285eda662 100644 --- a/client/src/components/ObjectStore/Instances/UpgradeForm.vue +++ b/client/src/components/ObjectStore/Instances/UpgradeForm.vue @@ -1,15 +1,16 @@ diff --git a/client/src/components/ObjectStore/Instances/services.ts b/client/src/components/ObjectStore/Instances/services.ts index c61effa0e79..16a14add79d 100644 --- a/client/src/components/ObjectStore/Instances/services.ts +++ b/client/src/components/ObjectStore/Instances/services.ts @@ -1,4 +1,13 @@ import { fetcher } from "@/api/schema/fetcher"; +import type { UserConcreteObjectStore } from "./types"; + export const create = fetcher.path("/api/object_store_instances").method("post").create(); export const update = fetcher.path("/api/object_store_instances/{user_object_store_id}").method("put").create(); + +export async function hide(instance: UserConcreteObjectStore) { + const payload = { hidden: true }; + const args = { user_object_store_id: String(instance?.id) }; + const { data: objectStore } = await update({ ...args, ...payload }); + return objectStore; +} diff --git a/client/src/components/ObjectStore/Instances/types.ts b/client/src/components/ObjectStore/Instances/types.ts index bd956468c7b..0176eaec757 100644 --- a/client/src/components/ObjectStore/Instances/types.ts +++ b/client/src/components/ObjectStore/Instances/types.ts @@ -2,8 +2,3 @@ import type { components } from "@/api/schema/schema"; export type UserConcreteObjectStore = components["schemas"]["UserConcreteObjectStoreModel"]; export type CreateInstancePayload = components["schemas"]["CreateInstancePayload"]; -export type ObjectStoreTemplateVariable = components["schemas"]["ObjectStoreTemplateVariable"]; -export type ObjectStoreTemplateSecret = components["schemas"]["ObjectStoreTemplateSecret"]; -export type VariableValueType = (string | boolean | number) | undefined; -export type VariableData = { [key: string]: VariableValueType }; -export type SecretData = { [key: string]: string }; diff --git a/client/src/components/ObjectStore/Instances/util.ts b/client/src/components/ObjectStore/Instances/util.ts deleted file mode 100644 index 77b99b11d73..00000000000 --- a/client/src/components/ObjectStore/Instances/util.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { markup } from "@/components/ObjectStore/configurationMarkdown"; - -import type { ObjectStoreTemplateSecret, ObjectStoreTemplateVariable, VariableValueType } from "./types"; - -export function metadataFormEntryName() { - return { - name: "_meta_name", - label: "Name", - type: "text", - optional: false, - help: "Label this new object store a name.", - }; -} - -export function metadataFormEntryDescription() { - return { - name: "_meta_description", - label: "Description", - optional: true, - type: "textarea", - help: "Provide some notes to yourself about this object store - perhaps to remind you how it is configured, where it stores the data, etc..", - }; -} - -export function templateVariableFormEntry(variable: ObjectStoreTemplateVariable, variableValue: VariableValueType) { - return { - name: variable.name, - type: "text", - help: markup(variable.help || "", true), - value: variableValue, - }; -} - -export function templateSecretFormEntry(secret: ObjectStoreTemplateSecret) { - return { - name: secret.name, - type: "password", - help: markup(secret.help || "", true), - value: "", - }; -} diff --git a/client/src/components/ObjectStore/ObjectStoreTypeSpan.vue b/client/src/components/ObjectStore/ObjectStoreTypeSpan.vue index 6672e6a4523..c17682b0cbb 100644 --- a/client/src/components/ObjectStore/ObjectStoreTypeSpan.vue +++ b/client/src/components/ObjectStore/ObjectStoreTypeSpan.vue @@ -1,17 +1,20 @@ diff --git a/client/src/components/ObjectStore/Templates/SelectTemplate.vue b/client/src/components/ObjectStore/Templates/SelectTemplate.vue index 5e99fbb0807..a8e8362eb83 100644 --- a/client/src/components/ObjectStore/Templates/SelectTemplate.vue +++ b/client/src/components/ObjectStore/Templates/SelectTemplate.vue @@ -2,6 +2,7 @@ import type { ObjectStoreTemplateSummaries } from "./types"; import TemplateSummaryPopover from "./TemplateSummaryPopover.vue"; +import SelectTemplate from "@/components/ConfigTemplates/SelectTemplate.vue"; interface SelectTemplateProps { templates: ObjectStoreTemplateSummaries; @@ -23,26 +24,12 @@ async function handleSubmit(templateId: string) {