From 7ef27e9c5c1c51525ec63e3fccf15b3d9ef0b5c2 Mon Sep 17 00:00:00 2001 From: Mrika Llabani Date: Mon, 27 Nov 2023 17:17:09 +0100 Subject: [PATCH 01/19] N21-1494 generate api --- src/serverApi/v3/api.ts | 170 +++++++++++++----- .../tool-configuration-status.enum.ts | 10 +- .../factory/toolReferenceResponseFactory.ts | 8 +- 3 files changed, 136 insertions(+), 52 deletions(-) diff --git a/src/serverApi/v3/api.ts b/src/serverApi/v3/api.ts index 30707cf1c6..28ac8943ec 100644 --- a/src/serverApi/v3/api.ts +++ b/src/serverApi/v3/api.ts @@ -720,6 +720,25 @@ export interface ContextExternalToolConfigurationTemplateResponse { */ version: number; } +/** + * + * @export + * @interface ContextExternalToolCountPerContextResponse + */ +export interface ContextExternalToolCountPerContextResponse { + /** + * + * @type {number} + * @memberof ContextExternalToolCountPerContextResponse + */ + course: number; + /** + * + * @type {number} + * @memberof ContextExternalToolCountPerContextResponse + */ + boardElement: number; +} /** * * @export @@ -1633,10 +1652,10 @@ export interface ExternalToolMetadataResponse { schoolExternalToolCount: number; /** * - * @type {SchoolExternalToolMetadataResponseContextExternalToolCountPerContext} + * @type {ContextExternalToolCountPerContextResponse} * @memberof ExternalToolMetadataResponse */ - contextExternalToolCountPerContext: SchoolExternalToolMetadataResponseContextExternalToolCountPerContext; + contextExternalToolCountPerContext: ContextExternalToolCountPerContextResponse; } /** * @@ -3923,29 +3942,10 @@ export interface SchoolExternalToolConfigurationTemplateResponse { export interface SchoolExternalToolMetadataResponse { /** * - * @type {SchoolExternalToolMetadataResponseContextExternalToolCountPerContext} + * @type {ContextExternalToolCountPerContextResponse} * @memberof SchoolExternalToolMetadataResponse */ - contextExternalToolCountPerContext: SchoolExternalToolMetadataResponseContextExternalToolCountPerContext; -} -/** - * - * @export - * @interface SchoolExternalToolMetadataResponseContextExternalToolCountPerContext - */ -export interface SchoolExternalToolMetadataResponseContextExternalToolCountPerContext { - /** - * - * @type {number} - * @memberof SchoolExternalToolMetadataResponseContextExternalToolCountPerContext - */ - course?: number; - /** - * - * @type {number} - * @memberof SchoolExternalToolMetadataResponseContextExternalToolCountPerContext - */ - boardElement?: number; + contextExternalToolCountPerContext: ContextExternalToolCountPerContextResponse; } /** * @@ -4022,10 +4022,10 @@ export interface SchoolExternalToolResponse { toolVersion: number; /** * - * @type {string} + * @type {ToolConfigurationStatusResponse} * @memberof SchoolExternalToolResponse */ - status: SchoolExternalToolResponseStatusEnum; + status: ToolConfigurationStatusResponse; /** * * @type {string} @@ -4033,17 +4033,6 @@ export interface SchoolExternalToolResponse { */ logoUrl?: string; } - -/** - * @export - * @enum {string} - */ -export enum SchoolExternalToolResponseStatusEnum { - Latest = 'Latest', - Outdated = 'Outdated', - Unknown = 'Unknown' -} - /** * * @export @@ -4752,14 +4741,28 @@ export interface TimestampsResponse { /** * * @export - * @enum {string} + * @interface ToolConfigurationStatusResponse */ -export enum ToolConfigurationStatusResponse { - Latest = 'Latest', - Outdated = 'Outdated', - Unknown = 'Unknown' +export interface ToolConfigurationStatusResponse { + /** + * Is the tool disabled for context? + * @type {boolean} + * @memberof ToolConfigurationStatusResponse + */ + isDisabled: boolean; + /** + * Is the tool outdated on school scope, because of non matching versions or required parameter changes on ExternalTool? + * @type {boolean} + * @memberof ToolConfigurationStatusResponse + */ + isOutdatedOnScopeSchool: boolean; + /** + * Is the tool outdated on context scope, because of non matching versions or required parameter changes on SchoolExternalTool? + * @type {boolean} + * @memberof ToolConfigurationStatusResponse + */ + isOutdatedOnScopeContext: boolean; } - /** * * @export @@ -4855,7 +4858,7 @@ export interface ToolReferenceResponse { */ openInNewTab: boolean; /** - * + * The status of the tool * @type {ToolConfigurationStatusResponse} * @memberof ToolReferenceResponse */ @@ -12585,6 +12588,44 @@ export class SubmissionApi extends BaseAPI implements SubmissionApiInterface { */ export const SystemsApiAxiosParamCreator = function (configuration?: Configuration) { return { + /** + * + * @summary Deletes a system. + * @param {string} systemId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + systemControllerDeleteSystem: async (systemId: string, options: any = {}): Promise => { + // verify required parameter 'systemId' is not null or undefined + assertParamExists('systemControllerDeleteSystem', 'systemId', systemId) + const localVarPath = `/systems/{systemId}` + .replace(`{${"systemId"}}`, encodeURIComponent(String(systemId))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + setSearchParams(localVarUrlObj, localVarQueryParameter, options.query); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, /** * This endpoint is used to show users the possible login systems that exist. No sensible data should be returned! * @summary Finds all publicly available systems. @@ -12669,6 +12710,17 @@ export const SystemsApiAxiosParamCreator = function (configuration?: Configurati export const SystemsApiFp = function(configuration?: Configuration) { const localVarAxiosParamCreator = SystemsApiAxiosParamCreator(configuration) return { + /** + * + * @summary Deletes a system. + * @param {string} systemId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async systemControllerDeleteSystem(systemId: string, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.systemControllerDeleteSystem(systemId, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, /** * This endpoint is used to show users the possible login systems that exist. No sensible data should be returned! * @summary Finds all publicly available systems. @@ -12702,6 +12754,16 @@ export const SystemsApiFp = function(configuration?: Configuration) { export const SystemsApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { const localVarFp = SystemsApiFp(configuration) return { + /** + * + * @summary Deletes a system. + * @param {string} systemId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + systemControllerDeleteSystem(systemId: string, options?: any): AxiosPromise { + return localVarFp.systemControllerDeleteSystem(systemId, options).then((request) => request(axios, basePath)); + }, /** * This endpoint is used to show users the possible login systems that exist. No sensible data should be returned! * @summary Finds all publicly available systems. @@ -12732,6 +12794,16 @@ export const SystemsApiFactory = function (configuration?: Configuration, basePa * @interface SystemsApi */ export interface SystemsApiInterface { + /** + * + * @summary Deletes a system. + * @param {string} systemId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof SystemsApiInterface + */ + systemControllerDeleteSystem(systemId: string, options?: any): AxiosPromise; + /** * This endpoint is used to show users the possible login systems that exist. No sensible data should be returned! * @summary Finds all publicly available systems. @@ -12762,6 +12834,18 @@ export interface SystemsApiInterface { * @extends {BaseAPI} */ export class SystemsApi extends BaseAPI implements SystemsApiInterface { + /** + * + * @summary Deletes a system. + * @param {string} systemId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof SystemsApi + */ + public systemControllerDeleteSystem(systemId: string, options?: any) { + return SystemsApiFp(this.configuration).systemControllerDeleteSystem(systemId, options).then((request) => request(this.axios, this.basePath)); + } + /** * This endpoint is used to show users the possible login systems that exist. No sensible data should be returned! * @summary Finds all publicly available systems. diff --git a/src/store/external-tool/tool-configuration-status.enum.ts b/src/store/external-tool/tool-configuration-status.enum.ts index 99b9ed6aa3..74170d30a2 100644 --- a/src/store/external-tool/tool-configuration-status.enum.ts +++ b/src/store/external-tool/tool-configuration-status.enum.ts @@ -1,5 +1,7 @@ -export enum ToolConfigurationStatus { - Latest = "Latest", - Outdated = "Outdated", - Unknown = "Unknown", +export interface ToolConfigurationStatus { + isDisabled: boolean; + + isOutdatedOnScopeSchool: boolean; + + isOutdatedOnScopeContext: boolean; } diff --git a/tests/test-utils/factory/toolReferenceResponseFactory.ts b/tests/test-utils/factory/toolReferenceResponseFactory.ts index 55bc580624..95f62ae1bd 100644 --- a/tests/test-utils/factory/toolReferenceResponseFactory.ts +++ b/tests/test-utils/factory/toolReferenceResponseFactory.ts @@ -1,13 +1,11 @@ -import { - ToolConfigurationStatusResponse, - ToolReferenceResponse, -} from "@/serverApi/v3"; +import { ToolReferenceResponse } from "@/serverApi/v3"; import { Factory } from "fishery"; +import { toolConfigurationStatusFactory } from "./toolConfigurationSatusFactory"; export const toolReferenceResponseFactory = Factory.define(({ sequence }) => ({ contextToolId: `context-external-tool-${sequence}`, - status: ToolConfigurationStatusResponse.Latest, + status: toolConfigurationStatusFactory.build(), openInNewTab: true, displayName: `Tool ${sequence}`, })); From 5cfc828bc27c930b0a1718ed2875e46871e9736d Mon Sep 17 00:00:00 2001 From: Mrika Llabani Date: Mon, 27 Nov 2023 17:19:03 +0100 Subject: [PATCH 02/19] N21-1494 change existing to toolStatusResponse --- .../external-tool-section-utils.composable.ts | 10 ++---- .../external-tool-mappings.composable.ts | 31 +++++++++---------- .../mapper/common-tool.mapper.ts | 21 +++++++------ .../mapper/external-tool.mapper.ts | 4 +-- 4 files changed, 32 insertions(+), 34 deletions(-) diff --git a/src/components/administration/external-tool-section-utils.composable.ts b/src/components/administration/external-tool-section-utils.composable.ts index 21fa44c61b..4f08deca5a 100644 --- a/src/components/administration/external-tool-section-utils.composable.ts +++ b/src/components/administration/external-tool-section-utils.composable.ts @@ -1,9 +1,6 @@ import { DataTableHeader } from "vuetify"; import { SchoolExternalToolItem } from "./school-external-tool-item"; -import { - SchoolExternalTool, - ToolConfigurationStatus, -} from "@/store/external-tool"; +import { SchoolExternalTool } from "@/store/external-tool"; import { ToolConfigurationStatusTranslationMapping } from "@/composables/external-tool-mappings.composable"; import SchoolExternalToolsModule from "@/store/school-external-tools"; @@ -35,10 +32,9 @@ export function useExternalToolsSectionUtils( const schoolExternalTools: SchoolExternalTool[] = schoolExternalToolsModule.getSchoolExternalTools; return schoolExternalTools.map((tool: SchoolExternalTool) => { - const outdated: boolean = - tool.status === ToolConfigurationStatus.Outdated; + const outdated: boolean = tool.status.isOutdatedOnScopeSchool; const statusTranslationKey: string = - ToolConfigurationStatusTranslationMapping[tool.status]; + ToolConfigurationStatusTranslationMapping(tool.status); return { id: tool.id, diff --git a/src/composables/external-tool-mappings.composable.ts b/src/composables/external-tool-mappings.composable.ts index 39e0078181..ef5ccf7814 100644 --- a/src/composables/external-tool-mappings.composable.ts +++ b/src/composables/external-tool-mappings.composable.ts @@ -11,15 +11,20 @@ const BusinessErrorMessageTranslationKeyMap = new Map([ ["tool_param_unknown", "pages.tool.apiError.tool_param_unknown"], ]); -export const ToolConfigurationStatusTranslationMapping: Record< - ToolConfigurationStatus, - string -> = { - [ToolConfigurationStatus.Latest]: "components.externalTools.status.latest", - [ToolConfigurationStatus.Outdated]: - "components.externalTools.status.outdated", - [ToolConfigurationStatus.Unknown]: "components.externalTools.status.unknown", -}; +export function ToolConfigurationStatusTranslationMapping( + toolStatus: ToolConfigurationStatus +) { + if ( + !toolStatus.isOutdatedOnScopeSchool && + !toolStatus.isOutdatedOnScopeContext + ) { + return "components.externalTools.status.latest"; + } else if (toolStatus.isOutdatedOnScopeSchool) { + return "components.externalTools.status.outdated"; + } else { + return "components.externalTools.status.unknown"; + } +} export function useExternalToolMappings() { const getBusinessErrorTranslationKey = ( @@ -43,13 +48,7 @@ export function useExternalToolMappings() { toolStatus: ToolConfigurationStatus ): string => { const translationKey: string | undefined = - ToolConfigurationStatusTranslationMapping[toolStatus]; - - if (!translationKey) { - return ToolConfigurationStatusTranslationMapping[ - ToolConfigurationStatus.Unknown - ]; - } + ToolConfigurationStatusTranslationMapping(toolStatus); return translationKey; }; diff --git a/src/store/external-tool/mapper/common-tool.mapper.ts b/src/store/external-tool/mapper/common-tool.mapper.ts index 28bb899bd1..7c931be756 100644 --- a/src/store/external-tool/mapper/common-tool.mapper.ts +++ b/src/store/external-tool/mapper/common-tool.mapper.ts @@ -49,15 +49,6 @@ export const ToolParamScopeMapping: Record< [CustomParameterResponseScopeEnum.School]: ToolParameterScope.School, }; -export const ToolConfigurationStatusMapping: Record< - ToolConfigurationStatusResponse, - ToolConfigurationStatus -> = { - [ToolConfigurationStatusResponse.Latest]: ToolConfigurationStatus.Latest, - [ToolConfigurationStatusResponse.Outdated]: ToolConfigurationStatus.Outdated, - [ToolConfigurationStatusResponse.Unknown]: ToolConfigurationStatus.Unknown, -}; - export const ToolLaunchRequestMethodMapping: Record< ToolLaunchRequestResponseMethodEnum, ToolLaunchRequestMethodEnum @@ -88,4 +79,16 @@ export class CommonToolMapper { return mapped; } + + static mapToolConfigurationStatus( + status: ToolConfigurationStatusResponse + ): ToolConfigurationStatus { + const mapped: ToolConfigurationStatus = { + isDisabled: status.isDisabled, + isOutdatedOnScopeSchool: status.isOutdatedOnScopeSchool, + isOutdatedOnScopeContext: status.isOutdatedOnScopeContext, + }; + + return mapped; + } } diff --git a/src/store/external-tool/mapper/external-tool.mapper.ts b/src/store/external-tool/mapper/external-tool.mapper.ts index 1b87d4532b..6ab952b8e0 100644 --- a/src/store/external-tool/mapper/external-tool.mapper.ts +++ b/src/store/external-tool/mapper/external-tool.mapper.ts @@ -8,7 +8,7 @@ import { ExternalToolDisplayData } from "../external-tool-display-data"; import { ToolLaunchRequest } from "../tool-launch-request"; import { ToolParameter } from "../tool-parameter"; import { - ToolConfigurationStatusMapping, + CommonToolMapper, ToolLaunchRequestMethodMapping, ToolParamLocationMapping, ToolParamScopeMapping, @@ -50,7 +50,7 @@ export class ExternalToolMapper { const mapped: ExternalToolDisplayData = { contextExternalToolId: response.contextToolId, name: response.displayName, - status: ToolConfigurationStatusMapping[response.status], + status: CommonToolMapper.mapToolConfigurationStatus(response.status), logoUrl: response.logoUrl, openInNewTab: response.openInNewTab, }; From 33840e1e83bdecac5fd29d483dddf54a492dda96 Mon Sep 17 00:00:00 2001 From: Mrika Llabani Date: Mon, 27 Nov 2023 17:19:25 +0100 Subject: [PATCH 03/19] N21-1494 adjust factorys --- .../factory/schoolExternalToolResponseFactory.ts | 8 +++----- .../factory/toolConfigurationSatusFactory.ts | 11 +++++++++++ .../factory/toolConfigurationStatusResponseFactory.ts | 11 +++++++++++ 3 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 tests/test-utils/factory/toolConfigurationSatusFactory.ts create mode 100644 tests/test-utils/factory/toolConfigurationStatusResponseFactory.ts diff --git a/tests/test-utils/factory/schoolExternalToolResponseFactory.ts b/tests/test-utils/factory/schoolExternalToolResponseFactory.ts index f7ccfcb603..ffec68e114 100644 --- a/tests/test-utils/factory/schoolExternalToolResponseFactory.ts +++ b/tests/test-utils/factory/schoolExternalToolResponseFactory.ts @@ -1,8 +1,6 @@ -import { - SchoolExternalToolResponse, - SchoolExternalToolResponseStatusEnum, -} from "@/serverApi/v3"; +import { SchoolExternalToolResponse } from "@/serverApi/v3"; import { Factory } from "fishery"; +import { toolConfigurationStatusResponseFactory } from "./toolConfigurationStatusResponseFactory"; export const schoolExternalToolResponseFactory = Factory.define(({ sequence }) => ({ @@ -10,7 +8,7 @@ export const schoolExternalToolResponseFactory = schoolId: `school-${sequence}`, toolId: `tool-${sequence}`, name: `SchoolExternalTool${sequence}`, - status: SchoolExternalToolResponseStatusEnum.Latest, + status: toolConfigurationStatusResponseFactory.build(), parameters: [], toolVersion: 1, })); diff --git a/tests/test-utils/factory/toolConfigurationSatusFactory.ts b/tests/test-utils/factory/toolConfigurationSatusFactory.ts new file mode 100644 index 0000000000..d5b7377b42 --- /dev/null +++ b/tests/test-utils/factory/toolConfigurationSatusFactory.ts @@ -0,0 +1,11 @@ +import { Factory } from "fishery"; +import { ToolConfigurationStatus } from "@/store/external-tool"; + +export const toolConfigurationStatusFactory = + Factory.define(() => { + return { + isDisabled: false, + isOutdatedOnScopeContext: false, + isOutdatedOnScopeSchool: false, + }; + }); diff --git a/tests/test-utils/factory/toolConfigurationStatusResponseFactory.ts b/tests/test-utils/factory/toolConfigurationStatusResponseFactory.ts new file mode 100644 index 0000000000..73007476d6 --- /dev/null +++ b/tests/test-utils/factory/toolConfigurationStatusResponseFactory.ts @@ -0,0 +1,11 @@ +import { Factory } from "fishery"; +import { ToolConfigurationStatusResponse } from "@/serverApi/v3"; + +export const toolConfigurationStatusResponseFactory = + Factory.define(() => { + return { + isDisabled: false, + isOutdatedOnScopeContext: false, + isOutdatedOnScopeSchool: false, + }; + }); From b94b20ef2b600bb99c6cc422dfeca288201e9525 Mon Sep 17 00:00:00 2001 From: Mrika Llabani Date: Tue, 28 Nov 2023 08:37:29 +0100 Subject: [PATCH 04/19] N21-1494 locales --- .../ExternalToolElement.vue | 15 +++++++++++++-- src/components/rooms/RoomExternalToolCard.vue | 5 +++-- src/locales/de.json | 11 ++++++++--- src/locales/en.json | 14 +++++++++----- src/locales/es.json | 10 +++++++--- src/locales/uk.json | 9 +++++++-- 6 files changed, 47 insertions(+), 17 deletions(-) diff --git a/src/components/feature-board-external-tool-element/ExternalToolElement.vue b/src/components/feature-board-external-tool-element/ExternalToolElement.vue index 441b5663d1..5da941489c 100644 --- a/src/components/feature-board-external-tool-element/ExternalToolElement.vue +++ b/src/components/feature-board-external-tool-element/ExternalToolElement.vue @@ -45,6 +45,7 @@ import { useI18n } from "@/composables/i18n.composable"; import { ExternalToolElementResponse } from "@/serverApi/v3"; -import { ToolConfigurationStatus } from "@/store/external-tool"; import { ContextExternalTool } from "@/store/external-tool/context-external-tool"; import { useBoardFocusHandler, useContentElementState } from "@data-board"; import { @@ -84,6 +84,7 @@ import { import ExternalToolElementAlert from "./ExternalToolElementAlert.vue"; import ExternalToolElementConfigurationDialog from "./ExternalToolElementConfigurationDialog.vue"; import ExternalToolElementMenu from "./ExternalToolElementMenu.vue"; +import { ToolConfigurationStatus } from "../../store/external-tool"; export default defineComponent({ components: { @@ -142,9 +143,18 @@ export default defineComponent({ ); const isToolOutdated: ComputedRef = computed( - () => displayData.value?.status === ToolConfigurationStatus.Outdated + () => + (displayData.value?.status.isOutdatedOnScopeSchool || + displayData.value?.status.isOutdatedOnScopeContext) ?? + false ); + const toolConfigurationStatus: ComputedRef< + ToolConfigurationStatus | undefined + > = computed(() => { + return displayData.value?.status; + }); + const isLoading = computed( () => hasLinkedTool.value && !displayData.value && isDisplayDataLoading.value @@ -214,6 +224,7 @@ export default defineComponent({ isLoading, isToolOutdated, isConfigurationDialogOpen, + toolConfigurationStatus, mdiPuzzleOutline, onMoveElementDown, onMoveElementUp, diff --git a/src/components/rooms/RoomExternalToolCard.vue b/src/components/rooms/RoomExternalToolCard.vue index aae81dfd0f..fd87c46f8c 100644 --- a/src/components/rooms/RoomExternalToolCard.vue +++ b/src/components/rooms/RoomExternalToolCard.vue @@ -35,7 +35,6 @@