type) {
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/domain/settings/IrisSettings.java b/src/main/java/de/tum/cit/aet/artemis/iris/domain/settings/IrisSettings.java
index 5ca715a2f688..5efb75e76ea0 100644
--- a/src/main/java/de/tum/cit/aet/artemis/iris/domain/settings/IrisSettings.java
+++ b/src/main/java/de/tum/cit/aet/artemis/iris/domain/settings/IrisSettings.java
@@ -49,13 +49,7 @@ public abstract class IrisSettings extends DomainObject {
public abstract void setIrisLectureIngestionSettings(IrisLectureIngestionSubSettings irisLectureIngestionSettings);
- public abstract IrisHestiaSubSettings getIrisHestiaSettings();
-
- public abstract void setIrisHestiaSettings(IrisHestiaSubSettings irisHestiaSettings);
-
public abstract IrisCompetencyGenerationSubSettings getIrisCompetencyGenerationSettings();
public abstract void setIrisCompetencyGenerationSettings(IrisCompetencyGenerationSubSettings irisCompetencyGenerationSubSettings);
-
- public abstract boolean isValid();
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/domain/settings/IrisSubSettings.java b/src/main/java/de/tum/cit/aet/artemis/iris/domain/settings/IrisSubSettings.java
index 16588cf448a5..5288c247e891 100644
--- a/src/main/java/de/tum/cit/aet/artemis/iris/domain/settings/IrisSubSettings.java
+++ b/src/main/java/de/tum/cit/aet/artemis/iris/domain/settings/IrisSubSettings.java
@@ -26,7 +26,6 @@
* IrisSubSettings is an abstract super class for the specific sub settings types.
* Sub Settings are settings for a specific feature of Iris.
* {@link IrisChatSubSettings} are used to specify settings for the chat feature.
- * {@link IrisHestiaSubSettings} are used to specify settings for the Hestia integration.
* {@link IrisCompetencyGenerationSubSettings} are used to specify settings for the competency generation feature.
*
* Also see {@link de.tum.cit.aet.artemis.iris.service.settings.IrisSettingsService} for more information.
@@ -41,7 +40,6 @@
@JsonSubTypes({
@JsonSubTypes.Type(value = IrisChatSubSettings.class, name = "chat"),
@JsonSubTypes.Type(value = IrisLectureIngestionSubSettings.class, name = "lecture-ingestion"),
- @JsonSubTypes.Type(value = IrisHestiaSubSettings.class, name = "hestia"),
@JsonSubTypes.Type(value = IrisCompetencyGenerationSubSettings.class, name = "competency-generation")
})
// @formatter:on
@@ -51,13 +49,12 @@ public abstract class IrisSubSettings extends DomainObject {
@Column(name = "enabled")
private boolean enabled = false;
- @Column(name = "allowed_models")
- @Convert(converter = IrisModelListConverter.class)
- private SortedSet allowedModels = new TreeSet<>();
+ @Column(name = "allowed_variants", nullable = false)
+ @Convert(converter = IrisListConverter.class)
+ private SortedSet allowedVariants = new TreeSet<>();
- @Nullable
- @Column(name = "preferred_model")
- private String preferredModel;
+ @Column(name = "selected_variant", nullable = false)
+ private String selectedVariant;
public boolean isEnabled() {
return enabled;
@@ -67,20 +64,20 @@ public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
- public SortedSet getAllowedModels() {
- return allowedModels;
+ public SortedSet getAllowedVariants() {
+ return allowedVariants;
}
- public void setAllowedModels(SortedSet allowedModels) {
- this.allowedModels = allowedModels;
+ public void setAllowedVariants(SortedSet allowedVariants) {
+ this.allowedVariants = allowedVariants;
}
@Nullable
- public String getPreferredModel() {
- return preferredModel;
+ public String getSelectedVariant() {
+ return selectedVariant;
}
- public void setPreferredModel(@Nullable String preferredModel) {
- this.preferredModel = preferredModel;
+ public void setSelectedVariant(@Nullable String selectedVariant) {
+ this.selectedVariant = selectedVariant;
}
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/domain/settings/IrisSubSettingsType.java b/src/main/java/de/tum/cit/aet/artemis/iris/domain/settings/IrisSubSettingsType.java
index d938134f4555..2a8270d420bc 100644
--- a/src/main/java/de/tum/cit/aet/artemis/iris/domain/settings/IrisSubSettingsType.java
+++ b/src/main/java/de/tum/cit/aet/artemis/iris/domain/settings/IrisSubSettingsType.java
@@ -1,5 +1,5 @@
package de.tum.cit.aet.artemis.iris.domain.settings;
public enum IrisSubSettingsType {
- CHAT, HESTIA, COMPETENCY_GENERATION, LECTURE_INGESTION
+ CHAT, COMPETENCY_GENERATION, LECTURE_INGESTION
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/dto/IrisCombinedChatSubSettingsDTO.java b/src/main/java/de/tum/cit/aet/artemis/iris/dto/IrisCombinedChatSubSettingsDTO.java
index 72d8e599ed70..c5589e824507 100644
--- a/src/main/java/de/tum/cit/aet/artemis/iris/dto/IrisCombinedChatSubSettingsDTO.java
+++ b/src/main/java/de/tum/cit/aet/artemis/iris/dto/IrisCombinedChatSubSettingsDTO.java
@@ -6,10 +6,8 @@
import com.fasterxml.jackson.annotation.JsonInclude;
-import de.tum.cit.aet.artemis.iris.domain.IrisTemplate;
-
@JsonInclude(JsonInclude.Include.NON_EMPTY)
-public record IrisCombinedChatSubSettingsDTO(boolean enabled, Integer rateLimit, Integer rateLimitTimeframeHours, @Nullable Set allowedModels,
- @Nullable String preferredModel, @Nullable IrisTemplate template) {
+public record IrisCombinedChatSubSettingsDTO(boolean enabled, Integer rateLimit, Integer rateLimitTimeframeHours, @Nullable Set allowedVariants,
+ @Nullable String selectedVariant) {
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/dto/IrisCombinedCompetencyGenerationSubSettingsDTO.java b/src/main/java/de/tum/cit/aet/artemis/iris/dto/IrisCombinedCompetencyGenerationSubSettingsDTO.java
index 18ffcbc17b50..414b422e0f64 100644
--- a/src/main/java/de/tum/cit/aet/artemis/iris/dto/IrisCombinedCompetencyGenerationSubSettingsDTO.java
+++ b/src/main/java/de/tum/cit/aet/artemis/iris/dto/IrisCombinedCompetencyGenerationSubSettingsDTO.java
@@ -6,9 +6,6 @@
import com.fasterxml.jackson.annotation.JsonInclude;
-import de.tum.cit.aet.artemis.iris.domain.IrisTemplate;
-
@JsonInclude(JsonInclude.Include.NON_EMPTY)
-public record IrisCombinedCompetencyGenerationSubSettingsDTO(boolean enabled, @Nullable Set allowedModels, @Nullable String preferredModel,
- @Nullable IrisTemplate template) {
+public record IrisCombinedCompetencyGenerationSubSettingsDTO(boolean enabled, @Nullable Set allowedVariants, @Nullable String selectedVariant) {
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/dto/IrisCombinedHestiaSubSettingsDTO.java b/src/main/java/de/tum/cit/aet/artemis/iris/dto/IrisCombinedHestiaSubSettingsDTO.java
deleted file mode 100644
index c70ce4825a92..000000000000
--- a/src/main/java/de/tum/cit/aet/artemis/iris/dto/IrisCombinedHestiaSubSettingsDTO.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package de.tum.cit.aet.artemis.iris.dto;
-
-import java.util.Set;
-
-import jakarta.annotation.Nullable;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-
-import de.tum.cit.aet.artemis.iris.domain.IrisTemplate;
-
-@JsonInclude(JsonInclude.Include.NON_EMPTY)
-public record IrisCombinedHestiaSubSettingsDTO(boolean enabled, @Nullable Set allowedModels, @Nullable String preferredModel, @Nullable IrisTemplate template) {
-}
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/dto/IrisCombinedSettingsDTO.java b/src/main/java/de/tum/cit/aet/artemis/iris/dto/IrisCombinedSettingsDTO.java
index 9353757c782e..355b05ae551a 100644
--- a/src/main/java/de/tum/cit/aet/artemis/iris/dto/IrisCombinedSettingsDTO.java
+++ b/src/main/java/de/tum/cit/aet/artemis/iris/dto/IrisCombinedSettingsDTO.java
@@ -4,5 +4,5 @@
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public record IrisCombinedSettingsDTO(IrisCombinedChatSubSettingsDTO irisChatSettings, IrisCombinedLectureIngestionSubSettingsDTO irisLectureIngestionSettings,
- IrisCombinedHestiaSubSettingsDTO irisHestiaSettings, IrisCombinedCompetencyGenerationSubSettingsDTO irisCompetencyGenerationSettings) {
+ IrisCombinedCompetencyGenerationSubSettingsDTO irisCompetencyGenerationSettings) {
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/repository/IrisHestiaSessionRepository.java b/src/main/java/de/tum/cit/aet/artemis/iris/repository/IrisHestiaSessionRepository.java
deleted file mode 100644
index 22a14bd98bd7..000000000000
--- a/src/main/java/de/tum/cit/aet/artemis/iris/repository/IrisHestiaSessionRepository.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package de.tum.cit.aet.artemis.iris.repository;
-
-import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_IRIS;
-
-import java.util.List;
-
-import org.springframework.context.annotation.Profile;
-import org.springframework.stereotype.Repository;
-
-import de.tum.cit.aet.artemis.core.repository.base.ArtemisJpaRepository;
-import de.tum.cit.aet.artemis.iris.domain.session.IrisHestiaSession;
-
-/**
- * Repository interface for managing {@link IrisHestiaSession} entities.
- * Provides custom queries for finding hestia sessions based on different criteria.
- */
-@Repository
-@Profile(PROFILE_IRIS)
-public interface IrisHestiaSessionRepository extends ArtemisJpaRepository {
-
- /**
- * Finds a list of {@link IrisHestiaSession} based on the exercise and user IDs.
- *
- * @param codeHintId The ID of the code hint.
- * @return A list of hestia sessions sorted by creation date in descending order.
- */
- List findByCodeHintIdOrderByCreationDateDesc(Long codeHintId);
-}
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/repository/IrisSettingsRepository.java b/src/main/java/de/tum/cit/aet/artemis/iris/repository/IrisSettingsRepository.java
index 8c4ffd56068e..4dd037d54c77 100644
--- a/src/main/java/de/tum/cit/aet/artemis/iris/repository/IrisSettingsRepository.java
+++ b/src/main/java/de/tum/cit/aet/artemis/iris/repository/IrisSettingsRepository.java
@@ -29,7 +29,6 @@ public interface IrisSettingsRepository extends ArtemisJpaRepository findAllGlobalSettings();
@@ -43,7 +42,6 @@ default IrisGlobalSettings findGlobalSettingsElseThrow() {
FROM IrisCourseSettings irisSettings
LEFT JOIN FETCH irisSettings.irisChatSettings
LEFT JOIN FETCH irisSettings.irisLectureIngestionSettings
- LEFT JOIN FETCH irisSettings.irisHestiaSettings
LEFT JOIN FETCH irisSettings.irisCompetencyGenerationSettings
WHERE irisSettings.course.id = :courseId
""")
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/repository/IrisTemplateRepository.java b/src/main/java/de/tum/cit/aet/artemis/iris/repository/IrisTemplateRepository.java
deleted file mode 100644
index 2b1a930d7aef..000000000000
--- a/src/main/java/de/tum/cit/aet/artemis/iris/repository/IrisTemplateRepository.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package de.tum.cit.aet.artemis.iris.repository;
-
-import de.tum.cit.aet.artemis.core.repository.base.ArtemisJpaRepository;
-import de.tum.cit.aet.artemis.iris.domain.IrisTemplate;
-
-/**
- * Spring Data repository for the IrisTemplate entity.
- */
-public interface IrisTemplateRepository extends ArtemisJpaRepository {
-
-}
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/service/IrisDefaultTemplateService.java b/src/main/java/de/tum/cit/aet/artemis/iris/service/IrisDefaultTemplateService.java
deleted file mode 100644
index 2a4757596bf1..000000000000
--- a/src/main/java/de/tum/cit/aet/artemis/iris/service/IrisDefaultTemplateService.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package de.tum.cit.aet.artemis.iris.service;
-
-import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_IRIS;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Path;
-import java.util.Optional;
-
-import org.apache.commons.io.IOUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.context.annotation.Profile;
-import org.springframework.core.io.Resource;
-import org.springframework.stereotype.Service;
-
-import de.tum.cit.aet.artemis.core.service.ResourceLoaderService;
-import de.tum.cit.aet.artemis.iris.domain.IrisTemplate;
-
-/**
- * Service that loads default Iris templates from the resources/templates/iris folder.
- */
-@Profile(PROFILE_IRIS)
-@Service
-public class IrisDefaultTemplateService {
-
- private static final Logger log = LoggerFactory.getLogger(IrisDefaultTemplateService.class);
-
- private final ResourceLoaderService resourceLoaderService;
-
- public IrisDefaultTemplateService(ResourceLoaderService resourceLoaderService) {
- this.resourceLoaderService = resourceLoaderService;
- }
-
- /**
- * Loads the default Iris template with the given file name.
- * For example, "chat.hbs" will load the template from "resources/templates/iris/chat.hbs".
- *
- * @param templateFileName The file name of the template to load.
- * @return The loaded Iris template, or an empty template if an IO error occurred.
- */
- public IrisTemplate load(String templateFileName) {
- Path filePath = Path.of("templates", "iris", templateFileName);
- Resource resource = resourceLoaderService.getResource(filePath);
- try {
- String fileContent = IOUtils.toString(resource.getInputStream(), StandardCharsets.UTF_8);
- return new IrisTemplate(fileContent);
- }
- catch (IOException e) {
- log.error("Error while loading Iris template from file: {}", filePath, e);
- return new IrisTemplate("");
- }
- }
-
- /**
- * Loads the global template version from the "resources/templates/iris/template-version.txt" file.
- *
- * @return an Optional containing the version loaded from the file, or an empty Optional if there was an error.
- */
- public Optional loadGlobalTemplateVersion() {
- Path filePath = Path.of("templates", "iris", "template-version.txt");
- Resource resource = resourceLoaderService.getResource(filePath);
- try {
- String fileContent = IOUtils.toString(resource.getInputStream(), StandardCharsets.UTF_8);
- int version = Integer.parseInt(fileContent.trim());
- return Optional.of(version);
- }
- catch (IOException e) {
- log.error("Error while loading global template version from file: {}", filePath, e);
- }
- catch (NumberFormatException e) {
- log.error("Content of {} was not a parseable int!", filePath, e);
- }
- return Optional.empty();
- }
-}
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/service/IrisSessionService.java b/src/main/java/de/tum/cit/aet/artemis/iris/service/IrisSessionService.java
index 41fa1247b739..c37844d9740a 100644
--- a/src/main/java/de/tum/cit/aet/artemis/iris/service/IrisSessionService.java
+++ b/src/main/java/de/tum/cit/aet/artemis/iris/service/IrisSessionService.java
@@ -14,12 +14,10 @@
import de.tum.cit.aet.artemis.iris.domain.message.IrisMessage;
import de.tum.cit.aet.artemis.iris.domain.session.IrisCourseChatSession;
import de.tum.cit.aet.artemis.iris.domain.session.IrisExerciseChatSession;
-import de.tum.cit.aet.artemis.iris.domain.session.IrisHestiaSession;
import de.tum.cit.aet.artemis.iris.domain.session.IrisSession;
import de.tum.cit.aet.artemis.iris.service.session.IrisChatBasedFeatureInterface;
import de.tum.cit.aet.artemis.iris.service.session.IrisCourseChatSessionService;
import de.tum.cit.aet.artemis.iris.service.session.IrisExerciseChatSessionService;
-import de.tum.cit.aet.artemis.iris.service.session.IrisHestiaSessionService;
import de.tum.cit.aet.artemis.iris.service.session.IrisRateLimitedFeatureInterface;
import de.tum.cit.aet.artemis.iris.service.session.IrisSubFeatureInterface;
@@ -36,14 +34,11 @@ public class IrisSessionService {
private final IrisCourseChatSessionService irisCourseChatSessionService;
- private final IrisHestiaSessionService irisHestiaSessionService;
-
public IrisSessionService(UserRepository userRepository, IrisExerciseChatSessionService irisExerciseChatSessionService,
- IrisCourseChatSessionService irisCourseChatSessionService, IrisHestiaSessionService irisHestiaSessionService) {
+ IrisCourseChatSessionService irisCourseChatSessionService) {
this.userRepository = userRepository;
this.irisExerciseChatSessionService = irisExerciseChatSessionService;
this.irisCourseChatSessionService = irisCourseChatSessionService;
- this.irisHestiaSessionService = irisHestiaSessionService;
}
/**
@@ -138,7 +133,6 @@ private IrisSubFeatureWrapper getIrisSessionSubServic
return switch (session) {
case IrisExerciseChatSession chatSession -> (IrisSubFeatureWrapper) new IrisSubFeatureWrapper<>(irisExerciseChatSessionService, chatSession);
case IrisCourseChatSession courseChatSession -> (IrisSubFeatureWrapper) new IrisSubFeatureWrapper<>(irisCourseChatSessionService, courseChatSession);
- case IrisHestiaSession hestiaSession -> (IrisSubFeatureWrapper) new IrisSubFeatureWrapper<>(irisHestiaSessionService, hestiaSession);
case null, default -> throw new BadRequestException("Unknown Iris session type " + session.getClass().getSimpleName());
};
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/service/pyris/PyrisConnectorService.java b/src/main/java/de/tum/cit/aet/artemis/iris/service/pyris/PyrisConnectorService.java
index 785fc59b9ed7..f41de6b6c97d 100644
--- a/src/main/java/de/tum/cit/aet/artemis/iris/service/pyris/PyrisConnectorService.java
+++ b/src/main/java/de/tum/cit/aet/artemis/iris/service/pyris/PyrisConnectorService.java
@@ -19,10 +19,11 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
+import de.tum.cit.aet.artemis.iris.domain.settings.IrisSubSettingsType;
import de.tum.cit.aet.artemis.iris.exception.IrisException;
import de.tum.cit.aet.artemis.iris.exception.IrisForbiddenException;
import de.tum.cit.aet.artemis.iris.exception.IrisInternalPyrisErrorException;
-import de.tum.cit.aet.artemis.iris.service.pyris.dto.PyrisModelDTO;
+import de.tum.cit.aet.artemis.iris.service.pyris.dto.PyrisVariantDTO;
import de.tum.cit.aet.artemis.iris.service.pyris.dto.lectureingestionwebhook.PyrisWebhookLectureIngestionExecutionDTO;
import de.tum.cit.aet.artemis.iris.web.open.PublicPyrisStatusUpdateResource;
@@ -50,13 +51,14 @@ public PyrisConnectorService(@Qualifier("pyrisRestTemplate") RestTemplate restTe
}
/**
- * Requests all available models from Pyris
+ * Requests all available variants from Pyris for a feature
*
- * @return A list of available Models as IrisModelDTO
+ * @param feature The feature to get the variants for
+ * @return A list of available Models as IrisVariantDTO
*/
- public List getOfferedModels() throws PyrisConnectorException {
+ public List getOfferedVariants(IrisSubSettingsType feature) throws PyrisConnectorException {
try {
- var response = restTemplate.getForEntity(pyrisUrl + "/api/v1/models", PyrisModelDTO[].class);
+ var response = restTemplate.getForEntity(pyrisUrl + "/api/v1/pipelines/" + feature.name() + "/variants", PyrisVariantDTO[].class);
if (!response.getStatusCode().is2xxSuccessful() || !response.hasBody()) {
throw new PyrisConnectorException("Could not fetch offered models");
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/service/pyris/dto/PyrisModelDTO.java b/src/main/java/de/tum/cit/aet/artemis/iris/service/pyris/dto/PyrisVariantDTO.java
similarity index 67%
rename from src/main/java/de/tum/cit/aet/artemis/iris/service/pyris/dto/PyrisModelDTO.java
rename to src/main/java/de/tum/cit/aet/artemis/iris/service/pyris/dto/PyrisVariantDTO.java
index 705fada64870..ccfbecf7ee9a 100644
--- a/src/main/java/de/tum/cit/aet/artemis/iris/service/pyris/dto/PyrisModelDTO.java
+++ b/src/main/java/de/tum/cit/aet/artemis/iris/service/pyris/dto/PyrisVariantDTO.java
@@ -3,5 +3,5 @@
import com.fasterxml.jackson.annotation.JsonInclude;
@JsonInclude(JsonInclude.Include.NON_EMPTY)
-public record PyrisModelDTO(String id, String name, String description) {
+public record PyrisVariantDTO(String id, String name, String description) {
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/service/session/IrisCourseChatSessionService.java b/src/main/java/de/tum/cit/aet/artemis/iris/service/session/IrisCourseChatSessionService.java
index a2c404b13103..6dea7a728ca6 100644
--- a/src/main/java/de/tum/cit/aet/artemis/iris/service/session/IrisCourseChatSessionService.java
+++ b/src/main/java/de/tum/cit/aet/artemis/iris/service/session/IrisCourseChatSessionService.java
@@ -116,7 +116,8 @@ public void checkRateLimit(User user) {
*/
@Override
public void requestAndHandleResponse(IrisCourseChatSession session) {
- requestAndHandleResponse(session, "default", null);
+ var variant = irisSettingsService.getCombinedIrisSettingsFor(session.getCourse(), false).irisChatSettings().selectedVariant();
+ requestAndHandleResponse(session, variant, null);
}
private void requestAndHandleResponse(IrisCourseChatSession session, String variant, CompetencyJol competencyJol) {
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/service/session/IrisExerciseChatSessionService.java b/src/main/java/de/tum/cit/aet/artemis/iris/service/session/IrisExerciseChatSessionService.java
index cec0a9322134..47e0da357ea9 100644
--- a/src/main/java/de/tum/cit/aet/artemis/iris/service/session/IrisExerciseChatSessionService.java
+++ b/src/main/java/de/tum/cit/aet/artemis/iris/service/session/IrisExerciseChatSessionService.java
@@ -146,9 +146,8 @@ public void requestAndHandleResponse(IrisExerciseChatSession session) {
var exercise = programmingExerciseRepository.findByIdWithTemplateAndSolutionParticipationElseThrow(chatSession.getExercise().getId());
var latestSubmission = getLatestSubmissionIfExists(exercise, chatSession.getUser());
- // TODO: Use settings to determine the variant
- // var irisSettings = irisSettingsService.getCombinedIrisSettingsFor(chatSession.getExercise(), false);
- pyrisPipelineService.executeExerciseChatPipeline("default", latestSubmission, exercise, chatSession);
+ var variant = irisSettingsService.getCombinedIrisSettingsFor(session.getExercise(), false).irisChatSettings().selectedVariant();
+ pyrisPipelineService.executeExerciseChatPipeline(variant, latestSubmission, exercise, chatSession);
}
private Optional getLatestSubmissionIfExists(ProgrammingExercise exercise, User user) {
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/service/session/IrisHestiaSessionService.java b/src/main/java/de/tum/cit/aet/artemis/iris/service/session/IrisHestiaSessionService.java
deleted file mode 100644
index 6762b6d23d43..000000000000
--- a/src/main/java/de/tum/cit/aet/artemis/iris/service/session/IrisHestiaSessionService.java
+++ /dev/null
@@ -1,113 +0,0 @@
-package de.tum.cit.aet.artemis.iris.service.session;
-
-import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_IRIS;
-
-import java.time.ZonedDateTime;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.context.annotation.Profile;
-import org.springframework.stereotype.Service;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-
-import de.tum.cit.aet.artemis.core.domain.User;
-import de.tum.cit.aet.artemis.core.security.Role;
-import de.tum.cit.aet.artemis.core.service.AuthorizationCheckService;
-import de.tum.cit.aet.artemis.iris.domain.session.IrisHestiaSession;
-import de.tum.cit.aet.artemis.iris.domain.settings.IrisSubSettingsType;
-import de.tum.cit.aet.artemis.iris.repository.IrisHestiaSessionRepository;
-import de.tum.cit.aet.artemis.iris.repository.IrisSessionRepository;
-import de.tum.cit.aet.artemis.iris.service.pyris.PyrisConnectorService;
-import de.tum.cit.aet.artemis.iris.service.settings.IrisSettingsService;
-import de.tum.cit.aet.artemis.programming.domain.ProgrammingExercise;
-import de.tum.cit.aet.artemis.programming.domain.hestia.CodeHint;
-
-/**
- * Service to handle the Hestia integration of Iris.
- */
-@Service
-@Profile(PROFILE_IRIS)
-public class IrisHestiaSessionService implements IrisButtonBasedFeatureInterface {
-
- private static final Logger log = LoggerFactory.getLogger(IrisHestiaSessionService.class);
-
- private final IrisSettingsService irisSettingsService;
-
- private final AuthorizationCheckService authCheckService;
-
- private final IrisSessionRepository irisSessionRepository;
-
- private final IrisHestiaSessionRepository irisHestiaSessionRepository;
-
- public IrisHestiaSessionService(PyrisConnectorService pyrisConnectorService, IrisSettingsService irisSettingsService, AuthorizationCheckService authCheckService,
- IrisSessionRepository irisSessionRepository, IrisHestiaSessionRepository irisHestiaSessionRepository) {
- this.irisSettingsService = irisSettingsService;
- this.authCheckService = authCheckService;
- this.irisSessionRepository = irisSessionRepository;
- this.irisHestiaSessionRepository = irisHestiaSessionRepository;
- }
-
- /**
- * Creates a new Iris session for the given code hint.
- * If there is already an existing session for the code hint from the last hour, it will be returned instead.
- *
- * @param codeHint The code hint to create the session for
- * @return The Iris session for the code hint
- */
- public IrisHestiaSession getOrCreateSession(CodeHint codeHint) {
- var existingSessions = irisHestiaSessionRepository.findByCodeHintIdOrderByCreationDateDesc(codeHint.getId());
- // Return the newest session if there is one and it is not older than 1 hour
- if (!existingSessions.isEmpty() && existingSessions.getFirst().getCreationDate().plusHours(1).isAfter(ZonedDateTime.now())) {
- checkHasAccessTo(null, existingSessions.getFirst());
- return existingSessions.getFirst();
- }
-
- // Otherwise create a new session
- var irisSession = new IrisHestiaSession();
- irisSession.setCodeHint(codeHint);
- checkHasAccessTo(null, irisSession);
- irisSession = irisSessionRepository.save(irisSession);
- return irisSession;
- }
-
- @JsonInclude(JsonInclude.Include.NON_EMPTY)
- record HestiaDTO(CodeHint codeHint, IrisHestiaSession session, ProgrammingExercise exercise) {
- }
-
- /**
- * Generates the description and content for a code hint.
- * It does not directly save the code hint, but instead returns it with the generated description and content.
- * This way the instructor can still modify the code hint before saving it or discard the changes.
- *
- * @param session The Iris session to generate the description for
- * @return The code hint with the generated description and content
- */
- @Override
- public CodeHint executeRequest(IrisHestiaSession session) {
- // TODO: Re-add in a future PR. Remember to reenable the test cases!
- return null;
- }
-
- /**
- * Checks if the user has at least the given role for the exercise of the code hint.
- *
- * @param user The user to check the access for
- * @param session The Iris session to check the access for
- */
- @Override
- public void checkHasAccessTo(User user, IrisHestiaSession session) {
- var exercise = session.getCodeHint().getExercise();
- authCheckService.checkHasAtLeastRoleForExerciseElseThrow(Role.EDITOR, exercise, user);
- }
-
- /**
- * Not supported for Iris Hestia sessions.
- *
- * @param session The session to get a message for
- */
- @Override
- public void checkIsFeatureActivatedFor(IrisHestiaSession session) {
- irisSettingsService.isEnabledForElseThrow(IrisSubSettingsType.HESTIA, session.getCodeHint().getExercise());
- }
-}
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/service/settings/IrisSettingsService.java b/src/main/java/de/tum/cit/aet/artemis/iris/service/settings/IrisSettingsService.java
index 39bb14ff31cd..bf9d4a8d35d3 100644
--- a/src/main/java/de/tum/cit/aet/artemis/iris/service/settings/IrisSettingsService.java
+++ b/src/main/java/de/tum/cit/aet/artemis/iris/service/settings/IrisSettingsService.java
@@ -9,7 +9,8 @@
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Objects;
-import java.util.Optional;
+import java.util.Set;
+import java.util.TreeSet;
import java.util.function.Supplier;
import org.springframework.boot.context.event.ApplicationReadyEvent;
@@ -24,20 +25,17 @@
import de.tum.cit.aet.artemis.core.exception.ConflictException;
import de.tum.cit.aet.artemis.core.service.AuthorizationCheckService;
import de.tum.cit.aet.artemis.exercise.domain.Exercise;
-import de.tum.cit.aet.artemis.iris.domain.IrisTemplate;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisChatSubSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisCompetencyGenerationSubSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisCourseSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisExerciseSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisGlobalSettings;
-import de.tum.cit.aet.artemis.iris.domain.settings.IrisHestiaSubSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisLectureIngestionSubSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisSubSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisSubSettingsType;
import de.tum.cit.aet.artemis.iris.dto.IrisCombinedSettingsDTO;
import de.tum.cit.aet.artemis.iris.repository.IrisSettingsRepository;
-import de.tum.cit.aet.artemis.iris.service.IrisDefaultTemplateService;
/**
* Service for managing {@link IrisSettings}.
@@ -54,34 +52,14 @@ public class IrisSettingsService {
private final IrisSubSettingsService irisSubSettingsService;
- private final IrisDefaultTemplateService irisDefaultTemplateService;
-
private final AuthorizationCheckService authCheckService;
- public IrisSettingsService(IrisSettingsRepository irisSettingsRepository, IrisSubSettingsService irisSubSettingsService, IrisDefaultTemplateService irisDefaultTemplateService,
- AuthorizationCheckService authCheckService) {
+ public IrisSettingsService(IrisSettingsRepository irisSettingsRepository, IrisSubSettingsService irisSubSettingsService, AuthorizationCheckService authCheckService) {
this.irisSettingsRepository = irisSettingsRepository;
this.irisSubSettingsService = irisSubSettingsService;
- this.irisDefaultTemplateService = irisDefaultTemplateService;
this.authCheckService = authCheckService;
}
- private Optional loadGlobalTemplateVersion() {
- return irisDefaultTemplateService.loadGlobalTemplateVersion();
- }
-
- private IrisTemplate loadDefaultChatTemplate() {
- return irisDefaultTemplateService.load("chat.hbs");
- }
-
- private IrisTemplate loadDefaultHestiaTemplate() {
- return irisDefaultTemplateService.load("hestia.hbs");
- }
-
- private IrisTemplate loadDefaultCompetencyGenerationTemplate() {
- return irisDefaultTemplateService.load("competency-generation.hbs");
- }
-
/**
* Hooks into the {@link ApplicationReadyEvent} and creates or updates the global IrisSettings object on startup.
*
@@ -98,10 +76,6 @@ public void execute(ApplicationReadyEvent event) throws Exception {
if (allGlobalSettings.size() > 1) {
var maxIdSettings = allGlobalSettings.stream().max(Comparator.comparingLong(IrisSettings::getId)).orElseThrow();
allGlobalSettings.stream().filter(settings -> !Objects.equals(settings.getId(), maxIdSettings.getId())).forEach(irisSettingsRepository::delete);
- autoUpdateGlobalSettings(maxIdSettings);
- }
- else {
- autoUpdateGlobalSettings(allGlobalSettings.stream().findFirst().get());
}
}
@@ -110,46 +84,20 @@ public void execute(ApplicationReadyEvent event) throws Exception {
*/
private void createInitialGlobalSettings() {
var settings = new IrisGlobalSettings();
- settings.setCurrentVersion(loadGlobalTemplateVersion().orElse(0));
initializeIrisChatSettings(settings);
initializeIrisLectureIngestionSettings(settings);
- initializeIrisHestiaSettings(settings);
initializeIrisCompetencyGenerationSettings(settings);
irisSettingsRepository.save(settings);
}
- /**
- * Auto updates the global IrisSettings object if the current version is outdated.
- *
- * @param settings The global IrisSettings object to update
- */
- private void autoUpdateGlobalSettings(IrisGlobalSettings settings) {
- Optional globalVersion = loadGlobalTemplateVersion();
- if (globalVersion.isEmpty() || settings.getCurrentVersion() < globalVersion.get()) {
- if (settings.isEnableAutoUpdateChat() || settings.getIrisChatSettings() == null) {
- initializeIrisChatSettings(settings);
- }
- if (settings.isEnableAutoUpdateLectureIngestion() || settings.getIrisLectureIngestionSettings() == null) {
- initializeIrisLectureIngestionSettings(settings);
- }
- if (settings.isEnableAutoUpdateHestia() || settings.getIrisHestiaSettings() == null) {
- initializeIrisHestiaSettings(settings);
- }
- if (settings.isEnableAutoUpdateCompetencyGeneration() || settings.getIrisCompetencyGenerationSettings() == null) {
- initializeIrisCompetencyGenerationSettings(settings);
- }
-
- globalVersion.ifPresent(settings::setCurrentVersion);
- saveIrisSettings(settings);
- }
- }
-
private static T initializeSettings(T settings, Supplier constructor) {
if (settings == null) {
settings = constructor.get();
settings.setEnabled(false);
+ settings.setAllowedVariants(new TreeSet<>(Set.of("default")));
+ settings.setSelectedVariant("default");
}
return settings;
}
@@ -157,7 +105,6 @@ private static T initializeSettings(T settings, Supp
private void initializeIrisChatSettings(IrisGlobalSettings settings) {
var irisChatSettings = settings.getIrisChatSettings();
irisChatSettings = initializeSettings(irisChatSettings, IrisChatSubSettings::new);
- irisChatSettings.setTemplate(loadDefaultChatTemplate());
settings.setIrisChatSettings(irisChatSettings);
}
@@ -167,17 +114,9 @@ private void initializeIrisLectureIngestionSettings(IrisGlobalSettings settings)
settings.setIrisLectureIngestionSettings(irisLectureIngestionSettings);
}
- private void initializeIrisHestiaSettings(IrisGlobalSettings settings) {
- var irisHestiaSettings = settings.getIrisHestiaSettings();
- irisHestiaSettings = initializeSettings(irisHestiaSettings, IrisHestiaSubSettings::new);
- irisHestiaSettings.setTemplate(loadDefaultHestiaTemplate());
- settings.setIrisHestiaSettings(irisHestiaSettings);
- }
-
private void initializeIrisCompetencyGenerationSettings(IrisGlobalSettings settings) {
var irisCompetencyGenerationSettings = settings.getIrisCompetencyGenerationSettings();
irisCompetencyGenerationSettings = initializeSettings(irisCompetencyGenerationSettings, IrisCompetencyGenerationSubSettings::new);
- irisCompetencyGenerationSettings.setTemplate(loadDefaultCompetencyGenerationTemplate());
settings.setIrisCompetencyGenerationSettings(irisCompetencyGenerationSettings);
}
@@ -214,9 +153,6 @@ private T saveNewIrisSettings(T settings) {
if (settings instanceof IrisGlobalSettings) {
throw new BadRequestAlertException("You can not create new global settings", "IrisSettings", "notGlobal");
}
- if (!settings.isValid()) {
- throw new BadRequestAlertException("New Iris settings are not valid", "IrisSettings", "notValid");
- }
if (settings instanceof IrisCourseSettings courseSettings && irisSettingsRepository.findCourseSettings(courseSettings.getCourse().getId()).isPresent()) {
throw new ConflictException("Iris settings for this course already exist", "IrisSettings", "alreadyExists");
}
@@ -241,9 +177,6 @@ private T updateIrisSettings(long existingSettingsId, T
if (!Objects.equals(existingSettingsId, settingsUpdate.getId())) {
throw new ConflictException("Existing Iris settings ID does not match update ID", "IrisSettings", "idMismatch");
}
- if (!settingsUpdate.isValid()) {
- throw new BadRequestAlertException("Updated Iris settings are not valid", "IrisSettings", "notValid");
- }
var existingSettings = irisSettingsRepository.findByIdElseThrow(existingSettingsId);
@@ -269,17 +202,9 @@ else if (existingSettings instanceof IrisExerciseSettings exerciseSettings && se
* @return The updated global Iris settings
*/
private IrisGlobalSettings updateGlobalSettings(IrisGlobalSettings existingSettings, IrisGlobalSettings settingsUpdate) {
- existingSettings.setCurrentVersion(settingsUpdate.getCurrentVersion());
-
- existingSettings.setEnableAutoUpdateChat(settingsUpdate.isEnableAutoUpdateChat());
- existingSettings.setEnableAutoUpdateLectureIngestion(settingsUpdate.isEnableAutoUpdateLectureIngestion());
- existingSettings.setEnableAutoUpdateHestia(settingsUpdate.isEnableAutoUpdateHestia());
- existingSettings.setEnableAutoUpdateCompetencyGeneration(settingsUpdate.isEnableAutoUpdateCompetencyGeneration());
-
existingSettings.setIrisLectureIngestionSettings(
irisSubSettingsService.update(existingSettings.getIrisLectureIngestionSettings(), settingsUpdate.getIrisLectureIngestionSettings(), null, GLOBAL));
existingSettings.setIrisChatSettings(irisSubSettingsService.update(existingSettings.getIrisChatSettings(), settingsUpdate.getIrisChatSettings(), null, GLOBAL));
- existingSettings.setIrisHestiaSettings(irisSubSettingsService.update(existingSettings.getIrisHestiaSettings(), settingsUpdate.getIrisHestiaSettings(), null, GLOBAL));
existingSettings.setIrisCompetencyGenerationSettings(
irisSubSettingsService.update(existingSettings.getIrisCompetencyGenerationSettings(), settingsUpdate.getIrisCompetencyGenerationSettings(), null, GLOBAL));
@@ -299,8 +224,6 @@ private IrisCourseSettings updateCourseSettings(IrisCourseSettings existingSetti
irisSubSettingsService.update(existingSettings.getIrisChatSettings(), settingsUpdate.getIrisChatSettings(), parentSettings.irisChatSettings(), COURSE));
existingSettings.setIrisLectureIngestionSettings(irisSubSettingsService.update(existingSettings.getIrisLectureIngestionSettings(),
settingsUpdate.getIrisLectureIngestionSettings(), parentSettings.irisLectureIngestionSettings(), COURSE));
- existingSettings.setIrisHestiaSettings(
- irisSubSettingsService.update(existingSettings.getIrisHestiaSettings(), settingsUpdate.getIrisHestiaSettings(), parentSettings.irisHestiaSettings(), COURSE));
existingSettings.setIrisCompetencyGenerationSettings(irisSubSettingsService.update(existingSettings.getIrisCompetencyGenerationSettings(),
settingsUpdate.getIrisCompetencyGenerationSettings(), parentSettings.irisCompetencyGenerationSettings(), COURSE));
@@ -382,8 +305,7 @@ public IrisCombinedSettingsDTO getCombinedIrisGlobalSettings() {
settingsList.add(getGlobalSettings());
return new IrisCombinedSettingsDTO(irisSubSettingsService.combineChatSettings(settingsList, false),
- irisSubSettingsService.combineLectureIngestionSubSettings(settingsList, false), irisSubSettingsService.combineHestiaSettings(settingsList, false),
- irisSubSettingsService.combineCompetencyGenerationSettings(settingsList, false));
+ irisSubSettingsService.combineLectureIngestionSubSettings(settingsList, false), irisSubSettingsService.combineCompetencyGenerationSettings(settingsList, false));
}
/**
@@ -402,7 +324,7 @@ public IrisCombinedSettingsDTO getCombinedIrisSettingsFor(Course course, boolean
settingsList.add(irisSettingsRepository.findCourseSettings(course.getId()).orElse(null));
return new IrisCombinedSettingsDTO(irisSubSettingsService.combineChatSettings(settingsList, minimal),
- irisSubSettingsService.combineLectureIngestionSubSettings(settingsList, minimal), irisSubSettingsService.combineHestiaSettings(settingsList, minimal),
+ irisSubSettingsService.combineLectureIngestionSubSettings(settingsList, minimal),
irisSubSettingsService.combineCompetencyGenerationSettings(settingsList, minimal));
}
@@ -423,7 +345,7 @@ public IrisCombinedSettingsDTO getCombinedIrisSettingsFor(Exercise exercise, boo
settingsList.add(getRawIrisSettingsFor(exercise));
return new IrisCombinedSettingsDTO(irisSubSettingsService.combineChatSettings(settingsList, minimal),
- irisSubSettingsService.combineLectureIngestionSubSettings(settingsList, minimal), irisSubSettingsService.combineHestiaSettings(settingsList, minimal),
+ irisSubSettingsService.combineLectureIngestionSubSettings(settingsList, minimal),
irisSubSettingsService.combineCompetencyGenerationSettings(settingsList, minimal));
}
@@ -450,7 +372,6 @@ public IrisCourseSettings getDefaultSettingsFor(Course course) {
settings.setCourse(course);
settings.setIrisLectureIngestionSettings(new IrisLectureIngestionSubSettings());
settings.setIrisChatSettings(new IrisChatSubSettings());
- settings.setIrisHestiaSettings(new IrisHestiaSubSettings());
settings.setIrisCompetencyGenerationSettings(new IrisCompetencyGenerationSubSettings());
return settings;
}
@@ -523,7 +444,6 @@ public void deleteSettingsFor(Exercise exercise) {
private boolean isFeatureEnabledInSettings(IrisCombinedSettingsDTO settings, IrisSubSettingsType type) {
return switch (type) {
case CHAT -> settings.irisChatSettings().enabled();
- case HESTIA -> settings.irisHestiaSettings().enabled();
case COMPETENCY_GENERATION -> settings.irisCompetencyGenerationSettings().enabled();
case LECTURE_INGESTION -> settings.irisLectureIngestionSettings().enabled();
};
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/service/settings/IrisSubSettingsService.java b/src/main/java/de/tum/cit/aet/artemis/iris/service/settings/IrisSubSettingsService.java
index dfd555bb59c5..5a3c20b4c810 100644
--- a/src/main/java/de/tum/cit/aet/artemis/iris/service/settings/IrisSubSettingsService.java
+++ b/src/main/java/de/tum/cit/aet/artemis/iris/service/settings/IrisSubSettingsService.java
@@ -15,18 +15,15 @@
import org.springframework.stereotype.Service;
import de.tum.cit.aet.artemis.core.service.AuthorizationCheckService;
-import de.tum.cit.aet.artemis.iris.domain.IrisTemplate;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisChatSubSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisCompetencyGenerationSubSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisExerciseSettings;
-import de.tum.cit.aet.artemis.iris.domain.settings.IrisHestiaSubSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisLectureIngestionSubSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisSettingsType;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisSubSettings;
import de.tum.cit.aet.artemis.iris.dto.IrisCombinedChatSubSettingsDTO;
import de.tum.cit.aet.artemis.iris.dto.IrisCombinedCompetencyGenerationSubSettingsDTO;
-import de.tum.cit.aet.artemis.iris.dto.IrisCombinedHestiaSubSettingsDTO;
import de.tum.cit.aet.artemis.iris.dto.IrisCombinedLectureIngestionSubSettingsDTO;
/**
@@ -76,10 +73,9 @@ public IrisChatSubSettings update(IrisChatSubSettings currentSettings, IrisChatS
currentSettings.setRateLimit(newSettings.getRateLimit());
currentSettings.setRateLimitTimeframeHours(newSettings.getRateLimitTimeframeHours());
}
- currentSettings.setAllowedModels(selectAllowedModels(currentSettings.getAllowedModels(), newSettings.getAllowedModels()));
- currentSettings.setPreferredModel(validatePreferredModel(currentSettings.getPreferredModel(), newSettings.getPreferredModel(), currentSettings.getAllowedModels(),
- parentSettings != null ? parentSettings.allowedModels() : null));
- currentSettings.setTemplate(newSettings.getTemplate());
+ currentSettings.setAllowedVariants(selectAllowedVariants(currentSettings.getAllowedVariants(), newSettings.getAllowedVariants()));
+ currentSettings.setSelectedVariant(validateSelectedVariant(currentSettings.getSelectedVariant(), newSettings.getSelectedVariant(), currentSettings.getAllowedVariants(),
+ parentSettings != null ? parentSettings.allowedVariants() : null));
return currentSettings;
}
@@ -114,40 +110,6 @@ public IrisLectureIngestionSubSettings update(IrisLectureIngestionSubSettings cu
return currentSettings;
}
- /**
- * Updates a Hestia sub settings object.
- * If the new settings are null, the current settings will be deleted (except if the parent settings are null == if the settings are global).
- * Special notes:
- * - If the user is not an admin the allowed models will not be updated.
- * - If the user is not an admin the preferred model will only be updated if it is included in the allowed models.
- *
- * @param currentSettings Current Hestia sub settings.
- * @param newSettings Updated Hestia sub settings.
- * @param parentSettings Parent Hestia sub settings.
- * @param settingsType Type of the settings the sub settings belong to.
- * @return Updated Hestia sub settings.
- */
- public IrisHestiaSubSettings update(IrisHestiaSubSettings currentSettings, IrisHestiaSubSettings newSettings, IrisCombinedHestiaSubSettingsDTO parentSettings,
- IrisSettingsType settingsType) {
- if (newSettings == null) {
- if (parentSettings == null) {
- throw new IllegalArgumentException("Cannot delete the Hestia settings");
- }
- return null;
- }
- if (currentSettings == null) {
- currentSettings = new IrisHestiaSubSettings();
- }
- if (settingsType == IrisSettingsType.EXERCISE || authCheckService.isAdmin()) {
- currentSettings.setEnabled(newSettings.isEnabled());
- }
- currentSettings.setAllowedModels(selectAllowedModels(currentSettings.getAllowedModels(), newSettings.getAllowedModels()));
- currentSettings.setPreferredModel(validatePreferredModel(currentSettings.getPreferredModel(), newSettings.getPreferredModel(), currentSettings.getAllowedModels(),
- parentSettings != null ? parentSettings.allowedModels() : null));
- currentSettings.setTemplate(newSettings.getTemplate());
- return currentSettings;
- }
-
/**
* Updates a Competency Generation sub settings object.
* If the new settings are null, the current settings will be deleted (except if the parent settings are null == if the settings are global).
@@ -174,11 +136,10 @@ public IrisCompetencyGenerationSubSettings update(IrisCompetencyGenerationSubSet
}
if (authCheckService.isAdmin()) {
currentSettings.setEnabled(newSettings.isEnabled());
- currentSettings.setAllowedModels(selectAllowedModels(currentSettings.getAllowedModels(), newSettings.getAllowedModels()));
+ currentSettings.setAllowedVariants(selectAllowedVariants(currentSettings.getAllowedVariants(), newSettings.getAllowedVariants()));
}
- currentSettings.setPreferredModel(validatePreferredModel(currentSettings.getPreferredModel(), newSettings.getPreferredModel(), currentSettings.getAllowedModels(),
- parentSettings != null ? parentSettings.allowedModels() : null));
- currentSettings.setTemplate(newSettings.getTemplate());
+ currentSettings.setSelectedVariant(validateSelectedVariant(currentSettings.getSelectedVariant(), newSettings.getSelectedVariant(), currentSettings.getAllowedVariants(),
+ parentSettings != null ? parentSettings.allowedVariants() : null));
return currentSettings;
}
@@ -187,12 +148,12 @@ public IrisCompetencyGenerationSubSettings update(IrisCompetencyGenerationSubSet
* If the user is an admin, all models are allowed.
* Otherwise, only models that are allowed by the parent settings or the current settings are allowed.
*
- * @param allowedModels The allowed models of the current settings.
- * @param updatedAllowedModels The allowed models of the updated settings.
+ * @param allowedVariants The allowed models of the current settings.
+ * @param updatedAllowedVariants The allowed models of the updated settings.
* @return The filtered allowed models.
*/
- private SortedSet selectAllowedModels(SortedSet allowedModels, SortedSet updatedAllowedModels) {
- return authCheckService.isAdmin() ? updatedAllowedModels : allowedModels;
+ private SortedSet selectAllowedVariants(SortedSet allowedVariants, SortedSet updatedAllowedVariants) {
+ return authCheckService.isAdmin() ? updatedAllowedVariants : allowedVariants;
}
/**
@@ -200,23 +161,23 @@ private SortedSet selectAllowedModels(SortedSet allowedModels, S
* If the user is an admin, all models are allowed.
* Otherwise, only models that are allowed by the current settings are allowed.
*
- * @param preferredModel The preferred model of the current settings.
- * @param newPreferredModel The preferred model of the updated settings.
- * @param allowedModels The allowed models of the current settings.
- * @param parentAllowedModels The allowed models of the parent settings.
+ * @param selectedVariant The preferred model of the current settings.
+ * @param newSelectedVariant The preferred model of the updated settings.
+ * @param allowedVariants The allowed models of the current settings.
+ * @param parentAllowedVariants The allowed models of the parent settings.
* @return The validated preferred model.
*/
- private String validatePreferredModel(String preferredModel, String newPreferredModel, Set allowedModels, Set parentAllowedModels) {
- if (newPreferredModel == null || newPreferredModel.isBlank()) {
+ private String validateSelectedVariant(String selectedVariant, String newSelectedVariant, Set allowedVariants, Set parentAllowedVariants) {
+ if (newSelectedVariant == null || newSelectedVariant.isBlank()) {
return null;
}
- var canChangePreferredModel = authCheckService.isAdmin() || (allowedModels != null && !allowedModels.isEmpty() && allowedModels.contains(newPreferredModel))
- || ((allowedModels == null || allowedModels.isEmpty()) && parentAllowedModels != null && parentAllowedModels.contains(newPreferredModel));
- if (canChangePreferredModel) {
- return newPreferredModel;
+ var canChangeSelectedVariant = authCheckService.isAdmin() || (allowedVariants != null && !allowedVariants.isEmpty() && allowedVariants.contains(newSelectedVariant))
+ || ((allowedVariants == null || allowedVariants.isEmpty()) && parentAllowedVariants != null && parentAllowedVariants.contains(newSelectedVariant));
+ if (canChangeSelectedVariant) {
+ return newSelectedVariant;
}
- return preferredModel;
+ return selectedVariant;
}
/**
@@ -231,10 +192,9 @@ private String validatePreferredModel(String preferredModel, String newPreferred
public IrisCombinedChatSubSettingsDTO combineChatSettings(ArrayList settingsList, boolean minimal) {
var enabled = getCombinedEnabled(settingsList, IrisSettings::getIrisChatSettings);
var rateLimit = getCombinedRateLimit(settingsList);
- var allowedModels = minimal ? getCombinedAllowedModels(settingsList, IrisSettings::getIrisChatSettings) : null;
- var preferredModel = minimal ? getCombinedPreferredModel(settingsList, IrisSettings::getIrisChatSettings) : null;
- var template = minimal ? getCombinedTemplate(settingsList, IrisSettings::getIrisChatSettings, IrisChatSubSettings::getTemplate) : null;
- return new IrisCombinedChatSubSettingsDTO(enabled, rateLimit, null, allowedModels, preferredModel, template);
+ var allowedVariants = !minimal ? getCombinedAllowedVariants(settingsList, IrisSettings::getIrisChatSettings) : null;
+ var selectedVariant = !minimal ? getCombinedSelectedVariant(settingsList, IrisSettings::getIrisChatSettings) : null;
+ return new IrisCombinedChatSubSettingsDTO(enabled, rateLimit, null, allowedVariants, selectedVariant);
}
/**
@@ -251,24 +211,6 @@ public IrisCombinedLectureIngestionSubSettingsDTO combineLectureIngestionSubSett
return new IrisCombinedLectureIngestionSubSettingsDTO(enabled);
}
- /**
- * Combines the Hestia settings of multiple {@link IrisSettings} objects.
- * If minimal is true, the returned object will only contain the enabled field.
- * The minimal version can safely be sent to students.
- *
- * @param settingsList List of {@link IrisSettings} objects to combine.
- * @param minimal Whether to return a minimal version of the combined settings.
- * @return Combined Hestia settings.
- */
- public IrisCombinedHestiaSubSettingsDTO combineHestiaSettings(ArrayList settingsList, boolean minimal) {
- var actualSettingsList = settingsList.stream().filter(settings -> !(settings instanceof IrisExerciseSettings)).toList();
- var enabled = getCombinedEnabled(actualSettingsList, IrisSettings::getIrisHestiaSettings);
- var allowedModels = minimal ? getCombinedAllowedModels(actualSettingsList, IrisSettings::getIrisHestiaSettings) : null;
- var preferredModel = minimal ? getCombinedPreferredModel(actualSettingsList, IrisSettings::getIrisHestiaSettings) : null;
- var template = minimal ? getCombinedTemplate(actualSettingsList, IrisSettings::getIrisHestiaSettings, IrisHestiaSubSettings::getTemplate) : null;
- return new IrisCombinedHestiaSubSettingsDTO(enabled, allowedModels, preferredModel, template);
- }
-
/**
* Combines the Competency Generation settings of multiple {@link IrisSettings} objects.
* If minimal is true, the returned object will only contain the enabled field.
@@ -281,11 +223,9 @@ public IrisCombinedHestiaSubSettingsDTO combineHestiaSettings(ArrayList settingsList, boolean minimal) {
var actualSettingsList = settingsList.stream().filter(settings -> !(settings instanceof IrisExerciseSettings)).toList();
var enabled = getCombinedEnabled(actualSettingsList, IrisSettings::getIrisCompetencyGenerationSettings);
- var allowedModels = minimal ? getCombinedAllowedModels(actualSettingsList, IrisSettings::getIrisCompetencyGenerationSettings) : null;
- var preferredModel = minimal ? getCombinedPreferredModel(actualSettingsList, IrisSettings::getIrisCompetencyGenerationSettings) : null;
- var template = minimal ? getCombinedTemplate(actualSettingsList, IrisSettings::getIrisCompetencyGenerationSettings, IrisCompetencyGenerationSubSettings::getTemplate)
- : null;
- return new IrisCombinedCompetencyGenerationSubSettingsDTO(enabled, allowedModels, preferredModel, template);
+ var allowedVariants = !minimal ? getCombinedAllowedVariants(actualSettingsList, IrisSettings::getIrisCompetencyGenerationSettings) : null;
+ var selectedVariant = !minimal ? getCombinedSelectedVariant(actualSettingsList, IrisSettings::getIrisCompetencyGenerationSettings) : null;
+ return new IrisCombinedCompetencyGenerationSubSettingsDTO(enabled, allowedVariants, selectedVariant);
}
/**
@@ -322,43 +262,28 @@ private Integer getCombinedRateLimit(List settingsList) {
}
/**
- * Combines the allowedModels field of multiple {@link IrisSettings} objects.
- * Simply takes the last allowedModels.
+ * Combines the allowedVariants field of multiple {@link IrisSettings} objects.
+ * Simply takes the last allowedVariants.
*
* @param settingsList List of {@link IrisSettings} objects to combine.
* @param subSettingsFunction Function to get the sub settings from an IrisSettings object.
- * @return Combined allowedModels field.
+ * @return Combined allowedVariants field.
*/
- private Set getCombinedAllowedModels(List settingsList, Function subSettingsFunction) {
- return settingsList.stream().filter(Objects::nonNull).map(subSettingsFunction).filter(Objects::nonNull).map(IrisSubSettings::getAllowedModels).filter(Objects::nonNull)
+ private Set getCombinedAllowedVariants(List settingsList, Function subSettingsFunction) {
+ return settingsList.stream().filter(Objects::nonNull).map(subSettingsFunction).filter(Objects::nonNull).map(IrisSubSettings::getAllowedVariants).filter(Objects::nonNull)
.filter(models -> !models.isEmpty()).reduce((first, second) -> second).orElse(new TreeSet<>());
}
/**
- * Combines the preferredModel field of multiple {@link IrisSettings} objects.
- * Simply takes the last preferredModel.
- * TODO
+ * Combines the selectedVariant field of multiple {@link IrisSettings} objects.
+ * Simply takes the last selectedVariant.
*
* @param settingsList List of {@link IrisSettings} objects to combine.
* @param subSettingsFunction Function to get the sub settings from an IrisSettings object.
- * @return Combined preferredModel field.
+ * @return Combined selectedVariant field.
*/
- private String getCombinedPreferredModel(List settingsList, Function subSettingsFunction) {
- return settingsList.stream().filter(Objects::nonNull).map(subSettingsFunction).filter(Objects::nonNull).map(IrisSubSettings::getPreferredModel)
+ private String getCombinedSelectedVariant(List settingsList, Function subSettingsFunction) {
+ return settingsList.stream().filter(Objects::nonNull).map(subSettingsFunction).filter(Objects::nonNull).map(IrisSubSettings::getSelectedVariant)
.filter(model -> model != null && !model.isBlank()).reduce((first, second) -> second).orElse(null);
}
-
- /**
- * Combines the template field of multiple {@link IrisSettings} objects.
- * Simply takes the last template.
- *
- * @param settingsList List of {@link IrisSettings} objects to combine.
- * @param templateFunction Function to get the template from the sub settings from an IrisSettings object.
- * @return Combined template field.
- */
- private IrisTemplate getCombinedTemplate(List settingsList, Function subSettingsFunction,
- Function templateFunction) {
- return settingsList.stream().filter(Objects::nonNull).map(subSettingsFunction).filter(Objects::nonNull).map(templateFunction)
- .filter(template -> template != null && template.getContent() != null && !template.getContent().isBlank()).reduce((first, second) -> second).orElse(null);
- }
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/web/IrisModelsResource.java b/src/main/java/de/tum/cit/aet/artemis/iris/web/IrisModelsResource.java
deleted file mode 100644
index ae4bedb82493..000000000000
--- a/src/main/java/de/tum/cit/aet/artemis/iris/web/IrisModelsResource.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package de.tum.cit.aet.artemis.iris.web;
-
-import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_IRIS;
-
-import java.util.List;
-
-import org.springframework.context.annotation.Profile;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import de.tum.cit.aet.artemis.core.exception.InternalServerErrorException;
-import de.tum.cit.aet.artemis.core.security.annotations.EnforceAtLeastEditor;
-import de.tum.cit.aet.artemis.iris.service.pyris.PyrisConnectorException;
-import de.tum.cit.aet.artemis.iris.service.pyris.PyrisConnectorService;
-import de.tum.cit.aet.artemis.iris.service.pyris.dto.PyrisModelDTO;
-
-/**
- * REST controller for managing the models Pyris provides.
- */
-@Profile(PROFILE_IRIS)
-@RestController
-@RequestMapping("api/")
-public class IrisModelsResource {
-
- private final PyrisConnectorService pyrisConnectorService;
-
- public IrisModelsResource(PyrisConnectorService pyrisConnectorService) {
- this.pyrisConnectorService = pyrisConnectorService;
- }
-
- /**
- * GET iris/models: Retrieve all available models offered by Pyris
- *
- * @return the {@link ResponseEntity} with status {@code 200 (Ok)} and with body a List of the models
- */
- @GetMapping("iris/models")
- @EnforceAtLeastEditor
- public ResponseEntity> getAllModels() {
- try {
- var models = pyrisConnectorService.getOfferedModels();
- return ResponseEntity.ok(models);
- }
- catch (PyrisConnectorException e) {
- throw new InternalServerErrorException("Could not fetch available Iris models");
- }
- }
-}
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/web/IrisSettingsResource.java b/src/main/java/de/tum/cit/aet/artemis/iris/web/IrisSettingsResource.java
index 32676da073bb..a4f51180b159 100644
--- a/src/main/java/de/tum/cit/aet/artemis/iris/web/IrisSettingsResource.java
+++ b/src/main/java/de/tum/cit/aet/artemis/iris/web/IrisSettingsResource.java
@@ -14,9 +14,13 @@
import de.tum.cit.aet.artemis.core.repository.CourseRepository;
import de.tum.cit.aet.artemis.core.repository.UserRepository;
import de.tum.cit.aet.artemis.core.security.Role;
-import de.tum.cit.aet.artemis.core.security.annotations.EnforceAtLeastEditor;
import de.tum.cit.aet.artemis.core.security.annotations.EnforceAtLeastInstructor;
-import de.tum.cit.aet.artemis.core.security.annotations.EnforceAtLeastStudent;
+import de.tum.cit.aet.artemis.core.security.annotations.enforceRoleInCourse.EnforceAtLeastEditorInCourse;
+import de.tum.cit.aet.artemis.core.security.annotations.enforceRoleInCourse.EnforceAtLeastInstructorInCourse;
+import de.tum.cit.aet.artemis.core.security.annotations.enforceRoleInCourse.EnforceAtLeastStudentInCourse;
+import de.tum.cit.aet.artemis.core.security.annotations.enforceRoleInExercise.EnforceAtLeastEditorInExercise;
+import de.tum.cit.aet.artemis.core.security.annotations.enforceRoleInExercise.EnforceAtLeastInstructorInExercise;
+import de.tum.cit.aet.artemis.core.security.annotations.enforceRoleInExercise.EnforceAtLeastStudentInExercise;
import de.tum.cit.aet.artemis.core.service.AuthorizationCheckService;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisCourseSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisExerciseSettings;
@@ -71,10 +75,9 @@ public ResponseEntity getGlobalSettings() {
* @return the {@link ResponseEntity} with status {@code 200 (Ok)} and with body the settings, or with status {@code 404 (Not Found)} if the course could not be found.
*/
@GetMapping("courses/{courseId}/raw-iris-settings")
- @EnforceAtLeastEditor
+ @EnforceAtLeastEditorInCourse
public ResponseEntity getRawCourseSettings(@PathVariable Long courseId) {
var course = courseRepository.findByIdElseThrow(courseId);
- authCheckService.checkHasAtLeastRoleInCourseElseThrow(Role.EDITOR, course, null);
var irisSettings = irisSettingsService.getRawIrisSettingsFor(course);
return ResponseEntity.ok(irisSettings);
}
@@ -86,7 +89,7 @@ public ResponseEntity getRawCourseSettings(@PathVariable Long cour
* @return the {@link ResponseEntity} with status {@code 200 (Ok)} and with body the settings, or with status {@code 404 (Not Found)} if the exercise could not be found.
*/
@GetMapping("programming-exercises/{exerciseId}/raw-iris-settings")
- @EnforceAtLeastEditor
+ @EnforceAtLeastEditorInExercise
public ResponseEntity getRawProgrammingExerciseSettings(@PathVariable Long exerciseId) {
var exercise = programmingExerciseRepository.findByIdElseThrow(exerciseId);
var user = userRepository.getUserWithGroupsAndAuthorities();
@@ -103,11 +106,10 @@ public ResponseEntity getRawProgrammingExerciseSettings(@PathVaria
* @return the {@link ResponseEntity} with status {@code 200 (Ok)} and with body the settings, or with status {@code 404 (Not Found)} if the course could not be found.
*/
@GetMapping("courses/{courseId}/iris-settings")
- @EnforceAtLeastStudent
+ @EnforceAtLeastStudentInCourse
public ResponseEntity getCourseSettings(@PathVariable Long courseId) {
var course = courseRepository.findByIdElseThrow(courseId);
var user = userRepository.getUserWithGroupsAndAuthorities();
- authCheckService.checkHasAtLeastRoleInCourseElseThrow(Role.STUDENT, course, user);
// Editors can see the full settings, students only the reduced settings
var getReduced = !authCheckService.isAtLeastEditorInCourse(course, user);
@@ -122,11 +124,10 @@ public ResponseEntity getCourseSettings(@PathVariable L
* @return the {@link ResponseEntity} with status {@code 200 (Ok)} and with body the settings, or with status {@code 404 (Not Found)} if the exercise could not be found.
*/
@GetMapping("programming-exercises/{exerciseId}/iris-settings")
- @EnforceAtLeastStudent
+ @EnforceAtLeastStudentInExercise
public ResponseEntity getProgrammingExerciseSettings(@PathVariable Long exerciseId) {
var exercise = programmingExerciseRepository.findByIdElseThrow(exerciseId);
var user = userRepository.getUserWithGroupsAndAuthorities();
- authCheckService.checkHasAtLeastRoleForExerciseElseThrow(Role.STUDENT, exercise, user);
var combinedIrisSettings = irisSettingsService.getCombinedIrisSettingsFor(exercise, irisSettingsService.shouldShowMinimalSettings(exercise, user));
return ResponseEntity.ok(combinedIrisSettings);
@@ -140,10 +141,9 @@ public ResponseEntity getProgrammingExerciseSettings(@P
* @return the {@link ResponseEntity} with status {@code 200 (Ok)} and with body the updated settings, or with status {@code 404 (Not Found)} if the course could not be found.
*/
@PutMapping("courses/{courseId}/raw-iris-settings")
- @EnforceAtLeastEditor
+ @EnforceAtLeastInstructorInCourse
public ResponseEntity updateCourseSettings(@PathVariable Long courseId, @RequestBody IrisCourseSettings settings) {
var course = courseRepository.findByIdElseThrow(courseId);
- authCheckService.checkHasAtLeastRoleInCourseElseThrow(Role.EDITOR, course, null);
settings.setCourse(course);
var updatedSettings = irisSettingsService.saveIrisSettings(settings);
return ResponseEntity.ok(updatedSettings);
@@ -158,11 +158,9 @@ public ResponseEntity updateCourseSettings(@PathVariable Lon
* found.
*/
@PutMapping("programming-exercises/{exerciseId}/raw-iris-settings")
- @EnforceAtLeastInstructor
+ @EnforceAtLeastInstructorInExercise
public ResponseEntity updateProgrammingExerciseSettings(@PathVariable Long exerciseId, @RequestBody IrisExerciseSettings settings) {
var exercise = programmingExerciseRepository.findByIdElseThrow(exerciseId);
- var user = userRepository.getUserWithGroupsAndAuthorities();
- authCheckService.checkHasAtLeastRoleForExerciseElseThrow(Role.INSTRUCTOR, exercise, user);
settings.setExercise(exercise);
var updatedSettings = irisSettingsService.saveIrisSettings(settings);
return ResponseEntity.ok(updatedSettings);
diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/web/IrisVariantsResource.java b/src/main/java/de/tum/cit/aet/artemis/iris/web/IrisVariantsResource.java
new file mode 100644
index 000000000000..9342d1522023
--- /dev/null
+++ b/src/main/java/de/tum/cit/aet/artemis/iris/web/IrisVariantsResource.java
@@ -0,0 +1,56 @@
+package de.tum.cit.aet.artemis.iris.web;
+
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.annotation.Profile;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import de.tum.cit.aet.artemis.core.exception.InternalServerErrorException;
+import de.tum.cit.aet.artemis.core.security.annotations.EnforceAtLeastEditor;
+import de.tum.cit.aet.artemis.iris.domain.settings.IrisSubSettingsType;
+import de.tum.cit.aet.artemis.iris.service.pyris.PyrisConnectorException;
+import de.tum.cit.aet.artemis.iris.service.pyris.PyrisConnectorService;
+import de.tum.cit.aet.artemis.iris.service.pyris.dto.PyrisVariantDTO;
+
+/**
+ * REST controller for managing the variants Pyris provides.
+ */
+@Profile("iris")
+@RestController
+@RequestMapping("api/")
+public class IrisVariantsResource {
+
+ private static final Logger log = LoggerFactory.getLogger(IrisVariantsResource.class);
+
+ private final PyrisConnectorService pyrisConnectorService;
+
+ public IrisVariantsResource(PyrisConnectorService pyrisConnectorService) {
+ this.pyrisConnectorService = pyrisConnectorService;
+ }
+
+ /**
+ * GET iris/variants/{feature}: Retrieve all available variants offered by Pyris for a certain feature
+ *
+ * @param featureRaw the feature for which to retrieve the variants
+ * @return the {@link ResponseEntity} with status {@code 200 (Ok)} and with body a List of the variants
+ */
+ @GetMapping("iris/variants/{feature}")
+ @EnforceAtLeastEditor
+ public ResponseEntity> getAllVariants(@PathVariable("feature") String featureRaw) {
+ var feature = IrisSubSettingsType.valueOf(featureRaw.toUpperCase().replace("-", "_"));
+ try {
+ var variants = pyrisConnectorService.getOfferedVariants(feature);
+ return ResponseEntity.ok(variants);
+ }
+ catch (PyrisConnectorException e) {
+ log.error("Could not fetch available variants for feature {}", feature, e);
+ throw new InternalServerErrorException("Could not fetch available variants for feature " + feature);
+ }
+ }
+}
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/hestia/CodeHintService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/hestia/CodeHintService.java
index ac73fae28454..f04de8a56db9 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/service/hestia/CodeHintService.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/hestia/CodeHintService.java
@@ -13,8 +13,6 @@
import org.springframework.stereotype.Service;
import de.tum.cit.aet.artemis.core.exception.BadRequestAlertException;
-import de.tum.cit.aet.artemis.iris.domain.session.IrisHestiaSession;
-import de.tum.cit.aet.artemis.iris.service.session.IrisHestiaSessionService;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingExercise;
import de.tum.cit.aet.artemis.programming.domain.hestia.CodeHint;
import de.tum.cit.aet.artemis.programming.domain.hestia.ProgrammingExerciseSolutionEntry;
@@ -29,17 +27,14 @@ public class CodeHintService {
private static final Logger log = LoggerFactory.getLogger(CodeHintService.class);
- private final Optional irisHestiaSessionService;
-
private final CodeHintRepository codeHintRepository;
private final ProgrammingExerciseTaskRepository taskRepository;
private final ProgrammingExerciseSolutionEntryRepository solutionEntryRepository;
- public CodeHintService(Optional irisHestiaSessionService, CodeHintRepository codeHintRepository, ProgrammingExerciseTaskRepository taskRepository,
+ public CodeHintService(CodeHintRepository codeHintRepository, ProgrammingExerciseTaskRepository taskRepository,
ProgrammingExerciseSolutionEntryRepository solutionEntryRepository) {
- this.irisHestiaSessionService = irisHestiaSessionService;
this.codeHintRepository = codeHintRepository;
this.taskRepository = taskRepository;
this.solutionEntryRepository = solutionEntryRepository;
@@ -189,17 +184,4 @@ public void updateSolutionEntriesForCodeHint(CodeHint hint) {
codeHintRepository.save(hint);
}
-
- /**
- * Generates a description and content for a code hint using the Iris subsystem.
- * See {@link IrisHestiaSessionService#executeRequest(IrisHestiaSession)} for more information.
- *
- * @param codeHint The code hint to be generated
- * @return The code hint with description and content
- */
- public CodeHint generateDescriptionWithIris(CodeHint codeHint) {
- var irisService = irisHestiaSessionService.orElseThrow();
- var session = irisService.getOrCreateSession(codeHint);
- return irisService.executeRequest(session);
- }
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/web/hestia/CodeHintResource.java b/src/main/java/de/tum/cit/aet/artemis/programming/web/hestia/CodeHintResource.java
index 297e784f1e2b..122aa11b7a17 100644
--- a/src/main/java/de/tum/cit/aet/artemis/programming/web/hestia/CodeHintResource.java
+++ b/src/main/java/de/tum/cit/aet/artemis/programming/web/hestia/CodeHintResource.java
@@ -1,11 +1,9 @@
package de.tum.cit.aet.artemis.programming.web.hestia;
import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_CORE;
-import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_IRIS;
import java.util.List;
import java.util.Objects;
-import java.util.Optional;
import java.util.Set;
import org.slf4j.Logger;
@@ -23,8 +21,6 @@
import de.tum.cit.aet.artemis.core.exception.AccessForbiddenException;
import de.tum.cit.aet.artemis.core.exception.ConflictException;
import de.tum.cit.aet.artemis.core.security.annotations.enforceRoleInExercise.EnforceAtLeastEditorInExercise;
-import de.tum.cit.aet.artemis.iris.domain.settings.IrisSubSettingsType;
-import de.tum.cit.aet.artemis.iris.service.settings.IrisSettingsService;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingExercise;
import de.tum.cit.aet.artemis.programming.domain.hestia.CodeHint;
import de.tum.cit.aet.artemis.programming.repository.ProgrammingExerciseRepository;
@@ -50,15 +46,12 @@ public class CodeHintResource {
private final CodeHintService codeHintService;
- private final Optional irisSettingsService;
-
public CodeHintResource(ProgrammingExerciseRepository programmingExerciseRepository, ProgrammingExerciseSolutionEntryRepository solutionEntryRepository,
- CodeHintRepository codeHintRepository, CodeHintService codeHintService, Optional irisSettingsService) {
+ CodeHintRepository codeHintRepository, CodeHintService codeHintService) {
this.programmingExerciseRepository = programmingExerciseRepository;
this.solutionEntryRepository = solutionEntryRepository;
this.codeHintRepository = codeHintRepository;
this.codeHintService = codeHintService;
- this.irisSettingsService = irisSettingsService;
}
/**
@@ -98,41 +91,6 @@ public ResponseEntity> generateCodeHintsForExercise(@PathVariable
return ResponseEntity.ok(codeHints);
}
- /**
- * {@code POST programming-exercises/:exerciseId/code-hints/:codeHintId/generate-description} : Generate a description for a code hint using Iris.
- *
- * @param exerciseId The id of the exercise of the code hint
- * @param codeHintId The id of the code hint
- * @return the {@link ResponseEntity} with status {@code 200 (Ok)} and with body the updated code hint
- */
- // TODO: move into some IrisResource
- @Profile(PROFILE_IRIS)
- @PostMapping("programming-exercises/{exerciseId}/code-hints/{codeHintId}/generate-description")
- @EnforceAtLeastEditorInExercise
- public ResponseEntity generateDescriptionForCodeHint(@PathVariable Long exerciseId, @PathVariable Long codeHintId) {
- log.debug("REST request to generate description with Iris for CodeHint: {}", codeHintId);
-
- ProgrammingExercise exercise = programmingExerciseRepository.findByIdElseThrow(exerciseId);
- irisSettingsService.orElseThrow().isEnabledForElseThrow(IrisSubSettingsType.HESTIA, exercise);
-
- // Hints for exam exercises are not supported at the moment
- if (exercise.isExamExercise()) {
- throw new AccessForbiddenException("Code hints for exams are currently not supported");
- }
-
- var codeHint = codeHintRepository.findByIdWithSolutionEntriesElseThrow(codeHintId);
- if (!Objects.equals(codeHint.getExercise().getId(), exercise.getId())) {
- throw new ConflictException("The code hint does not belong to the exercise", "CodeHint", "codeHintExerciseConflict");
- }
-
- if (codeHint.getSolutionEntries().isEmpty()) {
- throw new ConflictException("The code hint does not have any solution entries", "CodeHint", "codeHintNoSolutionEntries");
- }
-
- codeHint = codeHintService.generateDescriptionWithIris(codeHint);
- return ResponseEntity.ok(codeHint);
- }
-
/**
* {@code DELETE programming-exercises/:exerciseId/code-hints/:codeHintId/solution-entries/:solutionEntryId} :
* Removes a solution entry from a code hint.
diff --git a/src/main/resources/config/liquibase/changelog/20240825191919_changelog.xml b/src/main/resources/config/liquibase/changelog/20240825191919_changelog.xml
new file mode 100644
index 000000000000..3ae7fd7ea038
--- /dev/null
+++ b/src/main/resources/config/liquibase/changelog/20240825191919_changelog.xml
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ DELETE FROM iris_sub_settings WHERE discriminator = 'HESTIA';
+
+
+
+
+
+
+
+
+
+
+ UPDATE iris_sub_settings
+ SET allowed_variants = 'default', selected_variant = 'default'
+ WHERE id IN (
+ SELECT iris_chat_settings_id FROM iris_settings WHERE discriminator = 'GLOBAL'
+ UNION
+ SELECT iris_competency_generation_settings_id FROM iris_settings WHERE discriminator = 'GLOBAL'
+ UNION
+ SELECT iris_lecture_ingestion_settings_id FROM iris_settings WHERE discriminator = 'GLOBAL'
+ );
+
+
+
+
+
+
+
+
+
+
+
+
+
+ DELETE FROM iris_json_message_content WHERE id IN (
+ SELECT iris_message_content.id FROM iris_message_content
+ JOIN iris_message ON iris_message_content.message_id = iris_message.id
+ JOIN iris_session ON iris_message.session_id = iris_session.id
+ WHERE iris_session.discriminator = 'HESTIA'
+ );
+ DELETE FROM iris_text_message_content WHERE id IN (
+ SELECT iris_message_content.id FROM iris_message_content
+ JOIN iris_message ON iris_message_content.message_id = iris_message.id
+ JOIN iris_session ON iris_message.session_id = iris_session.id
+ WHERE iris_session.discriminator = 'HESTIA'
+ );
+ DELETE FROM iris_message_content WHERE message_id IN (
+ SELECT iris_message.id FROM iris_message
+ JOIN iris_session ON iris_message.session_id = iris_session.id
+ WHERE iris_session.discriminator = 'HESTIA'
+ );
+ DELETE FROM iris_message WHERE session_id IN (
+ SELECT id FROM iris_session WHERE discriminator = 'HESTIA'
+ );
+ DELETE FROM iris_session WHERE discriminator = 'HESTIA';
+
+
+
+
+
+
+
diff --git a/src/main/resources/config/liquibase/master.xml b/src/main/resources/config/liquibase/master.xml
index 49f3eeee4d63..b560fb1047fe 100644
--- a/src/main/resources/config/liquibase/master.xml
+++ b/src/main/resources/config/liquibase/master.xml
@@ -22,6 +22,7 @@
+
diff --git a/src/main/webapp/app/course/manage/detail/course-detail.component.ts b/src/main/webapp/app/course/manage/detail/course-detail.component.ts
index 5954f3c0b7c0..29858e79b334 100644
--- a/src/main/webapp/app/course/manage/detail/course-detail.component.ts
+++ b/src/main/webapp/app/course/manage/detail/course-detail.component.ts
@@ -50,7 +50,6 @@ export class CourseDetailComponent implements OnInit, OnDestroy {
communicationEnabled: boolean;
irisEnabled = false;
irisChatEnabled = false;
- irisHestiaEnabled = false;
ltiEnabled = false;
isAthenaEnabled = false;
tutorialEnabled = false;
@@ -96,7 +95,6 @@ export class CourseDetailComponent implements OnInit, OnDestroy {
if (this.irisEnabled) {
const irisSettings = await firstValueFrom(this.irisSettingsService.getGlobalSettings());
this.irisChatEnabled = irisSettings?.irisChatSettings?.enabled ?? false;
- this.irisHestiaEnabled = irisSettings?.irisHestiaSettings?.enabled ?? false;
}
this.route.data.subscribe(({ course }) => {
if (course) {
diff --git a/src/main/webapp/app/entities/iris/settings/iris-settings.model.ts b/src/main/webapp/app/entities/iris/settings/iris-settings.model.ts
index 017c3ea2cffa..ab7f3b475908 100644
--- a/src/main/webapp/app/entities/iris/settings/iris-settings.model.ts
+++ b/src/main/webapp/app/entities/iris/settings/iris-settings.model.ts
@@ -1,10 +1,5 @@
import { BaseEntity } from 'app/shared/model/base-entity';
-import {
- IrisChatSubSettings,
- IrisCompetencyGenerationSubSettings,
- IrisHestiaSubSettings,
- IrisLectureIngestionSubSettings,
-} from 'app/entities/iris/settings/iris-sub-settings.model';
+import { IrisChatSubSettings, IrisCompetencyGenerationSubSettings, IrisLectureIngestionSubSettings } from 'app/entities/iris/settings/iris-sub-settings.model';
export enum IrisSettingsType {
GLOBAL = 'global',
@@ -17,21 +12,14 @@ export abstract class IrisSettings implements BaseEntity {
type: IrisSettingsType;
irisChatSettings?: IrisChatSubSettings;
irisLectureIngestionSettings?: IrisLectureIngestionSubSettings;
- irisHestiaSettings?: IrisHestiaSubSettings;
irisCompetencyGenerationSettings?: IrisCompetencyGenerationSubSettings;
}
export class IrisGlobalSettings implements IrisSettings {
id?: number;
type = IrisSettingsType.GLOBAL;
- currentVersion?: number;
- enableAutoUpdateChat?: boolean;
- enableAutoUpdateLectureIngestion?: boolean;
- enableAutoUpdateHestia?: boolean;
- enableAutoUpdateCompetencyGeneration?: boolean;
irisChatSettings?: IrisChatSubSettings;
irisLectureIngestionSettings?: IrisLectureIngestionSubSettings;
- irisHestiaSettings?: IrisHestiaSubSettings;
irisCompetencyGenerationSettings?: IrisCompetencyGenerationSubSettings;
}
@@ -41,7 +29,6 @@ export class IrisCourseSettings implements IrisSettings {
courseId?: number;
irisChatSettings?: IrisChatSubSettings;
irisLectureIngestionSettings?: IrisLectureIngestionSubSettings;
- irisHestiaSettings?: IrisHestiaSubSettings;
irisCompetencyGenerationSettings?: IrisCompetencyGenerationSubSettings;
}
diff --git a/src/main/webapp/app/entities/iris/settings/iris-sub-settings.model.ts b/src/main/webapp/app/entities/iris/settings/iris-sub-settings.model.ts
index 8848394f1350..626155a43555 100644
--- a/src/main/webapp/app/entities/iris/settings/iris-sub-settings.model.ts
+++ b/src/main/webapp/app/entities/iris/settings/iris-sub-settings.model.ts
@@ -1,9 +1,7 @@
import { BaseEntity } from 'app/shared/model/base-entity';
-import { IrisTemplate } from 'app/entities/iris/settings/iris-template';
export enum IrisSubSettingsType {
CHAT = 'chat',
- HESTIA = 'hestia',
COMPETENCY_GENERATION = 'competency-generation',
LECTURE_INGESTION = 'lecture-ingestion',
}
@@ -12,13 +10,12 @@ export abstract class IrisSubSettings implements BaseEntity {
id?: number;
type: IrisSubSettingsType;
enabled = false;
- allowedModels?: string[];
- preferredModel?: string;
+ allowedVariants?: string[];
+ selectedVariant?: string;
}
export class IrisChatSubSettings extends IrisSubSettings {
type = IrisSubSettingsType.CHAT;
- template?: IrisTemplate;
rateLimit?: number;
rateLimitTimeframeHours?: number;
}
@@ -28,12 +25,6 @@ export class IrisLectureIngestionSubSettings extends IrisSubSettings {
autoIngestOnLectureAttachmentUpload: boolean;
}
-export class IrisHestiaSubSettings extends IrisSubSettings {
- type = IrisSubSettingsType.HESTIA;
- template?: IrisTemplate;
-}
-
export class IrisCompetencyGenerationSubSettings extends IrisSubSettings {
type = IrisSubSettingsType.COMPETENCY_GENERATION;
- template?: IrisTemplate;
}
diff --git a/src/main/webapp/app/entities/iris/settings/iris-template.ts b/src/main/webapp/app/entities/iris/settings/iris-template.ts
deleted file mode 100644
index eb0c8a90041c..000000000000
--- a/src/main/webapp/app/entities/iris/settings/iris-template.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import { BaseEntity } from 'app/shared/model/base-entity';
-
-export class IrisTemplate implements BaseEntity {
- id?: number;
- content = '';
-}
diff --git a/src/main/webapp/app/entities/iris/settings/iris-model.ts b/src/main/webapp/app/entities/iris/settings/iris-variant.ts
similarity index 69%
rename from src/main/webapp/app/entities/iris/settings/iris-model.ts
rename to src/main/webapp/app/entities/iris/settings/iris-variant.ts
index 94a7f9202d92..3fbecfee8c49 100644
--- a/src/main/webapp/app/entities/iris/settings/iris-model.ts
+++ b/src/main/webapp/app/entities/iris/settings/iris-variant.ts
@@ -1,4 +1,4 @@
-export class IrisModel {
+export class IrisVariant {
id: string;
name: string;
description: string;
diff --git a/src/main/webapp/app/exercises/shared/exercise-hint/manage/exercise-hint-update.component.html b/src/main/webapp/app/exercises/shared/exercise-hint/manage/exercise-hint-update.component.html
index 5c80f6e0c868..6bf170d0bac9 100644
--- a/src/main/webapp/app/exercises/shared/exercise-hint/manage/exercise-hint-update.component.html
+++ b/src/main/webapp/app/exercises/shared/exercise-hint/manage/exercise-hint-update.component.html
@@ -45,21 +45,6 @@
- @if (exerciseHint.type === HintType.CODE && irisSettings?.irisHestiaSettings?.enabled) {
-
- Generate description
-
-
- }
diff --git a/src/main/webapp/app/iris/iris.module.ts b/src/main/webapp/app/iris/iris.module.ts
index 5473966d0275..aacdbd0b64cf 100644
--- a/src/main/webapp/app/iris/iris.module.ts
+++ b/src/main/webapp/app/iris/iris.module.ts
@@ -14,7 +14,6 @@ import { IrisCommonSubSettingsUpdateComponent } from './settings/iris-settings-u
import { IrisCourseSettingsUpdateComponent } from 'app/iris/settings/iris-course-settings-update/iris-course-settings-update.component';
import { IrisExerciseSettingsUpdateComponent } from 'app/iris/settings/iris-exercise-settings-update/iris-exercise-settings-update.component';
import { IrisLogoComponent } from './iris-logo/iris-logo.component';
-import { IrisGlobalAutoupdateSettingsUpdateComponent } from './settings/iris-settings-update/iris-global-autoupdate-settings-update/iris-global-autoupdate-settings-update.component';
import { IrisExerciseChatbotButtonComponent } from 'app/iris/exercise-chatbot/exercise-chatbot-button.component';
import { IrisChatbotWidgetComponent } from 'app/iris/exercise-chatbot/widget/chatbot-widget.component';
import { IrisEnabledComponent } from 'app/iris/settings/shared/iris-enabled.component';
@@ -36,7 +35,6 @@ import { CourseChatbotComponent } from 'app/iris/course-chatbot/course-chatbot.c
IrisExerciseSettingsUpdateComponent,
IrisCommonSubSettingsUpdateComponent,
IrisLogoComponent,
- IrisGlobalAutoupdateSettingsUpdateComponent,
IrisEnabledComponent,
ChatStatusBarComponent,
IrisLogoButtonComponent,
diff --git a/src/main/webapp/app/iris/settings/iris-settings-update/iris-common-sub-settings-update/iris-common-sub-settings-update.component.html b/src/main/webapp/app/iris/settings/iris-settings-update/iris-common-sub-settings-update/iris-common-sub-settings-update.component.html
index 4132e9fab587..95238efecaf9 100644
--- a/src/main/webapp/app/iris/settings/iris-settings-update/iris-common-sub-settings-update/iris-common-sub-settings-update.component.html
+++ b/src/main/webapp/app/iris/settings/iris-settings-update/iris-common-sub-settings-update/iris-common-sub-settings-update.component.html
@@ -24,39 +24,62 @@
jhiTranslate="artemisApp.iris.settings.subSettings.enabled.off"
>
-
- :
+
+ :
@if (parentSubSettings) {
}
+ :
+
+
+
+ {{ getSelectedVariantName() ?? ('artemisApp.iris.settings.subSettings.variants.selectedVariant.inherit' | artemisTranslate) }}
+
+
+ @if (parentSubSettings) {
+
+ {{ 'artemisApp.iris.settings.subSettings.variants.selectedVariant.inherit' | artemisTranslate }}
+
+ }
+ @for (model of allowedVariants; track model) {
+
+ {{ model.name }}
+
+ }
+
+
+ @if (!subSettings?.selectedVariant) {
+
{{ getSelectedVariantNameParent() }}
+ }
+
diff --git a/src/main/webapp/app/iris/settings/iris-settings-update/iris-common-sub-settings-update/iris-common-sub-settings-update.component.ts b/src/main/webapp/app/iris/settings/iris-settings-update/iris-common-sub-settings-update/iris-common-sub-settings-update.component.ts
index 723b8ddb21a9..ba5bd6573691 100644
--- a/src/main/webapp/app/iris/settings/iris-settings-update/iris-common-sub-settings-update/iris-common-sub-settings-update.component.ts
+++ b/src/main/webapp/app/iris/settings/iris-settings-update/iris-common-sub-settings-update/iris-common-sub-settings-update.component.ts
@@ -1,10 +1,11 @@
import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';
import { IrisSubSettings, IrisSubSettingsType } from 'app/entities/iris/settings/iris-sub-settings.model';
-import { IrisModel } from 'app/entities/iris/settings/iris-model';
+import { IrisVariant } from 'app/entities/iris/settings/iris-variant';
import { AccountService } from 'app/core/auth/account.service';
import { ButtonType } from 'app/shared/components/button.component';
import { faTrash } from '@fortawesome/free-solid-svg-icons';
import { IrisSettingsType } from 'app/entities/iris/settings/iris-settings.model';
+import { IrisSettingsService } from 'app/iris/settings/shared/iris-settings.service';
@Component({
selector: 'jhi-iris-common-sub-settings-update',
@@ -17,9 +18,6 @@ export class IrisCommonSubSettingsUpdateComponent implements OnInit, OnChanges {
@Input()
parentSubSettings?: IrisSubSettings;
- @Input()
- allIrisModels: IrisModel[];
-
@Input()
settingsType: IrisSettingsType;
@@ -28,9 +26,11 @@ export class IrisCommonSubSettingsUpdateComponent implements OnInit, OnChanges {
isAdmin: boolean;
- inheritAllowedModels: boolean;
+ inheritAllowedVariants: boolean;
+
+ availableVariants: IrisVariant[] = [];
- allowedIrisModels: IrisModel[];
+ allowedVariants: IrisVariant[] = [];
enabled: boolean;
@@ -42,49 +42,62 @@ export class IrisCommonSubSettingsUpdateComponent implements OnInit, OnChanges {
// Icons
faTrash = faTrash;
- constructor(accountService: AccountService) {
+ constructor(
+ accountService: AccountService,
+ private irisSettingsService: IrisSettingsService,
+ ) {
this.isAdmin = accountService.isAdmin();
}
ngOnInit() {
this.enabled = this.subSettings?.enabled ?? false;
- this.allowedIrisModels = this.getAvailableModels();
- this.inheritAllowedModels = !!(!this.subSettings?.allowedModels && this.parentSubSettings);
+ this.loadVariants();
+ this.inheritAllowedVariants = !!(!this.subSettings?.allowedVariants && this.parentSubSettings);
}
ngOnChanges(changes: SimpleChanges): void {
- if (changes.allIrisModels) {
- this.allowedIrisModels = this.getAvailableModels();
+ if (changes.availableVariants) {
+ this.allowedVariants = this.getAllowedVariants();
}
if (changes.subSettings) {
this.enabled = this.subSettings?.enabled ?? false;
}
}
- getAvailableModels(): IrisModel[] {
- return this.allIrisModels.filter((model) => (this.subSettings?.allowedModels ?? this.parentSubSettings?.allowedModels ?? []).includes(model.id));
+ loadVariants(): void {
+ if (!this.subSettings?.type) {
+ return;
+ }
+ this.irisSettingsService.getVariantsForFeature(this.subSettings?.type).subscribe((variants) => {
+ this.availableVariants = variants ?? this.availableVariants;
+ this.allowedVariants = this.getAllowedVariants();
+ });
+ }
+
+ getAllowedVariants(): IrisVariant[] {
+ return this.availableVariants.filter((variant) => (this.subSettings?.allowedVariants ?? this.parentSubSettings?.allowedVariants ?? []).includes(variant.id));
}
- getPreferredModelName(): string | undefined {
- return this.allIrisModels.find((model) => model.id === this.subSettings?.preferredModel)?.name ?? this.subSettings?.preferredModel;
+ getSelectedVariantName(): string | undefined {
+ return this.availableVariants.find((variant) => variant.id === this.subSettings?.selectedVariant)?.name ?? this.subSettings?.selectedVariant;
}
- getPreferredModelNameParent(): string | undefined {
- return this.allIrisModels.find((model) => model.id === this.parentSubSettings?.preferredModel)?.name ?? this.parentSubSettings?.preferredModel;
+ getSelectedVariantNameParent(): string | undefined {
+ return this.availableVariants.find((variant) => variant.id === this.parentSubSettings?.selectedVariant)?.name ?? this.parentSubSettings?.selectedVariant;
}
- onAllowedIrisModelsSelectionChange(model: IrisModel) {
- this.inheritAllowedModels = false;
- if (this.allowedIrisModels.includes(model)) {
- this.allowedIrisModels = this.allowedIrisModels.filter((m) => m !== model);
+ onAllowedIrisVariantsSelectionChange(variant: IrisVariant) {
+ this.inheritAllowedVariants = false;
+ if (this.allowedVariants.map((variant) => variant.id).includes(variant.id)) {
+ this.allowedVariants = this.allowedVariants.filter((m) => m.id !== variant.id);
} else {
- this.allowedIrisModels.push(model);
+ this.allowedVariants.push(variant);
}
- this.subSettings!.allowedModels = this.allowedIrisModels.map((model) => model.id);
+ this.subSettings!.allowedVariants = this.allowedVariants.map((variant) => variant.id);
}
- setModel(model: IrisModel | undefined) {
- this.subSettings!.preferredModel = model?.id;
+ setVariant(variant: IrisVariant | undefined) {
+ this.subSettings!.selectedVariant = variant?.id;
}
onEnabledChange() {
@@ -101,12 +114,12 @@ export class IrisCommonSubSettingsUpdateComponent implements OnInit, OnChanges {
this.onEnabledChange();
}
- onInheritAllowedModelsChange() {
- if (this.inheritAllowedModels) {
- this.subSettings!.allowedModels = undefined;
- this.allowedIrisModels = this.getAvailableModels();
+ onInheritAllowedVariantsChange() {
+ if (this.inheritAllowedVariants) {
+ this.subSettings!.allowedVariants = undefined;
+ this.allowedVariants = this.getAllowedVariants();
} else {
- this.subSettings!.allowedModels = this.allowedIrisModels.map((model) => model.id);
+ this.subSettings!.allowedVariants = this.allowedVariants.map((variant) => variant.id);
}
}
diff --git a/src/main/webapp/app/iris/settings/iris-settings-update/iris-global-autoupdate-settings-update/iris-global-autoupdate-settings-update.component.html b/src/main/webapp/app/iris/settings/iris-settings-update/iris-global-autoupdate-settings-update/iris-global-autoupdate-settings-update.component.html
deleted file mode 100644
index efb780138e8c..000000000000
--- a/src/main/webapp/app/iris/settings/iris-settings-update/iris-global-autoupdate-settings-update/iris-global-autoupdate-settings-update.component.html
+++ /dev/null
@@ -1,20 +0,0 @@
-@if (irisSettings) {
-
-}
diff --git a/src/main/webapp/app/iris/settings/iris-settings-update/iris-global-autoupdate-settings-update/iris-global-autoupdate-settings-update.component.ts b/src/main/webapp/app/iris/settings/iris-settings-update/iris-global-autoupdate-settings-update/iris-global-autoupdate-settings-update.component.ts
deleted file mode 100644
index 404132633566..000000000000
--- a/src/main/webapp/app/iris/settings/iris-settings-update/iris-global-autoupdate-settings-update/iris-global-autoupdate-settings-update.component.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { Component, EventEmitter, Input, Output } from '@angular/core';
-import { IrisGlobalSettings } from 'app/entities/iris/settings/iris-settings.model';
-import { IrisSubSettings } from 'app/entities/iris/settings/iris-sub-settings.model';
-
-@Component({
- selector: 'jhi-iris-global-autoupdate-settings-update',
- templateUrl: './iris-global-autoupdate-settings-update.component.html',
-})
-export class IrisGlobalAutoupdateSettingsUpdateComponent {
- @Input()
- irisSettings?: IrisGlobalSettings;
-
- @Output()
- onChanges = new EventEmitter();
-}
diff --git a/src/main/webapp/app/iris/settings/iris-settings-update/iris-settings-update.component.html b/src/main/webapp/app/iris/settings/iris-settings-update/iris-settings-update.component.html
index b28a3a4c690c..c1e15d609c1f 100644
--- a/src/main/webapp/app/iris/settings/iris-settings-update/iris-settings-update.component.html
+++ b/src/main/webapp/app/iris/settings/iris-settings-update/iris-settings-update.component.html
@@ -11,18 +11,11 @@
@if (irisSettings) {
- @if (settingsType === GLOBAL) {
-
-
-
-
- }
@@ -34,33 +27,21 @@
-
- }
- @if (settingsType === COURSE) {
-
-
-
-
- }
- @if (settingsType !== EXERCISE) {
-
-
-
-
+
+
+ @if (settingsType === COURSE) {
+
+
+
+
+ }
}
@if (settingsType !== EXERCISE) {
@@ -70,7 +51,6 @@
diff --git a/src/main/webapp/app/iris/settings/iris-settings-update/iris-settings-update.component.ts b/src/main/webapp/app/iris/settings/iris-settings-update/iris-settings-update.component.ts
index 5bde2f10f791..aa9adac6be64 100644
--- a/src/main/webapp/app/iris/settings/iris-settings-update/iris-settings-update.component.ts
+++ b/src/main/webapp/app/iris/settings/iris-settings-update/iris-settings-update.component.ts
@@ -6,15 +6,9 @@ import { Observable } from 'rxjs';
import { AlertService } from 'app/core/util/alert.service';
import { ButtonType } from 'app/shared/components/button.component';
import { faRotate, faSave } from '@fortawesome/free-solid-svg-icons';
-import { IrisModel } from 'app/entities/iris/settings/iris-model';
import { ComponentCanDeactivate } from 'app/shared/guard/can-deactivate.model';
import { cloneDeep, isEqual } from 'lodash-es';
-import {
- IrisChatSubSettings,
- IrisCompetencyGenerationSubSettings,
- IrisHestiaSubSettings,
- IrisLectureIngestionSubSettings,
-} from 'app/entities/iris/settings/iris-sub-settings.model';
+import { IrisChatSubSettings, IrisCompetencyGenerationSubSettings, IrisLectureIngestionSubSettings } from 'app/entities/iris/settings/iris-sub-settings.model';
import { AccountService } from 'app/core/auth/account.service';
@Component({
@@ -30,7 +24,6 @@ export class IrisSettingsUpdateComponent implements OnInit, DoCheck, ComponentCa
public exerciseId?: number;
public irisSettings?: IrisSettings;
public parentIrisSettings?: IrisSettings;
- public allIrisModels?: IrisModel[];
originalIrisSettings?: IrisSettings;
@@ -77,13 +70,6 @@ export class IrisSettingsUpdateComponent implements OnInit, DoCheck, ComponentCa
return !this.isDirty;
}
- loadIrisModels(): void {
- this.irisSettingsService.getIrisModels().subscribe((models) => {
- this.allIrisModels = models;
- this.isLoading = false;
- });
- }
-
loadIrisSettings(): void {
this.isLoading = true;
this.loadIrisSettingsObservable().subscribe((settings) => {
@@ -116,9 +102,6 @@ export class IrisSettingsUpdateComponent implements OnInit, DoCheck, ComponentCa
if (!this.irisSettings.irisLectureIngestionSettings) {
this.irisSettings.irisLectureIngestionSettings = new IrisLectureIngestionSubSettings();
}
- if (!this.irisSettings.irisHestiaSettings) {
- this.irisSettings.irisHestiaSettings = new IrisHestiaSubSettings();
- }
if (!this.irisSettings.irisCompetencyGenerationSettings) {
this.irisSettings.irisCompetencyGenerationSettings = new IrisCompetencyGenerationSubSettings();
}
diff --git a/src/main/webapp/app/iris/settings/shared/iris-enabled.component.ts b/src/main/webapp/app/iris/settings/shared/iris-enabled.component.ts
index ef8d44419841..be64bd5d856b 100644
--- a/src/main/webapp/app/iris/settings/shared/iris-enabled.component.ts
+++ b/src/main/webapp/app/iris/settings/shared/iris-enabled.component.ts
@@ -56,9 +56,6 @@ export class IrisEnabledComponent implements OnInit {
case IrisSubSettingsType.CHAT:
this.irisSubSettings = this.irisSettings?.irisChatSettings;
break;
- case IrisSubSettingsType.HESTIA:
- this.irisSubSettings = this.irisSettings?.irisHestiaSettings;
- break;
case IrisSubSettingsType.COMPETENCY_GENERATION:
this.irisSubSettings = this.irisSettings?.irisCompetencyGenerationSettings;
break;
diff --git a/src/main/webapp/app/iris/settings/shared/iris-settings.service.ts b/src/main/webapp/app/iris/settings/shared/iris-settings.service.ts
index 475540bad156..7273e5958cf6 100644
--- a/src/main/webapp/app/iris/settings/shared/iris-settings.service.ts
+++ b/src/main/webapp/app/iris/settings/shared/iris-settings.service.ts
@@ -3,7 +3,8 @@ import { HttpClient, HttpResponse } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { IrisCourseSettings, IrisExerciseSettings, IrisGlobalSettings } from 'app/entities/iris/settings/iris-settings.model';
-import { IrisModel } from 'app/entities/iris/settings/iris-model';
+import { IrisVariant } from 'app/entities/iris/settings/iris-variant';
+import { IrisSubSettingsType } from 'app/entities/iris/settings/iris-sub-settings.model';
/**
* Service for calling the Iris settings endpoints on the server
@@ -90,9 +91,11 @@ export class IrisSettingsService {
}
/**
- * Get the global Iris settings
+ * Get the available variants for a feature
*/
- getIrisModels(): Observable
{
- return this.http.get(`${this.resourceUrl}/iris/models`, { observe: 'response' }).pipe(map((res: HttpResponse) => res.body ?? []));
+ getVariantsForFeature(feature: IrisSubSettingsType): Observable {
+ return this.http
+ .get(`${this.resourceUrl}/iris/variants/${feature}`, { observe: 'response' })
+ .pipe(map((res: HttpResponse) => res.body ?? []));
}
}
diff --git a/src/main/webapp/i18n/de/iris.json b/src/main/webapp/i18n/de/iris.json
index 34572e7581bd..4044841119d8 100644
--- a/src/main/webapp/i18n/de/iris.json
+++ b/src/main/webapp/i18n/de/iris.json
@@ -28,14 +28,14 @@
"hestiaSettings": "Hestia Einstellungen",
"competencyGenerationSettings": "Kompetenzgenerierung Einstellungen",
"enabled-disabled": "Aktiviert/Deaktiviert",
- "models": {
- "title": "Modelle",
- "allowedModels": {
- "title": "Erlaubte Modelle",
- "inheritSwitch": "Erbe erlaubte Modelle"
+ "variants": {
+ "title": "Varianten",
+ "allowedVariants": {
+ "title": "Erlaubte Varianten",
+ "inheritSwitch": "Erbe erlaubte Varianten"
},
- "preferredModel": {
- "title": "Präferiertes Modell",
+ "selectedVariant": {
+ "title": "Genuzte Variante",
"inherit": "Erben"
}
},
@@ -63,21 +63,13 @@
"global": "Globale Iris Einstellungen",
"course": "Kurs Iris Einstellungen",
"programmingExercise": "Programmieraufgabe Iris Einstellungen"
- },
- "autoUpdate": {
- "title": "Auto Update Einstellungen",
- "tooltip": "Wenn aktiviert, werden die spezifischen globalen Iris Einstellungen automatisch aktualisiert, wenn eine neue Version von Artemis neue Iris Einstellungen bereitstellt.",
- "chatLabel": "Auto Update der Chat Einstellungen",
- "hestiaLabel": "Auto Update der Hestia Einstellungen",
- "lectureIngestionLabel": "Auto Update der Vorlesungen Erfassung Einstellungen",
- "competencyGenerationLabel": "Auto Update der Kompetenzgenerierung Einstellungen"
}
},
"error": {
"forbidden": "Artemis ist nicht konfiguriert, um Iris zu verwenden. (Ungültiges Token)",
"internalPyrisError": "Ein interner Fehler beim Kommunizieren mit dem LLM ist aufgetreten. Die Fehlermeldung lautet: {{ pyrisErrorMessage }}.",
"invalidTemplate": "Die Vorlage ist ungültig. Die Fehlermeldung lautet: {{ pyrisErrorMessage }}.",
- "noModelAvailable": "Das Modell {{ model }} steht nicht zur Verfügung. Bitte kontaktiere einen Administrator, wenn das Problem weiterhin besteht.",
+ "noVariantAvailable": "Die Variante {{ variant }} steht nicht zur Verfügung. Bitte kontaktiere einen Administrator, wenn das Problem weiterhin besteht.",
"noResponse": "Es wurde keine Antwort von Iris empfangen. Bitte kontaktiere einen Administrator, wenn das Problem weiterhin besteht.",
"parseResponse": "Ein Fehler ist beim Parsen der Antwort von Iris aufgetreten. Ursache: {{ cause }}"
},
diff --git a/src/main/webapp/i18n/en/iris.json b/src/main/webapp/i18n/en/iris.json
index 6afbb928d5c9..21aed4b477e7 100644
--- a/src/main/webapp/i18n/en/iris.json
+++ b/src/main/webapp/i18n/en/iris.json
@@ -28,14 +28,14 @@
"hestiaSettings": "Hestia Settings",
"competencyGenerationSettings": "Competency Generation Settings",
"enabled-disabled": "Enabled/Disabled",
- "models": {
- "title": "Models",
- "allowedModels": {
- "title": "Allowed Models",
- "inheritSwitch": "Inherit Allowed Models"
+ "variants": {
+ "title": "Variants",
+ "allowedVariants": {
+ "title": "Allowed Variants",
+ "inheritSwitch": "Inherit Allowed Variants"
},
- "preferredModel": {
- "title": "Preferred Model",
+ "selectedVariant": {
+ "title": "Selected Variant",
"inherit": "Inherit"
}
},
@@ -63,21 +63,13 @@
"global": "Global Iris Settings",
"course": "Course Iris Settings",
"exercise": "Exercise Iris Settings"
- },
- "autoUpdate": {
- "title": "Auto Update Settings",
- "tooltip": "If enabled, the specific global Iris settings will be automatically updated when a new release of Artemis provides new Iris settings.",
- "chatLabel": "Auto Update Chat Settings",
- "hestiaLabel": "Auto Update Hestia Settings",
- "lectureIngestionLabel": "Auto Update Lecture Ingestion Settings",
- "competencyGenerationLabel": "Auto Update Competency Generation Settings"
}
},
"error": {
"forbidden": "Artemis is not configured to use Iris. (Invalid token)",
"internalPyrisError": "An internal error when communicating with the LLM occurred. Error message is: {{ pyrisErrorMessage }}.",
"invalidTemplate": "The template is invalid. Error message is: {{ pyrisErrorMessage }}.",
- "noModelAvailable": "Model {{ model }} is not available to use. Please contact your administrator if this problem persists.",
+ "noVariantAvailable": "Variant {{ variant }} is not available to use. Please contact your administrator if this problem persists.",
"noResponse": "No response from Iris was received.",
"parseResponse": "An error occurred while parsing the response from Iris. Cause: {{ cause }}"
},
diff --git a/src/test/java/de/tum/cit/aet/artemis/core/connector/IrisRequestMockProvider.java b/src/test/java/de/tum/cit/aet/artemis/core/connector/IrisRequestMockProvider.java
index 4c7146242014..2e4506485ead 100644
--- a/src/test/java/de/tum/cit/aet/artemis/core/connector/IrisRequestMockProvider.java
+++ b/src/test/java/de/tum/cit/aet/artemis/core/connector/IrisRequestMockProvider.java
@@ -28,8 +28,9 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
+import de.tum.cit.aet.artemis.iris.domain.settings.IrisSubSettingsType;
import de.tum.cit.aet.artemis.iris.service.pyris.dto.PyrisHealthStatusDTO;
-import de.tum.cit.aet.artemis.iris.service.pyris.dto.PyrisModelDTO;
+import de.tum.cit.aet.artemis.iris.service.pyris.dto.PyrisVariantDTO;
import de.tum.cit.aet.artemis.iris.service.pyris.dto.chat.exercise.PyrisExerciseChatPipelineExecutionDTO;
import de.tum.cit.aet.artemis.iris.service.pyris.dto.competency.PyrisCompetencyExtractionPipelineExecutionDTO;
import de.tum.cit.aet.artemis.iris.service.pyris.dto.lectureingestionwebhook.PyrisWebhookLectureIngestionExecutionDTO;
@@ -52,8 +53,8 @@ public class IrisRequestMockProvider {
@Value("${artemis.iris.url}/api/v1/webhooks")
private URL webhooksApiURL;
- @Value("${artemis.iris.url}/api/v1/models")
- private URL modelsApiURL;
+ @Value("${artemis.iris.url}/api/v1/pipelines/")
+ private String variantsApiBaseURL;
@Value("${artemis.iris.url}/api/v1/health/")
private URL healthApiURL;
@@ -139,11 +140,11 @@ public void mockIngestionWebhookRunError(int httpStatus) {
// @formatter:on
}
- public void mockModelsResponse() throws JsonProcessingException {
- var irisModelDTO = new PyrisModelDTO("TEST_MODEL", "Test model", "Test description");
- var irisModelDTOArray = new PyrisModelDTO[] { irisModelDTO };
+ public void mockVariantsResponse(IrisSubSettingsType feature) throws JsonProcessingException {
+ var irisModelDTO = new PyrisVariantDTO("TEST_MODEL", "Test model", "Test description");
+ var irisModelDTOArray = new PyrisVariantDTO[] { irisModelDTO };
// @formatter:off
- mockServer.expect(ExpectedCount.once(), requestTo(modelsApiURL.toString()))
+ mockServer.expect(ExpectedCount.once(), requestTo(variantsApiBaseURL + feature.name() + "/variants"))
.andExpect(method(HttpMethod.GET))
.andRespond(withSuccess(mapper.writeValueAsString(irisModelDTOArray), MediaType.APPLICATION_JSON));
// @formatter:on
@@ -169,9 +170,9 @@ public void mockStatusResponses() throws JsonProcessingException {
/**
* Mocks a get model error from the Pyris models endpoint
*/
- public void mockModelsError() {
+ public void mockVariantsError(IrisSubSettingsType feature) {
// @formatter:off
- mockServer.expect(ExpectedCount.once(), requestTo(modelsApiURL.toString()))
+ mockServer.expect(ExpectedCount.once(), requestTo(variantsApiBaseURL + feature.name() + "/variants"))
.andExpect(method(HttpMethod.GET))
.andRespond(withRawStatus(418));
// @formatter:on
diff --git a/src/test/java/de/tum/cit/aet/artemis/iris/AbstractIrisIntegrationTest.java b/src/test/java/de/tum/cit/aet/artemis/iris/AbstractIrisIntegrationTest.java
index 34337b170baf..28cf037fa204 100644
--- a/src/test/java/de/tum/cit/aet/artemis/iris/AbstractIrisIntegrationTest.java
+++ b/src/test/java/de/tum/cit/aet/artemis/iris/AbstractIrisIntegrationTest.java
@@ -18,7 +18,6 @@
import de.tum.cit.aet.artemis.core.connector.IrisRequestMockProvider;
import de.tum.cit.aet.artemis.core.domain.Course;
-import de.tum.cit.aet.artemis.iris.domain.IrisTemplate;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisSubSettings;
import de.tum.cit.aet.artemis.iris.repository.IrisSettingsRepository;
import de.tum.cit.aet.artemis.iris.service.settings.IrisSettingsService;
@@ -60,7 +59,6 @@ void tearDown() throws Exception {
protected void activateIrisGlobally() {
var globalSettings = irisSettingsService.getGlobalSettings();
activateSubSettings(globalSettings.getIrisChatSettings());
- activateSubSettings(globalSettings.getIrisHestiaSettings());
activateSubSettings(globalSettings.getIrisLectureIngestionSettings());
activateSubSettings(globalSettings.getIrisCompetencyGenerationSettings());
irisSettingsRepository.save(globalSettings);
@@ -73,21 +71,16 @@ protected void activateIrisGlobally() {
*/
private void activateSubSettings(IrisSubSettings settings) {
settings.setEnabled(true);
- settings.setPreferredModel(null);
- settings.setAllowedModels(new TreeSet<>(Set.of("dummy")));
+ settings.setSelectedVariant("default");
+ settings.setAllowedVariants(new TreeSet<>(Set.of("default")));
}
protected void activateIrisFor(Course course) {
var courseSettings = irisSettingsService.getDefaultSettingsFor(course);
activateSubSettings(courseSettings.getIrisChatSettings());
- courseSettings.getIrisChatSettings().setTemplate(createDummyTemplate());
-
- activateSubSettings(courseSettings.getIrisHestiaSettings());
- courseSettings.getIrisHestiaSettings().setTemplate(createDummyTemplate());
activateSubSettings(courseSettings.getIrisCompetencyGenerationSettings());
- courseSettings.getIrisCompetencyGenerationSettings().setTemplate(createDummyTemplate());
activateSubSettings(courseSettings.getIrisLectureIngestionSettings());
@@ -97,14 +90,9 @@ protected void activateIrisFor(Course course) {
protected void activateIrisFor(ProgrammingExercise exercise) {
var exerciseSettings = irisSettingsService.getDefaultSettingsFor(exercise);
activateSubSettings(exerciseSettings.getIrisChatSettings());
- exerciseSettings.getIrisChatSettings().setTemplate(createDummyTemplate());
irisSettingsRepository.save(exerciseSettings);
}
- protected IrisTemplate createDummyTemplate() {
- return new IrisTemplate("Hello World");
- }
-
/**
* Verify that the given messages were sent through the websocket for the given user and topic.
*
diff --git a/src/test/java/de/tum/cit/aet/artemis/iris/PyrisConnectorServiceTest.java b/src/test/java/de/tum/cit/aet/artemis/iris/PyrisConnectorServiceTest.java
index 413b0b77c046..de726729a035 100644
--- a/src/test/java/de/tum/cit/aet/artemis/iris/PyrisConnectorServiceTest.java
+++ b/src/test/java/de/tum/cit/aet/artemis/iris/PyrisConnectorServiceTest.java
@@ -5,12 +5,13 @@
import java.util.stream.Stream;
-import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.EnumSource;
import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.beans.factory.annotation.Autowired;
+import de.tum.cit.aet.artemis.iris.domain.settings.IrisSubSettingsType;
import de.tum.cit.aet.artemis.iris.exception.IrisForbiddenException;
import de.tum.cit.aet.artemis.iris.exception.IrisInternalPyrisErrorException;
import de.tum.cit.aet.artemis.iris.service.pyris.PyrisConnectorException;
@@ -49,20 +50,22 @@ void testExceptionIngestionV2(int httpStatus, Class> exceptionClass) {
assertThatThrownBy(() -> pyrisConnectorService.executeLectureWebhook("fullIngestion", null)).isInstanceOf(exceptionClass);
}
- @Test
- void testOfferedModels() throws Exception {
- irisRequestMockProvider.mockModelsResponse();
+ @ParameterizedTest
+ @EnumSource(IrisSubSettingsType.class)
+ void testOfferedModels(IrisSubSettingsType feature) throws Exception {
+ irisRequestMockProvider.mockVariantsResponse(feature);
- var offeredModels = pyrisConnectorService.getOfferedModels();
+ var offeredModels = pyrisConnectorService.getOfferedVariants(feature);
assertThat(offeredModels).hasSize(1);
assertThat(offeredModels.getFirst().id()).isEqualTo("TEST_MODEL");
}
- @Test
- void testOfferedModelsError() {
- irisRequestMockProvider.mockModelsError();
+ @ParameterizedTest
+ @EnumSource(IrisSubSettingsType.class)
+ void testOfferedModelsError(IrisSubSettingsType feature) {
+ irisRequestMockProvider.mockVariantsError(feature);
- assertThatThrownBy(() -> pyrisConnectorService.getOfferedModels()).isInstanceOf(PyrisConnectorException.class);
+ assertThatThrownBy(() -> pyrisConnectorService.getOfferedVariants(feature)).isInstanceOf(PyrisConnectorException.class);
}
}
diff --git a/src/test/java/de/tum/cit/aet/artemis/iris/settings/IrisSettingsIntegrationTest.java b/src/test/java/de/tum/cit/aet/artemis/iris/settings/IrisSettingsIntegrationTest.java
index 402f6501a3c0..211b0d122d55 100644
--- a/src/test/java/de/tum/cit/aet/artemis/iris/settings/IrisSettingsIntegrationTest.java
+++ b/src/test/java/de/tum/cit/aet/artemis/iris/settings/IrisSettingsIntegrationTest.java
@@ -17,7 +17,6 @@
import de.tum.cit.aet.artemis.iris.domain.settings.IrisCompetencyGenerationSubSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisCourseSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisExerciseSettings;
-import de.tum.cit.aet.artemis.iris.domain.settings.IrisHestiaSubSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisLectureIngestionSubSettings;
import de.tum.cit.aet.artemis.iris.domain.settings.IrisSettings;
import de.tum.cit.aet.artemis.iris.dto.IrisCombinedSettingsDTO;
@@ -56,7 +55,7 @@ void getMissingSettingsForCourse() throws Exception {
assertThat(loadedSettings2).isNotNull().usingRecursiveComparison().ignoringFieldsOfTypes(HashSet.class, TreeSet.class).ignoringActualNullFields()
.isEqualTo(irisSettingsService.getCombinedIrisSettingsFor(course, false));
assertThat(loadedSettings1).isNotNull().usingRecursiveComparison()
- .ignoringFields("id", "course", "irisChatSettings.id", "iris_lecture_ingestion_settings_id", "irisHestiaSettings.id", "irisCompetencyGenerationSettings.id")
+ .ignoringFields("id", "course", "irisChatSettings.id", "iris_lecture_ingestion_settings_id", "irisCompetencyGenerationSettings.id")
.isEqualTo(irisSettingsService.getDefaultSettingsFor(course));
}
@@ -71,8 +70,8 @@ void getCourseSettings() throws Exception {
var loadedSettings2 = request.get("/api/courses/" + course.getId() + "/iris-settings", HttpStatus.OK, IrisCombinedSettingsDTO.class);
assertThat(loadedSettings1).isNotNull().usingRecursiveComparison()
- .ignoringFields("id", "course", "irisChatSettings.id", "irisLectureIngestionSettings.id", "irisHestiaSettings.id", "irisCompetencyGenerationSettings.id")
- .ignoringExpectedNullFields().isEqualTo(loadedSettings2);
+ .ignoringFields("id", "course", "irisChatSettings.id", "irisLectureIngestionSettings.id", "irisCompetencyGenerationSettings.id").ignoringExpectedNullFields()
+ .isEqualTo(loadedSettings2);
assertThat(loadedSettings1).isNotNull().usingRecursiveComparison().ignoringFields("course")
.isEqualTo(irisSettingsRepository.findCourseSettings(course.getId()).orElseThrow());
}
@@ -87,10 +86,9 @@ void getCourseSettingsAsUser() throws Exception {
request.get("/api/courses/" + course.getId() + "/raw-iris-settings", HttpStatus.FORBIDDEN, IrisSettings.class);
var loadedSettings = request.get("/api/courses/" + course.getId() + "/iris-settings", HttpStatus.OK, IrisCombinedSettingsDTO.class);
- assertThat(loadedSettings)
- .isNotNull().usingRecursiveComparison().ignoringCollectionOrderInFields("irisChatSettings.allowedModels", "irisLectureIngestionSettings.allowedModels",
- "irisCompetencyGenerationSettings.allowedModels", "irisHestiaSettings.allowedModels")
- .ignoringFields("id").isEqualTo(irisSettingsService.getCombinedIrisSettingsFor(course, true));
+ assertThat(loadedSettings).isNotNull().usingRecursiveComparison().ignoringCollectionOrderInFields("irisChatSettings.allowedVariants",
+ "irisLectureIngestionSettings.allowedVariants", "irisCompetencyGenerationSettings.allowedVariants").ignoringFields("id")
+ .isEqualTo(irisSettingsService.getCombinedIrisSettingsFor(course, true));
}
@Test
@@ -103,7 +101,6 @@ void updateCourseSettings1() throws Exception {
var loadedSettings1 = request.get("/api/courses/" + course.getId() + "/raw-iris-settings", HttpStatus.OK, IrisSettings.class);
loadedSettings1.getIrisChatSettings().setEnabled(false);
- loadedSettings1.getIrisHestiaSettings().setEnabled(false);
loadedSettings1.getIrisCompetencyGenerationSettings().setEnabled(false);
loadedSettings1.getIrisLectureIngestionSettings().setEnabled(false);
@@ -115,7 +112,6 @@ void updateCourseSettings1() throws Exception {
assertThat(updatedSettings.getId()).isEqualTo(loadedSettings1.getId());
assertThat(updatedSettings.getIrisLectureIngestionSettings().getId()).isEqualTo(loadedSettings1.getIrisLectureIngestionSettings().getId());
assertThat(updatedSettings.getIrisChatSettings().getId()).isEqualTo(loadedSettings1.getIrisChatSettings().getId());
- assertThat(updatedSettings.getIrisHestiaSettings().getId()).isEqualTo(loadedSettings1.getIrisHestiaSettings().getId());
assertThat(updatedSettings.getIrisCompetencyGenerationSettings().getId()).isEqualTo(loadedSettings1.getIrisCompetencyGenerationSettings().getId());
}
@@ -129,12 +125,10 @@ void updateCourseSettings2() throws Exception {
var loadedSettings1 = request.get("/api/courses/" + course.getId() + "/raw-iris-settings", HttpStatus.OK, IrisSettings.class);
var chatSubSettingsId = loadedSettings1.getIrisChatSettings().getId();
- var hestiaSubSettingsId = loadedSettings1.getIrisHestiaSettings().getId();
var competencyGenerationSubSettingsId = loadedSettings1.getIrisCompetencyGenerationSettings().getId();
var lectureIngestionSubSettingsId = loadedSettings1.getIrisLectureIngestionSettings().getId();
loadedSettings1.setIrisLectureIngestionSettings(null);
loadedSettings1.setIrisChatSettings(null);
- loadedSettings1.setIrisHestiaSettings(null);
loadedSettings1.setIrisCompetencyGenerationSettings(null);
var updatedSettings = request.putWithResponseBody("/api/courses/" + course.getId() + "/raw-iris-settings", loadedSettings1, IrisSettings.class, HttpStatus.OK);
@@ -145,7 +139,6 @@ void updateCourseSettings2() throws Exception {
// Original subsettings should not exist anymore
assertThat(irisSubSettingsRepository.findById(lectureIngestionSubSettingsId)).isEmpty();
assertThat(irisSubSettingsRepository.findById(chatSubSettingsId)).isEmpty();
- assertThat(irisSubSettingsRepository.findById(hestiaSubSettingsId)).isEmpty();
assertThat(irisSubSettingsRepository.findById(competencyGenerationSubSettingsId)).isEmpty();
}
@@ -159,18 +152,11 @@ void updateCourseSettings3() throws Exception {
courseSettings.setCourse(course);
courseSettings.setIrisChatSettings(new IrisChatSubSettings());
courseSettings.getIrisChatSettings().setEnabled(true);
- courseSettings.getIrisChatSettings().setTemplate(createDummyTemplate());
- courseSettings.getIrisChatSettings().setPreferredModel(null);
-
- courseSettings.setIrisHestiaSettings(new IrisHestiaSubSettings());
- courseSettings.getIrisHestiaSettings().setEnabled(true);
- courseSettings.getIrisHestiaSettings().setTemplate(createDummyTemplate());
- courseSettings.getIrisHestiaSettings().setPreferredModel(null);
+ courseSettings.getIrisChatSettings().setSelectedVariant(null);
courseSettings.setIrisCompetencyGenerationSettings(new IrisCompetencyGenerationSubSettings());
courseSettings.getIrisCompetencyGenerationSettings().setEnabled(true);
- courseSettings.getIrisCompetencyGenerationSettings().setTemplate(createDummyTemplate());
- courseSettings.getIrisCompetencyGenerationSettings().setPreferredModel(null);
+ courseSettings.getIrisCompetencyGenerationSettings().setSelectedVariant(null);
courseSettings.setIrisLectureIngestionSettings(new IrisLectureIngestionSubSettings());
courseSettings.getIrisLectureIngestionSettings().setEnabled(true);
@@ -179,10 +165,8 @@ void updateCourseSettings3() throws Exception {
var loadedSettings1 = request.get("/api/courses/" + course.getId() + "/raw-iris-settings", HttpStatus.OK, IrisSettings.class);
assertThat(updatedSettings).usingRecursiveComparison().ignoringFields("course").isEqualTo(loadedSettings1);
- assertThat(loadedSettings1)
- .usingRecursiveComparison().ignoringFields("id", "course", "irisChatSettings.id", "irisChatSettings.template.id", "irisLectureIngestionSettings.id",
- "irisHestiaSettings.id", "irisHestiaSettings.template.id", "irisCompetencyGenerationSettings.id", "irisCompetencyGenerationSettings.template.id")
- .isEqualTo(courseSettings);
+ assertThat(loadedSettings1).usingRecursiveComparison().ignoringFields("id", "course", "irisChatSettings.id", "irisChatSettings.template.id",
+ "irisLectureIngestionSettings.id", "irisCompetencyGenerationSettings.id", "irisCompetencyGenerationSettings.template.id").isEqualTo(courseSettings);
}
@Test
@@ -214,7 +198,6 @@ void getProgrammingExerciseSettings() throws Exception {
assertThat(loadedSettings1).isNotNull().usingRecursiveComparison().ignoringFields("id", "exercise", "irisChatSettings.id").ignoringExpectedNullFields()
.isEqualTo(loadedSettings2);
- assertThat(loadedSettings1.getIrisHestiaSettings()).isNull();
assertThat(loadedSettings1.getIrisCompetencyGenerationSettings()).isNull();
assertThat(loadedSettings1.getIrisLectureIngestionSettings()).isNull();
assertThat(loadedSettings1).isNotNull().usingRecursiveComparison().ignoringFields("exercise")
@@ -233,7 +216,7 @@ void getProgrammingExerciseSettingsAsUser() throws Exception {
var loadedSettings = request.get("/api/programming-exercises/" + programmingExercise.getId() + "/iris-settings", HttpStatus.OK, IrisCombinedSettingsDTO.class);
assertThat(loadedSettings).isNotNull().usingRecursiveComparison().ignoringFields("id")
- .ignoringCollectionOrderInFields("irisChatSettings.allowedModels", "irisCompetencyGenerationSettings.allowedModels", "irisHestiaSettings.allowedModels")
+ .ignoringCollectionOrderInFields("irisChatSettings.allowedVariants", "irisCompetencyGenerationSettings.allowedVariants")
.isEqualTo(irisSettingsService.getCombinedIrisSettingsFor(programmingExercise, true));
}
@@ -271,7 +254,6 @@ void updateProgrammingExerciseSettings2() throws Exception {
var chatSubSettingsId = loadedSettings1.getIrisChatSettings().getId();
loadedSettings1.setIrisChatSettings(null);
- loadedSettings1.setIrisHestiaSettings(null);
var updatedSettings = request.putWithResponseBody("/api/programming-exercises/" + programmingExercise.getId() + "/raw-iris-settings", loadedSettings1, IrisSettings.class,
HttpStatus.OK);
@@ -294,8 +276,7 @@ void updateProgrammingExerciseSettings3() throws Exception {
exerciseSettings.setExercise(programmingExercise);
exerciseSettings.setIrisChatSettings(new IrisChatSubSettings());
exerciseSettings.getIrisChatSettings().setEnabled(true);
- exerciseSettings.getIrisChatSettings().setTemplate(createDummyTemplate());
- exerciseSettings.getIrisChatSettings().setPreferredModel(null);
+ exerciseSettings.getIrisChatSettings().setSelectedVariant(null);
var updatedSettings = request.putWithResponseBody("/api/programming-exercises/" + programmingExercise.getId() + "/raw-iris-settings", exerciseSettings, IrisSettings.class,
HttpStatus.OK);
diff --git a/src/test/javascript/spec/component/iris/settings/iris-common-sub-settings-update.component.spec.ts b/src/test/javascript/spec/component/iris/settings/iris-common-sub-settings-update.component.spec.ts
index 0a3bf65f8433..2b36487e4576 100644
--- a/src/test/javascript/spec/component/iris/settings/iris-common-sub-settings-update.component.spec.ts
+++ b/src/test/javascript/spec/component/iris/settings/iris-common-sub-settings-update.component.spec.ts
@@ -1,39 +1,43 @@
import { ArtemisTestModule } from '../../../test.module';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { FormsModule } from '@angular/forms';
-import { IrisTemplate } from 'app/entities/iris/settings/iris-template';
import { IrisChatSubSettings } from 'app/entities/iris/settings/iris-sub-settings.model';
import { NgbTooltip } from '@ng-bootstrap/ng-bootstrap';
import { MockDirective, MockPipe } from 'ng-mocks';
import { SimpleChange, SimpleChanges } from '@angular/core';
import { IrisCommonSubSettingsUpdateComponent } from 'app/iris/settings/iris-settings-update/iris-common-sub-settings-update/iris-common-sub-settings-update.component';
-import { mockModels } from './mock-settings';
+import { mockVariants } from './mock-settings';
import { IrisSettingsType } from 'app/entities/iris/settings/iris-settings.model';
import { ArtemisTranslatePipe } from 'app/shared/pipes/artemis-translate.pipe';
+import { IrisSettingsService } from 'app/iris/settings/shared/iris-settings.service';
+import { of } from 'rxjs';
function baseSettings() {
- const mockTemplate = new IrisTemplate();
- mockTemplate.id = 1;
- mockTemplate.content = 'Hello World';
const irisSubSettings = new IrisChatSubSettings();
irisSubSettings.id = 2;
irisSubSettings.enabled = true;
- const allowedModels = mockModels();
- allowedModels.pop();
- irisSubSettings.allowedModels = allowedModels.map((model) => model.id!);
- irisSubSettings.preferredModel = allowedModels[0].id!;
+ const allowedVariants = mockVariants();
+ allowedVariants.pop();
+ irisSubSettings.allowedVariants = allowedVariants.map((model) => model.id!);
+ irisSubSettings.selectedVariant = allowedVariants[0].id!;
return irisSubSettings;
}
describe('IrisCommonSubSettingsUpdateComponent Component', () => {
let comp: IrisCommonSubSettingsUpdateComponent;
let fixture: ComponentFixture;
+ let getVariantsSpy: jest.SpyInstance;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ArtemisTestModule, FormsModule, MockDirective(NgbTooltip), MockPipe(ArtemisTranslatePipe)],
declarations: [IrisCommonSubSettingsUpdateComponent],
- }).compileComponents();
+ })
+ .compileComponents()
+ .then(() => {
+ const irisSettingsService = TestBed.inject(IrisSettingsService);
+ getVariantsSpy = jest.spyOn(irisSettingsService, 'getVariantsForFeature').mockReturnValue(of(mockVariants()));
+ });
fixture = TestBed.createComponent(IrisCommonSubSettingsUpdateComponent);
comp = fixture.componentInstance;
});
@@ -45,28 +49,29 @@ describe('IrisCommonSubSettingsUpdateComponent Component', () => {
it('child setup works', () => {
comp.subSettings = baseSettings();
comp.parentSubSettings = baseSettings();
- comp.allIrisModels = mockModels();
+ comp.availableVariants = mockVariants();
comp.settingsType = IrisSettingsType.EXERCISE;
fixture.detectChanges();
+ expect(getVariantsSpy).toHaveBeenCalledOnce();
expect(comp.enabled).toBeTrue();
- expect(comp.inheritAllowedModels).toBeFalse();
- expect(comp.allowedIrisModels).toEqual([mockModels()[0]]);
+ expect(comp.inheritAllowedVariants).toBeFalse();
+ expect(comp.allowedVariants).toEqual([mockVariants()[0]]);
});
it('parent setup works', () => {
const subSettings = baseSettings();
- subSettings.allowedModels = undefined;
- subSettings.preferredModel = undefined;
+ subSettings.allowedVariants = undefined;
+ subSettings.selectedVariant = undefined;
comp.subSettings = subSettings;
comp.parentSubSettings = baseSettings();
- comp.allIrisModels = mockModels();
+ comp.availableVariants = mockVariants();
comp.settingsType = IrisSettingsType.EXERCISE;
fixture.detectChanges();
expect(comp.enabled).toBeTrue();
- expect(comp.inheritAllowedModels).toBeTrue();
- expect(comp.allowedIrisModels).toEqual([mockModels()[0]]);
+ expect(comp.inheritAllowedVariants).toBeTrue();
+ expect(comp.allowedVariants).toEqual([mockVariants()[0]]);
});
it('prevents enabling chat settings if the parent chat settings disabled', () => {
@@ -75,7 +80,7 @@ describe('IrisCommonSubSettingsUpdateComponent Component', () => {
comp.parentSubSettings.enabled = false;
comp.isAdmin = true;
comp.settingsType = IrisSettingsType.EXERCISE;
- comp.allIrisModels = mockModels();
+ comp.availableVariants = mockVariants();
fixture.detectChanges();
expect(comp.inheritDisabled).toBeTrue();
@@ -88,7 +93,7 @@ describe('IrisCommonSubSettingsUpdateComponent Component', () => {
comp.parentSubSettings.enabled = false;
comp.isAdmin = true;
comp.settingsType = IrisSettingsType.COURSE;
- comp.allIrisModels = mockModels();
+ comp.availableVariants = mockVariants();
fixture.detectChanges();
expect(comp.inheritDisabled).toBeTrue();
@@ -96,34 +101,34 @@ describe('IrisCommonSubSettingsUpdateComponent Component', () => {
});
it('change allowed model', () => {
- const allIrisModels = mockModels();
+ const availableVariants = mockVariants();
comp.subSettings = baseSettings();
comp.parentSubSettings = baseSettings();
- comp.allIrisModels = allIrisModels;
+ comp.availableVariants = availableVariants;
comp.settingsType = IrisSettingsType.EXERCISE;
fixture.detectChanges();
- comp.onAllowedIrisModelsSelectionChange(allIrisModels[1]);
- expect(comp.allowedIrisModels).toEqual([allIrisModels[0], allIrisModels[1]]);
- comp.onAllowedIrisModelsSelectionChange(allIrisModels[0]);
- expect(comp.allowedIrisModels).toEqual([allIrisModels[1]]);
+ comp.onAllowedIrisVariantsSelectionChange(availableVariants[1]);
+ expect(comp.allowedVariants).toEqual([availableVariants[0], availableVariants[1]]);
+ comp.onAllowedIrisVariantsSelectionChange(availableVariants[0]);
+ expect(comp.allowedVariants).toEqual([availableVariants[1]]);
});
it('change preferred model', () => {
comp.subSettings = baseSettings();
comp.parentSubSettings = baseSettings();
- comp.allIrisModels = mockModels();
+ comp.availableVariants = mockVariants();
comp.settingsType = IrisSettingsType.EXERCISE;
fixture.detectChanges();
- comp.setModel(mockModels()[1]);
- expect(comp.subSettings!.preferredModel).toBe(mockModels()[1].id);
+ comp.setVariant(mockVariants()[1]);
+ expect(comp.subSettings!.selectedVariant).toBe(mockVariants()[1].id);
});
it('change enabled', () => {
comp.subSettings = baseSettings();
comp.parentSubSettings = baseSettings();
- comp.allIrisModels = mockModels();
+ comp.availableVariants = mockVariants();
comp.settingsType = IrisSettingsType.EXERCISE;
fixture.detectChanges();
@@ -139,41 +144,41 @@ describe('IrisCommonSubSettingsUpdateComponent Component', () => {
it('change inherit allowed models', () => {
comp.subSettings = baseSettings();
comp.parentSubSettings = baseSettings();
- comp.allIrisModels = mockModels();
+ comp.availableVariants = mockVariants();
comp.settingsType = IrisSettingsType.EXERCISE;
fixture.detectChanges();
- comp.inheritAllowedModels = true;
- comp.onInheritAllowedModelsChange();
- expect(comp.subSettings!.allowedModels).toBeUndefined();
- expect(comp.allowedIrisModels).toEqual(comp.getAvailableModels());
+ comp.inheritAllowedVariants = true;
+ comp.onInheritAllowedVariantsChange();
+ expect(comp.subSettings!.allowedVariants).toBeUndefined();
+ expect(comp.allowedVariants).toEqual(comp.getAllowedVariants());
- comp.inheritAllowedModels = false;
- comp.onInheritAllowedModelsChange();
- expect(comp.subSettings!.allowedModels).toEqual(comp.allowedIrisModels.map((model) => model.id));
+ comp.inheritAllowedVariants = false;
+ comp.onInheritAllowedVariantsChange();
+ expect(comp.subSettings!.allowedVariants).toEqual(comp.allowedVariants.map((model) => model.id));
});
it('ngOnChanges works', () => {
comp.subSettings = baseSettings();
comp.parentSubSettings = baseSettings();
- comp.allIrisModels = mockModels();
+ comp.availableVariants = mockVariants();
comp.settingsType = IrisSettingsType.EXERCISE;
fixture.detectChanges();
const newSubSettings = baseSettings();
newSubSettings.enabled = false;
- const newModels = mockModels();
+ const newModels = mockVariants();
newModels.pop();
const changes: SimpleChanges = {
subSettings: new SimpleChange(comp.subSettings, newSubSettings, false),
- allIrisModels: new SimpleChange(comp.allIrisModels, newModels, false),
+ availableVariants: new SimpleChange(comp.availableVariants, newModels, false),
};
comp.subSettings = newSubSettings;
- comp.allIrisModels = mockModels();
+ comp.availableVariants = mockVariants();
comp.ngOnChanges(changes);
expect(comp.enabled).toBeFalse();
- expect(comp.allowedIrisModels).toEqual(newModels);
+ expect(comp.allowedVariants).toEqual(newModels);
});
});
diff --git a/src/test/javascript/spec/component/iris/settings/iris-course-settings-update.component.spec.ts b/src/test/javascript/spec/component/iris/settings/iris-course-settings-update.component.spec.ts
index 87c4fcb5989d..d31ecbaba114 100644
--- a/src/test/javascript/spec/component/iris/settings/iris-course-settings-update.component.spec.ts
+++ b/src/test/javascript/spec/component/iris/settings/iris-course-settings-update.component.spec.ts
@@ -6,7 +6,6 @@ import { MockComponent, MockDirective, MockProvider } from 'ng-mocks';
import { BehaviorSubject, of } from 'rxjs';
import { ButtonComponent } from 'app/shared/components/button.component';
import { IrisCommonSubSettingsUpdateComponent } from 'app/iris/settings/iris-settings-update/iris-common-sub-settings-update/iris-common-sub-settings-update.component';
-import { IrisGlobalAutoupdateSettingsUpdateComponent } from 'app/iris/settings/iris-settings-update/iris-global-autoupdate-settings-update/iris-global-autoupdate-settings-update.component';
import { mockEmptySettings, mockSettings } from './mock-settings';
import { ActivatedRoute, Params, provideRouter } from '@angular/router';
import { NgModel } from '@angular/forms';
@@ -23,7 +22,6 @@ describe('IrisCourseSettingsUpdateComponent Component', () => {
const route = { parent: { params: routeParamsSubject.asObservable() } } as ActivatedRoute;
let paramsSpy: jest.SpyInstance;
let getSettingsSpy: jest.SpyInstance;
- //let getModelsSpy: jest.SpyInstance;
let getParentSettingsSpy: jest.SpyInstance;
beforeEach(() => {
@@ -33,7 +31,6 @@ describe('IrisCourseSettingsUpdateComponent Component', () => {
IrisCourseSettingsUpdateComponent,
IrisSettingsUpdateComponent,
MockComponent(IrisCommonSubSettingsUpdateComponent),
- MockComponent(IrisGlobalAutoupdateSettingsUpdateComponent),
MockComponent(ButtonComponent),
MockDirective(NgModel),
],
@@ -49,7 +46,6 @@ describe('IrisCourseSettingsUpdateComponent Component', () => {
const irisSettings = mockSettings();
getSettingsSpy = jest.spyOn(irisSettingsService, 'getUncombinedCourseSettings').mockReturnValue(of(irisSettings));
- //getModelsSpy = jest.spyOn(irisSettingsService, 'getIrisModels').mockReturnValue(of(mockModels()));
getParentSettingsSpy = jest.spyOn(irisSettingsService, 'getGlobalSettings').mockReturnValue(of(irisSettings));
});
fixture = TestBed.createComponent(IrisCourseSettingsUpdateComponent);
@@ -66,11 +62,9 @@ describe('IrisCourseSettingsUpdateComponent Component', () => {
expect(comp.courseId).toBe(1);
expect(comp.settingsUpdateComponent).toBeTruthy();
expect(getSettingsSpy).toHaveBeenCalledWith(1);
- //expect(getModelsSpy).toHaveBeenCalledOnce();
expect(getParentSettingsSpy).toHaveBeenCalledOnce();
- expect(fixture.debugElement.query(By.directive(IrisGlobalAutoupdateSettingsUpdateComponent))).toBeFalsy();
- expect(fixture.debugElement.queryAll(By.directive(IrisCommonSubSettingsUpdateComponent))).toHaveLength(4);
+ expect(fixture.debugElement.queryAll(By.directive(IrisCommonSubSettingsUpdateComponent))).toHaveLength(3);
});
it('Can deactivate correctly', () => {
@@ -99,7 +93,6 @@ describe('IrisCourseSettingsUpdateComponent Component', () => {
comp.settingsUpdateComponent!.fillEmptyIrisSubSettings();
expect(comp.settingsUpdateComponent!.irisSettings.irisChatSettings).toBeTruthy();
expect(comp.settingsUpdateComponent!.irisSettings.irisLectureIngestionSettings).toBeTruthy();
- expect(comp.settingsUpdateComponent!.irisSettings.irisHestiaSettings).toBeTruthy();
expect(comp.settingsUpdateComponent!.irisSettings.irisCompetencyGenerationSettings).toBeTruthy();
});
});
diff --git a/src/test/javascript/spec/component/iris/settings/iris-enabled.component.spec.ts b/src/test/javascript/spec/component/iris/settings/iris-enabled.component.spec.ts
index f4aba8617eee..c47b91fdd5b1 100644
--- a/src/test/javascript/spec/component/iris/settings/iris-enabled.component.spec.ts
+++ b/src/test/javascript/spec/component/iris/settings/iris-enabled.component.spec.ts
@@ -47,7 +47,7 @@ describe('IrisEnabledComponent', () => {
expect(comp).toBeDefined();
});
- it.each([IrisSubSettingsType.CHAT, IrisSubSettingsType.HESTIA, IrisSubSettingsType.COMPETENCY_GENERATION])('should load exercise', async (subSettingstype) => {
+ it.each([IrisSubSettingsType.CHAT, IrisSubSettingsType.COMPETENCY_GENERATION])('should load exercise', async (subSettingstype) => {
const getExerciseSettingsSpy = jest.spyOn(irisSettingsService, 'getUncombinedProgrammingExerciseSettings').mockReturnValue(of(irisSettings));
comp.exercise = exercise;
comp.irisSubSettingsType = subSettingstype;
@@ -58,19 +58,16 @@ describe('IrisEnabledComponent', () => {
expect(comp.irisSubSettings).toBeDefined();
});
- it.each([IrisSubSettingsType.CHAT, IrisSubSettingsType.HESTIA, IrisSubSettingsType.COMPETENCY_GENERATION, IrisSubSettingsType.LECTURE_INGESTION])(
- 'should load course',
- async (subSettingstype) => {
- const getExerciseSettingsSpy = jest.spyOn(irisSettingsService, 'getUncombinedCourseSettings').mockReturnValue(of(irisSettings));
- comp.course = course;
- comp.irisSubSettingsType = subSettingstype;
- fixture.detectChanges();
- expect(getExerciseSettingsSpy).toHaveBeenCalledOnce();
- await Promise.resolve();
- expect(comp.irisSettings).toBe(irisSettings);
- expect(comp.irisSubSettings).toBeDefined();
- },
- );
+ it.each([IrisSubSettingsType.CHAT, IrisSubSettingsType.COMPETENCY_GENERATION, IrisSubSettingsType.LECTURE_INGESTION])('should load course', async (subSettingstype) => {
+ const getExerciseSettingsSpy = jest.spyOn(irisSettingsService, 'getUncombinedCourseSettings').mockReturnValue(of(irisSettings));
+ comp.course = course;
+ comp.irisSubSettingsType = subSettingstype;
+ fixture.detectChanges();
+ expect(getExerciseSettingsSpy).toHaveBeenCalledOnce();
+ await Promise.resolve();
+ expect(comp.irisSettings).toBe(irisSettings);
+ expect(comp.irisSubSettings).toBeDefined();
+ });
it('should set exercise enabled', async () => {
const setSettingsSpy = jest.spyOn(irisSettingsService, 'setProgrammingExerciseSettings').mockReturnValue(of(new HttpResponse({ body: null as any as IrisSettings })));
@@ -89,8 +86,8 @@ describe('IrisEnabledComponent', () => {
const setSettingsSpy = jest.spyOn(irisSettingsService, 'setCourseSettings').mockReturnValue(of(new HttpResponse({ body: null as any as IrisSettings })));
comp.course = course;
comp.irisSettings = irisSettings;
- comp.irisSubSettingsType = IrisSubSettingsType.HESTIA;
- comp.irisSubSettings = irisSettings.irisHestiaSettings;
+ comp.irisSubSettingsType = IrisSubSettingsType.CHAT;
+ comp.irisSubSettings = irisSettings.irisChatSettings;
comp.setEnabled(true);
expect(setSettingsSpy).toHaveBeenCalledOnce();
diff --git a/src/test/javascript/spec/component/iris/settings/iris-exercise-settings-update.component.spec.ts b/src/test/javascript/spec/component/iris/settings/iris-exercise-settings-update.component.spec.ts
index 98d0ff3f8770..140940787933 100644
--- a/src/test/javascript/spec/component/iris/settings/iris-exercise-settings-update.component.spec.ts
+++ b/src/test/javascript/spec/component/iris/settings/iris-exercise-settings-update.component.spec.ts
@@ -6,7 +6,6 @@ import { MockComponent, MockDirective, MockProvider } from 'ng-mocks';
import { BehaviorSubject, of } from 'rxjs';
import { ButtonComponent } from 'app/shared/components/button.component';
import { IrisCommonSubSettingsUpdateComponent } from 'app/iris/settings/iris-settings-update/iris-common-sub-settings-update/iris-common-sub-settings-update.component';
-import { IrisGlobalAutoupdateSettingsUpdateComponent } from 'app/iris/settings/iris-settings-update/iris-global-autoupdate-settings-update/iris-global-autoupdate-settings-update.component';
import { mockSettings } from './mock-settings';
import { IrisExerciseSettingsUpdateComponent } from 'app/iris/settings/iris-exercise-settings-update/iris-exercise-settings-update.component';
import { ActivatedRoute, Params, provideRouter } from '@angular/router';
@@ -23,7 +22,6 @@ describe('IrisExerciseSettingsUpdateComponent Component', () => {
const route = { parent: { params: routeParamsSubject.asObservable() } } as ActivatedRoute;
let paramsSpy: jest.SpyInstance;
let getSettingsSpy: jest.SpyInstance;
- //let getModelsSpy: jest.SpyInstance;
let getParentSettingsSpy: jest.SpyInstance;
beforeEach(() => {
@@ -33,7 +31,6 @@ describe('IrisExerciseSettingsUpdateComponent Component', () => {
IrisExerciseSettingsUpdateComponent,
IrisSettingsUpdateComponent,
MockComponent(IrisCommonSubSettingsUpdateComponent),
- MockComponent(IrisGlobalAutoupdateSettingsUpdateComponent),
MockComponent(ButtonComponent),
MockDirective(NgModel),
],
@@ -49,7 +46,6 @@ describe('IrisExerciseSettingsUpdateComponent Component', () => {
const irisSettings = mockSettings();
getSettingsSpy = jest.spyOn(irisSettingsService, 'getUncombinedProgrammingExerciseSettings').mockReturnValue(of(irisSettings));
- //getModelsSpy = jest.spyOn(irisSettingsService, 'getIrisModels').mockReturnValue(of(mockModels()));
getParentSettingsSpy = jest.spyOn(irisSettingsService, 'getCombinedCourseSettings').mockReturnValue(of(irisSettings));
});
fixture = TestBed.createComponent(IrisExerciseSettingsUpdateComponent);
@@ -67,10 +63,8 @@ describe('IrisExerciseSettingsUpdateComponent Component', () => {
expect(comp.exerciseId).toBe(2);
expect(comp.settingsUpdateComponent).toBeTruthy();
expect(getSettingsSpy).toHaveBeenCalledWith(2);
- //expect(getModelsSpy).toHaveBeenCalledOnce();
expect(getParentSettingsSpy).toHaveBeenCalledWith(1);
- expect(fixture.debugElement.query(By.directive(IrisGlobalAutoupdateSettingsUpdateComponent))).toBeFalsy();
expect(fixture.debugElement.queryAll(By.directive(IrisCommonSubSettingsUpdateComponent))).toHaveLength(1);
});
diff --git a/src/test/javascript/spec/component/iris/settings/iris-global-settings-update.component.spec.ts b/src/test/javascript/spec/component/iris/settings/iris-global-settings-update.component.spec.ts
index a00353681299..44783963ac05 100644
--- a/src/test/javascript/spec/component/iris/settings/iris-global-settings-update.component.spec.ts
+++ b/src/test/javascript/spec/component/iris/settings/iris-global-settings-update.component.spec.ts
@@ -6,7 +6,6 @@ import { MockComponent, MockDirective, MockProvider } from 'ng-mocks';
import { of } from 'rxjs';
import { ButtonComponent } from 'app/shared/components/button.component';
import { IrisCommonSubSettingsUpdateComponent } from 'app/iris/settings/iris-settings-update/iris-common-sub-settings-update/iris-common-sub-settings-update.component';
-import { IrisGlobalAutoupdateSettingsUpdateComponent } from 'app/iris/settings/iris-settings-update/iris-global-autoupdate-settings-update/iris-global-autoupdate-settings-update.component';
import { mockSettings } from './mock-settings';
import { NgModel } from '@angular/forms';
import { IrisGlobalSettingsUpdateComponent } from 'app/iris/settings/iris-global-settings-update/iris-global-settings-update.component';
@@ -19,7 +18,6 @@ describe('IrisGlobalSettingsUpdateComponent Component', () => {
let fixture: ComponentFixture;
let irisSettingsService: IrisSettingsService;
let getSettingsSpy: jest.SpyInstance;
- //let getModelsSpy: jest.SpyInstance;
beforeEach(() => {
TestBed.configureTestingModule({
@@ -28,7 +26,6 @@ describe('IrisGlobalSettingsUpdateComponent Component', () => {
IrisGlobalSettingsUpdateComponent,
IrisSettingsUpdateComponent,
MockComponent(IrisCommonSubSettingsUpdateComponent),
- MockComponent(IrisGlobalAutoupdateSettingsUpdateComponent),
MockComponent(ButtonComponent),
MockDirective(NgModel),
],
@@ -41,7 +38,6 @@ describe('IrisGlobalSettingsUpdateComponent Component', () => {
// Setup
const irisSettings = mockSettings();
getSettingsSpy = jest.spyOn(irisSettingsService, 'getGlobalSettings').mockReturnValue(of(irisSettings));
- //getModelsSpy = jest.spyOn(irisSettingsService, 'getIrisModels').mockReturnValue(of(mockModels()));
});
fixture = TestBed.createComponent(IrisGlobalSettingsUpdateComponent);
comp = fixture.componentInstance;
@@ -55,10 +51,8 @@ describe('IrisGlobalSettingsUpdateComponent Component', () => {
fixture.detectChanges();
expect(comp.settingsUpdateComponent).toBeTruthy();
expect(getSettingsSpy).toHaveBeenCalledOnce();
- //expect(getModelsSpy).toHaveBeenCalledOnce();
- expect(fixture.debugElement.query(By.directive(IrisGlobalAutoupdateSettingsUpdateComponent))).toBeTruthy();
- expect(fixture.debugElement.queryAll(By.directive(IrisCommonSubSettingsUpdateComponent))).toHaveLength(4);
+ expect(fixture.debugElement.queryAll(By.directive(IrisCommonSubSettingsUpdateComponent))).toHaveLength(3);
});
it('Can deactivate correctly', () => {
diff --git a/src/test/javascript/spec/component/iris/settings/iris-settings-update-component.spec.ts b/src/test/javascript/spec/component/iris/settings/iris-settings-update-component.spec.ts
index 1c3a6fb751b4..4fe2f213f845 100644
--- a/src/test/javascript/spec/component/iris/settings/iris-settings-update-component.spec.ts
+++ b/src/test/javascript/spec/component/iris/settings/iris-settings-update-component.spec.ts
@@ -2,12 +2,11 @@ import { ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testin
import { By } from '@angular/platform-browser';
import { IrisSettingsUpdateComponent } from 'app/iris/settings/iris-settings-update/iris-settings-update.component';
import { IrisSettingsType } from 'app/entities/iris/settings/iris-settings.model';
-import { mockSettings } from './mock-settings';
+import { mockSettings, mockVariants } from './mock-settings';
import { ArtemisTestModule } from '../../../test.module';
import { NgModel } from '@angular/forms';
import { MockComponent, MockDirective, MockPipe, MockProvider } from 'ng-mocks';
import { IrisCommonSubSettingsUpdateComponent } from 'app/iris/settings/iris-settings-update/iris-common-sub-settings-update/iris-common-sub-settings-update.component';
-import { IrisGlobalAutoupdateSettingsUpdateComponent } from 'app/iris/settings/iris-settings-update/iris-global-autoupdate-settings-update/iris-global-autoupdate-settings-update.component';
import { ButtonComponent } from 'app/shared/components/button.component';
import { IrisSettingsService } from 'app/iris/settings/shared/iris-settings.service';
import { of } from 'rxjs';
@@ -17,12 +16,12 @@ import { ArtemisTranslatePipe } from 'app/shared/pipes/artemis-translate.pipe';
describe('IrisSettingsUpdateComponent', () => {
let component: IrisSettingsUpdateComponent;
let fixture: ComponentFixture;
+ let getVariantsSpy: jest.SpyInstance;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ArtemisTestModule],
declarations: [
- IrisGlobalAutoupdateSettingsUpdateComponent,
IrisCourseSettingsUpdateComponent,
IrisSettingsUpdateComponent,
IrisCommonSubSettingsUpdateComponent,
@@ -42,15 +41,12 @@ describe('IrisSettingsUpdateComponent', () => {
.then(() => {
fixture = TestBed.createComponent(IrisSettingsUpdateComponent);
component = fixture.componentInstance;
+
+ const irisSettingsService = TestBed.inject(IrisSettingsService);
+ getVariantsSpy = jest.spyOn(irisSettingsService, 'getVariantsForFeature').mockReturnValue(of(mockVariants()));
});
});
- it('should display global auto-update settings only if settingsType is GLOBAL', () => {
- component.irisSettings = mockSettings();
- component.settingsType = IrisSettingsType.GLOBAL;
- fixture.detectChanges();
- const globalSettingsElement = fixture.debugElement.query(By.css('jhi-iris-global-autoupdate-settings-update'));
- expect(globalSettingsElement).toBeTruthy();
- });
+
it('should display the checkbox for lecture ingestion when settingsType is COURSE', fakeAsync(() => {
component.irisSettings = mockSettings();
component.settingsType = IrisSettingsType.COURSE;
@@ -65,5 +61,6 @@ describe('IrisSettingsUpdateComponent', () => {
expect(lectureIngestionElement).not.toBeNull();
expect(checkboxElement).toBeTruthy();
expect(labelElement).toBeTruthy();
+ expect(getVariantsSpy).toHaveBeenCalled();
}));
});
diff --git a/src/test/javascript/spec/component/iris/settings/mock-settings.ts b/src/test/javascript/spec/component/iris/settings/mock-settings.ts
index f9338cd78cc4..6c542caf9a91 100644
--- a/src/test/javascript/spec/component/iris/settings/mock-settings.ts
+++ b/src/test/javascript/spec/component/iris/settings/mock-settings.ts
@@ -1,51 +1,33 @@
-import { IrisModel } from 'app/entities/iris/settings/iris-model';
-import { IrisTemplate } from 'app/entities/iris/settings/iris-template';
-import {
- IrisChatSubSettings,
- IrisCompetencyGenerationSubSettings,
- IrisHestiaSubSettings,
- IrisLectureIngestionSubSettings,
-} from 'app/entities/iris/settings/iris-sub-settings.model';
+import { IrisVariant } from 'app/entities/iris/settings/iris-variant';
+import { IrisChatSubSettings, IrisCompetencyGenerationSubSettings, IrisLectureIngestionSubSettings } from 'app/entities/iris/settings/iris-sub-settings.model';
import { IrisGlobalSettings } from 'app/entities/iris/settings/iris-settings.model';
export function mockSettings() {
- const mockTemplate = new IrisTemplate();
- mockTemplate.id = 1;
- mockTemplate.content = 'Hello World';
const mockChatSettings = new IrisChatSubSettings();
mockChatSettings.id = 1;
- mockChatSettings.template = mockTemplate;
mockChatSettings.enabled = true;
const mockLectureIngestionSettings = new IrisLectureIngestionSubSettings();
mockLectureIngestionSettings.id = 7;
mockLectureIngestionSettings.enabled = true;
mockLectureIngestionSettings.autoIngestOnLectureAttachmentUpload = true;
- const mockHestiaSettings = new IrisHestiaSubSettings();
- mockHestiaSettings.id = 2;
- mockHestiaSettings.template = mockTemplate;
- mockHestiaSettings.enabled = true;
const mockCompetencyGenerationSettings = new IrisCompetencyGenerationSubSettings();
mockCompetencyGenerationSettings.id = 5;
mockCompetencyGenerationSettings.enabled = false;
const irisSettings = new IrisGlobalSettings();
irisSettings.id = 1;
irisSettings.irisChatSettings = mockChatSettings;
- irisSettings.irisHestiaSettings = mockHestiaSettings;
irisSettings.irisCompetencyGenerationSettings = mockCompetencyGenerationSettings;
irisSettings.irisLectureIngestionSettings = mockLectureIngestionSettings;
return irisSettings;
}
export function mockEmptySettings() {
- const mockTemplate = new IrisTemplate();
- mockTemplate.id = 1;
- mockTemplate.content = 'Hello World';
const irisSettings = new IrisGlobalSettings();
irisSettings.id = 1;
return irisSettings;
}
-export function mockModels() {
+export function mockVariants() {
return [
{
id: '1',
@@ -57,5 +39,5 @@ export function mockModels() {
name: 'Model 2',
description: 'Model 2 Description',
},
- ] as IrisModel[];
+ ] as IrisVariant[];
}
From da03f27a4c9aef1be9b4c6c6edb92be36445c287 Mon Sep 17 00:00:00 2001
From: Stephan Krusche
Date: Sat, 12 Oct 2024 11:37:20 +0200
Subject: [PATCH 08/28] Development: Update client dependencies
---
jest.config.js | 8 +-
package-lock.json | 1216 +++++++++++++++++++++++++++++----------------
package.json | 48 +-
3 files changed, 803 insertions(+), 469 deletions(-)
diff --git a/jest.config.js b/jest.config.js
index 3dab49d4b7e0..48cac393d596 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -102,10 +102,10 @@ module.exports = {
coverageThreshold: {
global: {
// TODO: in the future, the following values should increase to at least 90%
- statements: 87.37,
- branches: 73.68,
- functions: 81.93,
- lines: 87.42,
+ statements: 87.43,
+ branches: 73.72,
+ functions: 82.05,
+ lines: 87.49,
},
},
coverageReporters: ['clover', 'json', 'lcov', 'text-summary'],
diff --git a/package-lock.json b/package-lock.json
index 4b7bc1437ba6..91ee03d72aaf 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,18 +10,18 @@
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
- "@angular/animations": "18.2.7",
- "@angular/cdk": "18.2.7",
- "@angular/common": "18.2.7",
- "@angular/compiler": "18.2.7",
- "@angular/core": "18.2.7",
- "@angular/forms": "18.2.7",
- "@angular/localize": "18.2.7",
- "@angular/material": "18.2.7",
- "@angular/platform-browser": "18.2.7",
- "@angular/platform-browser-dynamic": "18.2.7",
- "@angular/router": "18.2.7",
- "@angular/service-worker": "18.2.7",
+ "@angular/animations": "18.2.8",
+ "@angular/cdk": "18.2.8",
+ "@angular/common": "18.2.8",
+ "@angular/compiler": "18.2.8",
+ "@angular/core": "18.2.8",
+ "@angular/forms": "18.2.8",
+ "@angular/localize": "18.2.8",
+ "@angular/material": "18.2.8",
+ "@angular/platform-browser": "18.2.8",
+ "@angular/platform-browser-dynamic": "18.2.8",
+ "@angular/router": "18.2.8",
+ "@angular/service-worker": "18.2.8",
"@ctrl/ngx-emoji-mart": "9.2.0",
"@danielmoncada/angular-datetime-picker": "18.1.0",
"@fingerprintjs/fingerprintjs": "4.5.0",
@@ -33,7 +33,7 @@
"@ng-bootstrap/ng-bootstrap": "17.0.1",
"@ngx-translate/core": "15.0.0",
"@ngx-translate/http-loader": "8.0.0",
- "@sentry/angular": "8.33.1",
+ "@sentry/angular": "8.34.0",
"@siemens/ngx-datatable": "22.4.1",
"@swimlane/ngx-charts": "20.5.0",
"@swimlane/ngx-graph": "8.4.0",
@@ -59,8 +59,8 @@
"ngx-infinite-scroll": "18.0.0",
"ngx-webstorage": "18.0.0",
"papaparse": "5.4.1",
- "pdfjs-dist": "4.6.82",
- "posthog-js": "1.166.1",
+ "pdfjs-dist": "4.7.76",
+ "posthog-js": "1.167.0",
"rxjs": "7.8.1",
"showdown": "2.1.0",
"showdown-highlight": "3.1.0",
@@ -78,29 +78,29 @@
},
"devDependencies": {
"@angular-builders/jest": "18.0.0",
- "@angular-devkit/build-angular": "18.2.7",
+ "@angular-devkit/build-angular": "18.2.8",
"@angular-eslint/builder": "18.3.1",
"@angular-eslint/eslint-plugin": "18.3.1",
"@angular-eslint/eslint-plugin-template": "18.3.1",
"@angular-eslint/schematics": "18.3.1",
"@angular-eslint/template-parser": "18.3.1",
- "@angular/cli": "18.2.7",
- "@angular/compiler-cli": "18.2.7",
- "@angular/language-service": "18.2.7",
- "@sentry/types": "8.33.1",
+ "@angular/cli": "18.2.8",
+ "@angular/compiler-cli": "18.2.8",
+ "@angular/language-service": "18.2.8",
+ "@sentry/types": "8.34.0",
"@types/crypto-js": "4.2.2",
"@types/d3-shape": "3.1.6",
"@types/dompurify": "3.0.5",
"@types/jest": "29.5.13",
"@types/lodash-es": "4.17.12",
- "@types/node": "22.7.4",
+ "@types/node": "22.7.5",
"@types/papaparse": "5.3.14",
"@types/showdown": "2.0.6",
"@types/smoothscroll-polyfill": "0.3.4",
"@types/sockjs-client": "1.5.4",
"@types/uuid": "10.0.0",
- "@typescript-eslint/eslint-plugin": "8.8.0",
- "@typescript-eslint/parser": "8.8.0",
+ "@typescript-eslint/eslint-plugin": "8.8.1",
+ "@typescript-eslint/parser": "8.8.1",
"eslint": "9.12.0",
"eslint-config-prettier": "9.1.0",
"eslint-plugin-deprecation": "3.0.0",
@@ -121,7 +121,7 @@
"ngxtension": "4.0.0",
"prettier": "3.3.3",
"rimraf": "6.0.1",
- "sass": "1.79.4",
+ "sass": "1.79.5",
"ts-jest": "29.2.5",
"typescript": "5.5.4",
"weak-napi": "2.0.2"
@@ -212,13 +212,13 @@
}
},
"node_modules/@angular-devkit/architect": {
- "version": "0.1802.7",
- "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1802.7.tgz",
- "integrity": "sha512-kpcgXnepEXcoxDTbqbGj7Hg1WJLWj1HLR3/FKmC5TbpBf1xiLxiqfkQNwz3BbE/W9JWMLdrXr3GI9O3O2gWPLg==",
+ "version": "0.1802.8",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1802.8.tgz",
+ "integrity": "sha512-/rtFQEKgS7LlB9oHr4NCBSdKnvP5kr8L5Hbd3Vl8hZOYK9QWjxKPEXnryA2d5+PCE98bBzZswCNXqELZCPTgIQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@angular-devkit/core": "18.2.7",
+ "@angular-devkit/core": "18.2.8",
"rxjs": "7.8.1"
},
"engines": {
@@ -228,17 +228,17 @@
}
},
"node_modules/@angular-devkit/build-angular": {
- "version": "18.2.7",
- "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-18.2.7.tgz",
- "integrity": "sha512-u8PriYdgddK7k+OS/pOFPD1v4Iu5bztUJZXZVcGeXBZFFdnGFFzKmQw9mfcyGvTMJp2ABgBuuJT0YqYgNfAhzw==",
+ "version": "18.2.8",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-18.2.8.tgz",
+ "integrity": "sha512-qK/iLk7A8vQp1CyiJV4DpwfLjPKoiOlTtFqoO5vD8Tyxmc+R06FQp6GJTsZ7JtrTLYSiH+QAWiY6NgF/Rj/hHg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@ampproject/remapping": "2.3.0",
- "@angular-devkit/architect": "0.1802.7",
- "@angular-devkit/build-webpack": "0.1802.7",
- "@angular-devkit/core": "18.2.7",
- "@angular/build": "18.2.7",
+ "@angular-devkit/architect": "0.1802.8",
+ "@angular-devkit/build-webpack": "0.1802.8",
+ "@angular-devkit/core": "18.2.8",
+ "@angular/build": "18.2.8",
"@babel/core": "7.25.2",
"@babel/generator": "7.25.0",
"@babel/helper-annotate-as-pure": "7.24.7",
@@ -249,7 +249,7 @@
"@babel/preset-env": "7.25.3",
"@babel/runtime": "7.25.0",
"@discoveryjs/json-ext": "0.6.1",
- "@ngtools/webpack": "18.2.7",
+ "@ngtools/webpack": "18.2.8",
"@vitejs/plugin-basic-ssl": "1.1.0",
"ansi-colors": "4.1.3",
"autoprefixer": "10.4.20",
@@ -382,13 +382,13 @@
"license": "0BSD"
},
"node_modules/@angular-devkit/build-webpack": {
- "version": "0.1802.7",
- "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1802.7.tgz",
- "integrity": "sha512-VrtbrhZ+dht3f0GjtfRLRGRN4XHN/W+/bA9DqckdxVS6SydsrCWNHonvEPmOs4jJmGIGXIu6tUBMcWleTao2sg==",
+ "version": "0.1802.8",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1802.8.tgz",
+ "integrity": "sha512-uPpopkXkO66SSdjtVr7xCyQCPs/x6KUC76xkDc4j0b8EEHifTbi/fNpbkcZ6wBmoAfjKLWXfKvtkh0TqKK5Hkw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@angular-devkit/architect": "0.1802.7",
+ "@angular-devkit/architect": "0.1802.8",
"rxjs": "7.8.1"
},
"engines": {
@@ -402,9 +402,9 @@
}
},
"node_modules/@angular-devkit/core": {
- "version": "18.2.7",
- "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.7.tgz",
- "integrity": "sha512-1ZTi4A6tEC2bkJ/puCIdIPYhesnlCVOMSDJL/lZAd0hC6X22T4pwu0AEvue7mcP5NbXpQDiBaXOZ3MmCA8PwOA==",
+ "version": "18.2.8",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.8.tgz",
+ "integrity": "sha512-4o2T6wsmXGE/v53+F8L7kGoN2+qzt03C9rtjLVQpOljzpJVttQ8bhvfWxyYLWwcl04RWqRa+82fpIZtBkOlZJw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -430,13 +430,13 @@
}
},
"node_modules/@angular-devkit/schematics": {
- "version": "18.2.7",
- "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-18.2.7.tgz",
- "integrity": "sha512-j7198lpkOXMG+Gyfln/5aDgBZV7m4pWMzHFhkO3+w3cbCNUN1TVZW0SyJcF+CYaxANzTbuumfvpsYc/fTeAGLw==",
+ "version": "18.2.8",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-18.2.8.tgz",
+ "integrity": "sha512-i/h2Oji5FhJMC7wDSnIl5XUe/qym+C1ZwScaATJwDyRLCUIynZkj5rLgdG/uK6l+H0PgvxigkF+akWpokkwW6w==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@angular-devkit/core": "18.2.7",
+ "@angular-devkit/core": "18.2.8",
"jsonc-parser": "3.3.1",
"magic-string": "0.30.11",
"ora": "5.4.1",
@@ -549,9 +549,9 @@
}
},
"node_modules/@angular/animations": {
- "version": "18.2.7",
- "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-18.2.7.tgz",
- "integrity": "sha512-5B7qD1K+kKOf9lgJT4VNMft3IK2BnRHjN1S6l38ywzQ/nxpmCG7f+qKAAU6CpCywhNUBeXW0hVXTMuMNPVOcQQ==",
+ "version": "18.2.8",
+ "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-18.2.8.tgz",
+ "integrity": "sha512-dMSn2hg70siv3lhP+vqhMbgc923xw6XBUvnpCPEzhZqFHvPXfh/LubmsD5RtqHmjWebXtgVcgS+zg3Gq3jB2lg==",
"license": "MIT",
"dependencies": {
"tslib": "^2.3.0"
@@ -560,18 +560,18 @@
"node": "^18.19.1 || ^20.11.1 || >=22.0.0"
},
"peerDependencies": {
- "@angular/core": "18.2.7"
+ "@angular/core": "18.2.8"
}
},
"node_modules/@angular/build": {
- "version": "18.2.7",
- "resolved": "https://registry.npmjs.org/@angular/build/-/build-18.2.7.tgz",
- "integrity": "sha512-oq6JsVxLP9/w9F2IjKroJwPB9CdlMblu2Xhfq/qQZRSUuM8Ppt1svr2FBTo1HrLIbosqukkVcSSdmKYDneo+cg==",
+ "version": "18.2.8",
+ "resolved": "https://registry.npmjs.org/@angular/build/-/build-18.2.8.tgz",
+ "integrity": "sha512-ufuA4vHJSrL9SQW7bKV61DOoN1mm0t0ILTHaxSoCG3YF70cZJOX7+HNp3cK2uoldRMwbTOKSvCWBw54KKDRd5Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"@ampproject/remapping": "2.3.0",
- "@angular-devkit/architect": "0.1802.7",
+ "@angular-devkit/architect": "0.1802.8",
"@babel/core": "7.25.2",
"@babel/helper-annotate-as-pure": "7.24.7",
"@babel/helper-split-export-declaration": "7.24.7",
@@ -651,9 +651,9 @@
}
},
"node_modules/@angular/cdk": {
- "version": "18.2.7",
- "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-18.2.7.tgz",
- "integrity": "sha512-Dfl37WBLeEUURQrDeuMcOgX2bkQJ+BGMOlr1qsFXzUWHH+qgYW2YwO1rbna/rjxyeFzc2Sy569dYRzNPqMewzg==",
+ "version": "18.2.8",
+ "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-18.2.8.tgz",
+ "integrity": "sha512-J8A2FkwTBzLleAEWz6EgW73dEoeq87GREBPjTv8+2JV09LX+V3hnbgNk6zWq5k4OXtQNg9WrWP9QyRbUyA597g==",
"license": "MIT",
"dependencies": {
"tslib": "^2.3.0"
@@ -668,18 +668,18 @@
}
},
"node_modules/@angular/cli": {
- "version": "18.2.7",
- "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-18.2.7.tgz",
- "integrity": "sha512-KoWgSvhRsU05A2m6B7jw1kdpyoS+Ce5GGLW6xcnX7VF2AckW54vYd/8ZkgpzQrKfvIpVblYd4KJGizKoaLZ5jA==",
+ "version": "18.2.8",
+ "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-18.2.8.tgz",
+ "integrity": "sha512-GKXG7F7z5rxwZ8/bnW/Bp8/zsfE/BpHmIP/icLfUIOwv2kaY5OD2tfQssWXPEuqZzYq2AYz+wjVSbWjxGoja8A==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@angular-devkit/architect": "0.1802.7",
- "@angular-devkit/core": "18.2.7",
- "@angular-devkit/schematics": "18.2.7",
+ "@angular-devkit/architect": "0.1802.8",
+ "@angular-devkit/core": "18.2.8",
+ "@angular-devkit/schematics": "18.2.8",
"@inquirer/prompts": "5.3.8",
"@listr2/prompt-adapter-inquirer": "2.0.15",
- "@schematics/angular": "18.2.7",
+ "@schematics/angular": "18.2.8",
"@yarnpkg/lockfile": "1.1.0",
"ini": "4.1.3",
"jsonc-parser": "3.3.1",
@@ -702,9 +702,9 @@
}
},
"node_modules/@angular/common": {
- "version": "18.2.7",
- "resolved": "https://registry.npmjs.org/@angular/common/-/common-18.2.7.tgz",
- "integrity": "sha512-5vDBmBR2JcIxHVEDunKXNU+T+OvTGiHZTSo35GFOHJxKFgX5g6+0tJBZunK04oBZGbJQUmp3pg2kMvuKKjZnkQ==",
+ "version": "18.2.8",
+ "resolved": "https://registry.npmjs.org/@angular/common/-/common-18.2.8.tgz",
+ "integrity": "sha512-TYsKtE5nVaIScWSLGSO34Skc+s3hB/BujSddnfQHoNFvPT/WR0dfmdlpVCTeLj+f50htFoMhW11tW99PbK+whQ==",
"license": "MIT",
"dependencies": {
"tslib": "^2.3.0"
@@ -713,14 +713,14 @@
"node": "^18.19.1 || ^20.11.1 || >=22.0.0"
},
"peerDependencies": {
- "@angular/core": "18.2.7",
+ "@angular/core": "18.2.8",
"rxjs": "^6.5.3 || ^7.4.0"
}
},
"node_modules/@angular/compiler": {
- "version": "18.2.7",
- "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-18.2.7.tgz",
- "integrity": "sha512-XemlYyRGnu/HrICtXwTPmGtyOrI8BhbGg/HMiJ7sVx40AeEIX0uyDgnu9Gc5OjmtDqZZ8Qftg1sQAxaCVjLb1w==",
+ "version": "18.2.8",
+ "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-18.2.8.tgz",
+ "integrity": "sha512-JRedHNfK1CCPVyeGQB5w3WBYqMA6X8Q240CkvjlGfn0pVXihf9DWk3nkSQJVgYxpvpHfxdgjaYZ5IpMzlkmkhw==",
"license": "MIT",
"dependencies": {
"tslib": "^2.3.0"
@@ -729,7 +729,7 @@
"node": "^18.19.1 || ^20.11.1 || >=22.0.0"
},
"peerDependencies": {
- "@angular/core": "18.2.7"
+ "@angular/core": "18.2.8"
},
"peerDependenciesMeta": {
"@angular/core": {
@@ -738,14 +738,14 @@
}
},
"node_modules/@angular/compiler-cli": {
- "version": "18.2.7",
- "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-18.2.7.tgz",
- "integrity": "sha512-U7cveObj+rrXH5EC8egAhATCeAAcOceEQDTVIOWmBa0qMR4hOMjtI2XUS2QRuI1Q+fQZ2hVEOW95WVLvEMsANA==",
+ "version": "18.2.8",
+ "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-18.2.8.tgz",
+ "integrity": "sha512-OksDE4LWQUCcIvMjtZF7eiDCdIMrcMMpC1+Q0PIYi7KmnqXFGs4/Y0NdJvtn/LrQznzz5WaKM3ZDVNZTRX4wmw==",
"license": "MIT",
"dependencies": {
"@babel/core": "7.25.2",
"@jridgewell/sourcemap-codec": "^1.4.14",
- "chokidar": "^3.0.0",
+ "chokidar": "^4.0.0",
"convert-source-map": "^1.5.1",
"reflect-metadata": "^0.2.0",
"semver": "^7.0.0",
@@ -761,14 +761,42 @@
"node": "^18.19.1 || ^20.11.1 || >=22.0.0"
},
"peerDependencies": {
- "@angular/compiler": "18.2.7",
+ "@angular/compiler": "18.2.8",
"typescript": ">=5.4 <5.6"
}
},
+ "node_modules/@angular/compiler-cli/node_modules/chokidar": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz",
+ "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==",
+ "license": "MIT",
+ "dependencies": {
+ "readdirp": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 14.16.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/@angular/compiler-cli/node_modules/readdirp": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz",
+ "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14.16.0"
+ },
+ "funding": {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
"node_modules/@angular/core": {
- "version": "18.2.7",
- "resolved": "https://registry.npmjs.org/@angular/core/-/core-18.2.7.tgz",
- "integrity": "sha512-hLOxgxLiyWm9iVHBsUsJfx1hDsXWZnfJBlr+N7cev53f0CDoPfbshqq6KV+JFqXFDguzR9dKHm1ewT1jK3e6Tw==",
+ "version": "18.2.8",
+ "resolved": "https://registry.npmjs.org/@angular/core/-/core-18.2.8.tgz",
+ "integrity": "sha512-NwIuX/Iby1jT6Iv1/s6S3wOFf8xfuQR3MPGvKhGgNtjXLbHG+TXceK9+QPZC0s9/Z8JR/hz+li34B79GrIKgUg==",
"license": "MIT",
"dependencies": {
"tslib": "^2.3.0"
@@ -782,9 +810,9 @@
}
},
"node_modules/@angular/forms": {
- "version": "18.2.7",
- "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-18.2.7.tgz",
- "integrity": "sha512-WO3c9/OA7ekBnDBgmvi5TlHshOt5S4NREIP+/VVyuRgg28BwUWyO/Nqh19nguE1UNNRt6OMLkT6NSV2ewhcXUg==",
+ "version": "18.2.8",
+ "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-18.2.8.tgz",
+ "integrity": "sha512-JCLki7KC6D5vF6dE6yGlBmW33khIgpHs8N9SzuiJtkQqNDTIQA8cPsGV6qpLpxflxASynQOX5lDkWYdQyfm77Q==",
"license": "MIT",
"dependencies": {
"tslib": "^2.3.0"
@@ -793,16 +821,16 @@
"node": "^18.19.1 || ^20.11.1 || >=22.0.0"
},
"peerDependencies": {
- "@angular/common": "18.2.7",
- "@angular/core": "18.2.7",
- "@angular/platform-browser": "18.2.7",
+ "@angular/common": "18.2.8",
+ "@angular/core": "18.2.8",
+ "@angular/platform-browser": "18.2.8",
"rxjs": "^6.5.3 || ^7.4.0"
}
},
"node_modules/@angular/language-service": {
- "version": "18.2.7",
- "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-18.2.7.tgz",
- "integrity": "sha512-gFsme3y5uC/dQGBBX05VnmT2KAEAZ6gsNk8m1b226LYvh8Oc+JQ4sXv7THGq1x5VnrTzRcCIELbkNHCiFdvL1Q==",
+ "version": "18.2.8",
+ "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-18.2.8.tgz",
+ "integrity": "sha512-IueQ57CPP0Dt0z2n8B1A6JTwTq6m/AJVObZzrkSfXlzY1rY2qRuTJmAbZpTJ3iAxVzNYoaGh+NFHmJL8fRiXKQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -810,9 +838,9 @@
}
},
"node_modules/@angular/localize": {
- "version": "18.2.7",
- "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-18.2.7.tgz",
- "integrity": "sha512-qYozomhO+1BlvtoMEEgKhaKz8thoztqNZEYPq9RmfkTB5uW7Q8h6rr1Sc2YAzJ6+ZA0McwabdJSX1TDxWyZx0Q==",
+ "version": "18.2.8",
+ "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-18.2.8.tgz",
+ "integrity": "sha512-1T7aXEdgVyeYnHOfQUuIDO8Lsamg1ZLrJrA5zUv61asPJp6HCcMjXy9vDQ1XvHm5+CdDjKk/rczlN4lSMZ0QRw==",
"license": "MIT",
"dependencies": {
"@babel/core": "7.25.2",
@@ -829,21 +857,21 @@
"node": "^18.19.1 || ^20.11.1 || >=22.0.0"
},
"peerDependencies": {
- "@angular/compiler": "18.2.7",
- "@angular/compiler-cli": "18.2.7"
+ "@angular/compiler": "18.2.8",
+ "@angular/compiler-cli": "18.2.8"
}
},
"node_modules/@angular/material": {
- "version": "18.2.7",
- "resolved": "https://registry.npmjs.org/@angular/material/-/material-18.2.7.tgz",
- "integrity": "sha512-mgPj2TCIrsngmu3iNnoaPc6su7uPv+NPCv9HaiKhTx4QGae8EW+RvUxEZJvh4Qaym1fJTi3hjnVeWvQDLQt4CA==",
+ "version": "18.2.8",
+ "resolved": "https://registry.npmjs.org/@angular/material/-/material-18.2.8.tgz",
+ "integrity": "sha512-wQGMVsfQ9lQfih2VsWAvV4z3S3uBxrxc61owlE+K0T1BxH9u/jo3A/rnRitIdvR/L4NnYlfhCnmrW9K+Pl+WCg==",
"license": "MIT",
"dependencies": {
"tslib": "^2.3.0"
},
"peerDependencies": {
"@angular/animations": "^18.0.0 || ^19.0.0",
- "@angular/cdk": "18.2.7",
+ "@angular/cdk": "18.2.8",
"@angular/common": "^18.0.0 || ^19.0.0",
"@angular/core": "^18.0.0 || ^19.0.0",
"@angular/forms": "^18.0.0 || ^19.0.0",
@@ -852,9 +880,9 @@
}
},
"node_modules/@angular/platform-browser": {
- "version": "18.2.7",
- "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-18.2.7.tgz",
- "integrity": "sha512-xgj2DH/isFrMZ73dJJm89NRnWBI3AHtugQrZbIapkKBdEt/C1o4SR2W2cV4mPb9o+ELnWurfrxFt9o/q2vnVLw==",
+ "version": "18.2.8",
+ "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-18.2.8.tgz",
+ "integrity": "sha512-EPai4ZPqSq3ilLJUC85kPi9wo5j5suQovwtgRyjM/75D9Qy4TV19g8hkVM5Co/zrltO8a2G6vDscCNI5BeGw2A==",
"license": "MIT",
"dependencies": {
"tslib": "^2.3.0"
@@ -863,9 +891,9 @@
"node": "^18.19.1 || ^20.11.1 || >=22.0.0"
},
"peerDependencies": {
- "@angular/animations": "18.2.7",
- "@angular/common": "18.2.7",
- "@angular/core": "18.2.7"
+ "@angular/animations": "18.2.8",
+ "@angular/common": "18.2.8",
+ "@angular/core": "18.2.8"
},
"peerDependenciesMeta": {
"@angular/animations": {
@@ -874,9 +902,9 @@
}
},
"node_modules/@angular/platform-browser-dynamic": {
- "version": "18.2.7",
- "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-18.2.7.tgz",
- "integrity": "sha512-BDldzUKjnUjo0NW5gHjBY6CeJP1bWVfF1h/T3idyYG+F4Lxlb3aykRgLWXg4srNLY1KqE7XOYUmgc5cV613bgw==",
+ "version": "18.2.8",
+ "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-18.2.8.tgz",
+ "integrity": "sha512-poZoapDqyN/rxGKQ3C6esdPiPLMkSpP2v12hoEa12KHgfPk7T1e+a+NMyJjV8HeOY3WyvL7tGRhW0NPTajTkhw==",
"license": "MIT",
"dependencies": {
"tslib": "^2.3.0"
@@ -885,16 +913,16 @@
"node": "^18.19.1 || ^20.11.1 || >=22.0.0"
},
"peerDependencies": {
- "@angular/common": "18.2.7",
- "@angular/compiler": "18.2.7",
- "@angular/core": "18.2.7",
- "@angular/platform-browser": "18.2.7"
+ "@angular/common": "18.2.8",
+ "@angular/compiler": "18.2.8",
+ "@angular/core": "18.2.8",
+ "@angular/platform-browser": "18.2.8"
}
},
"node_modules/@angular/router": {
- "version": "18.2.7",
- "resolved": "https://registry.npmjs.org/@angular/router/-/router-18.2.7.tgz",
- "integrity": "sha512-TXE8Aw63hDp3PEaNu4B1DMNvlS0uCzs36o/OSCCmewmLnzyJygkgi4jeEj20FsWPAQOUj5g5tnCYgxz1IRrCUg==",
+ "version": "18.2.8",
+ "resolved": "https://registry.npmjs.org/@angular/router/-/router-18.2.8.tgz",
+ "integrity": "sha512-L+olYgxIiBq+tbfayVI0cv1yOuymsw33msnGC2l/vpc9sSVfqGzESFnB4yMVU3vHtE9v6v2Y6O+iV44/b79W/g==",
"license": "MIT",
"dependencies": {
"tslib": "^2.3.0"
@@ -903,16 +931,16 @@
"node": "^18.19.1 || ^20.11.1 || >=22.0.0"
},
"peerDependencies": {
- "@angular/common": "18.2.7",
- "@angular/core": "18.2.7",
- "@angular/platform-browser": "18.2.7",
+ "@angular/common": "18.2.8",
+ "@angular/core": "18.2.8",
+ "@angular/platform-browser": "18.2.8",
"rxjs": "^6.5.3 || ^7.4.0"
}
},
"node_modules/@angular/service-worker": {
- "version": "18.2.7",
- "resolved": "https://registry.npmjs.org/@angular/service-worker/-/service-worker-18.2.7.tgz",
- "integrity": "sha512-1t8PUWmZi32i/SG/r12vz+cfn0l3xVEa0FY7GXaZK7hlfDL34js1HZXHkvGUuRZRw/4L1jl7AwPoxwGeWr2ldg==",
+ "version": "18.2.8",
+ "resolved": "https://registry.npmjs.org/@angular/service-worker/-/service-worker-18.2.8.tgz",
+ "integrity": "sha512-LQktgS2Hn845ASWNyjde18V+CHkkPeCzORfh0ChYKiOmXYFtj/myEik5o/QI/G13Kaymy+vcuwQKiUuZjZiD1w==",
"license": "MIT",
"dependencies": {
"tslib": "^2.3.0"
@@ -924,8 +952,8 @@
"node": "^18.19.1 || ^20.11.1 || >=22.0.0"
},
"peerDependencies": {
- "@angular/common": "18.2.7",
- "@angular/core": "18.2.7"
+ "@angular/common": "18.2.8",
+ "@angular/core": "18.2.8"
}
},
"node_modules/@babel/code-frame": {
@@ -942,9 +970,9 @@
}
},
"node_modules/@babel/compat-data": {
- "version": "7.25.7",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.7.tgz",
- "integrity": "sha512-9ickoLz+hcXCeh7jrcin+/SLWm+GkxE2kTvoYyp38p4WkdFXfQJxDFGWp/YHjiKLPx06z2A7W8XKuqbReXDzsw==",
+ "version": "7.25.8",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.8.tgz",
+ "integrity": "sha512-ZsysZyXY4Tlx+Q53XdnOFmqwfB9QDTHYxaZYajWRoBLuLEAwI2UIbtxOjWh/cFaa9IKUlcB+DDuoskLuKu56JA==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -1353,12 +1381,12 @@
}
},
"node_modules/@babel/parser": {
- "version": "7.25.7",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.7.tgz",
- "integrity": "sha512-aZn7ETtQsjjGG5HruveUK06cU3Hljuhd9Iojm4M8WWv3wLE6OkE5PWbDUkItmMgegmccaITudyuW5RPYrYlgWw==",
+ "version": "7.25.8",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.8.tgz",
+ "integrity": "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ==",
"license": "MIT",
"dependencies": {
- "@babel/types": "^7.25.7"
+ "@babel/types": "^7.25.8"
},
"bin": {
"parser": "bin/babel-parser.js"
@@ -1864,15 +1892,14 @@
}
},
"node_modules/@babel/plugin-transform-class-static-block": {
- "version": "7.25.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.25.7.tgz",
- "integrity": "sha512-rvUUtoVlkDWtDWxGAiiQj0aNktTPn3eFynBcMC2IhsXweehwgdI9ODe+XjWw515kEmv22sSOTp/rxIRuTiB7zg==",
+ "version": "7.25.8",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.25.8.tgz",
+ "integrity": "sha512-e82gl3TCorath6YLf9xUwFehVvjvfqFhdOo4+0iVIVju+6XOi5XHkqB3P2AXnSwoeTX0HBoXq5gJFtvotJzFnQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-create-class-features-plugin": "^7.25.7",
- "@babel/helper-plugin-utils": "^7.25.7",
- "@babel/plugin-syntax-class-static-block": "^7.14.5"
+ "@babel/helper-plugin-utils": "^7.25.7"
},
"engines": {
"node": ">=6.9.0"
@@ -1999,14 +2026,13 @@
}
},
"node_modules/@babel/plugin-transform-dynamic-import": {
- "version": "7.25.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.7.tgz",
- "integrity": "sha512-UvcLuual4h7/GfylKm2IAA3aph9rwvAM2XBA0uPKU3lca+Maai4jBjjEVUS568ld6kJcgbouuumCBhMd/Yz17w==",
+ "version": "7.25.8",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.8.tgz",
+ "integrity": "sha512-gznWY+mr4ZQL/EWPcbBQUP3BXS5FwZp8RUOw06BaRn8tQLzN4XLIxXejpHN9Qo8x8jjBmAAKp6FoS51AgkSA/A==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.25.7",
- "@babel/plugin-syntax-dynamic-import": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.25.7"
},
"engines": {
"node": ">=6.9.0"
@@ -2033,14 +2059,13 @@
}
},
"node_modules/@babel/plugin-transform-export-namespace-from": {
- "version": "7.25.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.7.tgz",
- "integrity": "sha512-h3MDAP5l34NQkkNulsTNyjdaR+OiB0Im67VU//sFupouP8Q6m9Spy7l66DcaAQxtmCqGdanPByLsnwFttxKISQ==",
+ "version": "7.25.8",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.8.tgz",
+ "integrity": "sha512-sPtYrduWINTQTW7FtOy99VCTWp4H23UX7vYcut7S4CIMEXU+54zKX9uCoGkLsWXteyaMXzVHgzWbLfQ1w4GZgw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.25.7",
- "@babel/plugin-syntax-export-namespace-from": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.25.7"
},
"engines": {
"node": ">=6.9.0"
@@ -2085,14 +2110,13 @@
}
},
"node_modules/@babel/plugin-transform-json-strings": {
- "version": "7.25.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.7.tgz",
- "integrity": "sha512-Ot43PrL9TEAiCe8C/2erAjXMeVSnE/BLEx6eyrKLNFCCw5jvhTHKyHxdI1pA0kz5njZRYAnMO2KObGqOCRDYSA==",
+ "version": "7.25.8",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.8.tgz",
+ "integrity": "sha512-4OMNv7eHTmJ2YXs3tvxAfa/I43di+VcF+M4Wt66c88EAED1RoGaf1D64cL5FkRpNL+Vx9Hds84lksWvd/wMIdA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.25.7",
- "@babel/plugin-syntax-json-strings": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.25.7"
},
"engines": {
"node": ">=6.9.0"
@@ -2118,14 +2142,13 @@
}
},
"node_modules/@babel/plugin-transform-logical-assignment-operators": {
- "version": "7.25.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.7.tgz",
- "integrity": "sha512-iImzbA55BjiovLyG2bggWS+V+OLkaBorNvc/yJoeeDQGztknRnDdYfp2d/UPmunZYEnZi6Lg8QcTmNMHOB0lGA==",
+ "version": "7.25.8",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.8.tgz",
+ "integrity": "sha512-f5W0AhSbbI+yY6VakT04jmxdxz+WsID0neG7+kQZbCOjuyJNdL5Nn4WIBm4hRpKnUcO9lP0eipUhFN12JpoH8g==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.25.7",
- "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4"
+ "@babel/helper-plugin-utils": "^7.25.7"
},
"engines": {
"node": ">=6.9.0"
@@ -2255,14 +2278,13 @@
}
},
"node_modules/@babel/plugin-transform-nullish-coalescing-operator": {
- "version": "7.25.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.7.tgz",
- "integrity": "sha512-FbuJ63/4LEL32mIxrxwYaqjJxpbzxPVQj5a+Ebrc8JICV6YX8nE53jY+K0RZT3um56GoNWgkS2BQ/uLGTjtwfw==",
+ "version": "7.25.8",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.8.tgz",
+ "integrity": "sha512-Z7WJJWdQc8yCWgAmjI3hyC+5PXIubH9yRKzkl9ZEG647O9szl9zvmKLzpbItlijBnVhTUf1cpyWBsZ3+2wjWPQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.25.7",
- "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.25.7"
},
"engines": {
"node": ">=6.9.0"
@@ -2272,14 +2294,13 @@
}
},
"node_modules/@babel/plugin-transform-numeric-separator": {
- "version": "7.25.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.7.tgz",
- "integrity": "sha512-8CbutzSSh4hmD+jJHIA8vdTNk15kAzOnFLVVgBSMGr28rt85ouT01/rezMecks9pkU939wDInImwCKv4ahU4IA==",
+ "version": "7.25.8",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.8.tgz",
+ "integrity": "sha512-rm9a5iEFPS4iMIy+/A/PiS0QN0UyjPIeVvbU5EMZFKJZHt8vQnasbpo3T3EFcxzCeYO0BHfc4RqooCZc51J86Q==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.25.7",
- "@babel/plugin-syntax-numeric-separator": "^7.10.4"
+ "@babel/helper-plugin-utils": "^7.25.7"
},
"engines": {
"node": ">=6.9.0"
@@ -2289,15 +2310,14 @@
}
},
"node_modules/@babel/plugin-transform-object-rest-spread": {
- "version": "7.25.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.7.tgz",
- "integrity": "sha512-1JdVKPhD7Y5PvgfFy0Mv2brdrolzpzSoUq2pr6xsR+m+3viGGeHEokFKsCgOkbeFOQxfB1Vt2F0cPJLRpFI4Zg==",
+ "version": "7.25.8",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.8.tgz",
+ "integrity": "sha512-LkUu0O2hnUKHKE7/zYOIjByMa4VRaV2CD/cdGz0AxU9we+VA3kDDggKEzI0Oz1IroG+6gUP6UmWEHBMWZU316g==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-compilation-targets": "^7.25.7",
"@babel/helper-plugin-utils": "^7.25.7",
- "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
"@babel/plugin-transform-parameters": "^7.25.7"
},
"engines": {
@@ -2325,14 +2345,13 @@
}
},
"node_modules/@babel/plugin-transform-optional-catch-binding": {
- "version": "7.25.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.7.tgz",
- "integrity": "sha512-m9obYBA39mDPN7lJzD5WkGGb0GO54PPLXsbcnj1Hyeu8mSRz7Gb4b1A6zxNX32ZuUySDK4G6it8SDFWD1nCnqg==",
+ "version": "7.25.8",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.8.tgz",
+ "integrity": "sha512-EbQYweoMAHOn7iJ9GgZo14ghhb9tTjgOc88xFgYngifx7Z9u580cENCV159M4xDh3q/irbhSjZVpuhpC2gKBbg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.25.7",
- "@babel/plugin-syntax-optional-catch-binding": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.25.7"
},
"engines": {
"node": ">=6.9.0"
@@ -2342,15 +2361,14 @@
}
},
"node_modules/@babel/plugin-transform-optional-chaining": {
- "version": "7.25.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.7.tgz",
- "integrity": "sha512-h39agClImgPWg4H8mYVAbD1qP9vClFbEjqoJmt87Zen8pjqK8FTPUwrOXAvqu5soytwxrLMd2fx2KSCp2CHcNg==",
+ "version": "7.25.8",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.8.tgz",
+ "integrity": "sha512-q05Bk7gXOxpTHoQ8RSzGSh/LHVB9JEIkKnk3myAWwZHnYiTGYtbdrYkIsS8Xyh4ltKf7GNUSgzs/6P2bJtBAQg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.25.7",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.25.7",
- "@babel/plugin-syntax-optional-chaining": "^7.8.3"
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.25.7"
},
"engines": {
"node": ">=6.9.0"
@@ -2393,16 +2411,15 @@
}
},
"node_modules/@babel/plugin-transform-private-property-in-object": {
- "version": "7.25.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.7.tgz",
- "integrity": "sha512-LzA5ESzBy7tqj00Yjey9yWfs3FKy4EmJyKOSWld144OxkTji81WWnUT8nkLUn+imN/zHL8ZQlOu/MTUAhHaX3g==",
+ "version": "7.25.8",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.8.tgz",
+ "integrity": "sha512-8Uh966svuB4V8RHHg0QJOB32QK287NBksJOByoKmHMp1TAobNniNalIkI2i5IPj5+S9NYCG4VIjbEuiSN8r+ow==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-annotate-as-pure": "^7.25.7",
"@babel/helper-create-class-features-plugin": "^7.25.7",
- "@babel/helper-plugin-utils": "^7.25.7",
- "@babel/plugin-syntax-private-property-in-object": "^7.14.5"
+ "@babel/helper-plugin-utils": "^7.25.7"
},
"engines": {
"node": ">=6.9.0"
@@ -2827,9 +2844,9 @@
}
},
"node_modules/@babel/types": {
- "version": "7.25.7",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.7.tgz",
- "integrity": "sha512-vwIVdXG+j+FOpkwqHRcBgHLYNL7XMkufrlaFvL9o6Ai9sJn9+PdyIL5qa0XzTZw084c+u9LOls53eoZWP/W5WQ==",
+ "version": "7.25.8",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.8.tgz",
+ "integrity": "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==",
"license": "MIT",
"dependencies": {
"@babel/helper-string-parser": "^7.25.7",
@@ -2908,9 +2925,9 @@
}
},
"node_modules/@emnapi/core": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.2.0.tgz",
- "integrity": "sha512-E7Vgw78I93we4ZWdYCb4DGAwRROGkMIXk7/y87UmANR+J6qsWusmC3gLt0H+O0KOt5e6O38U8oJamgbudrES/w==",
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.3.1.tgz",
+ "integrity": "sha512-pVGjBIt1Y6gg3EJN8jTcfpP/+uuRksIo055oE/OBkDNcjZqVbfkWCksG1Jp4yZnj3iKWyWX8fdG/j6UDYPbFog==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2919,9 +2936,9 @@
}
},
"node_modules/@emnapi/runtime": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.2.0.tgz",
- "integrity": "sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==",
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.3.1.tgz",
+ "integrity": "sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3793,9 +3810,9 @@
}
},
"node_modules/@inquirer/figures": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.6.tgz",
- "integrity": "sha512-yfZzps3Cso2UbM7WlxKwZQh2Hs6plrbjs1QnzQDZhK2DgyCo6D8AaHps9olkNcUFlcYERMqU3uJSp1gmy3s/qQ==",
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.7.tgz",
+ "integrity": "sha512-m+Trk77mp54Zma6xLkLuY+mvanPxlE4A7yNKs2HBiyZ4UkVs28Mv5c/pgWrHeInx+USHeX/WEPzjrWrcJiQgjw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4990,9 +5007,9 @@
}
},
"node_modules/@jsonjoy.com/util": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.3.0.tgz",
- "integrity": "sha512-Cebt4Vk7k1xHy87kHY7KSPLT77A7Ev7IfOblyLZhtYEhrdQ6fX4EoLq3xOQ3O/DRMEh2ok5nyC180E+ABS8Wmw==",
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.5.0.tgz",
+ "integrity": "sha512-ojoNsrIuPI9g6o8UxhraZQSyF2ByJanAY4cTFbc8Mf2AXEF4aQRGY1dJxyJpuyav8r9FGflEt/Ff3u5Nt6YMPA==",
"dev": true,
"license": "Apache-2.0",
"engines": {
@@ -5359,9 +5376,9 @@
}
},
"node_modules/@ngtools/webpack": {
- "version": "18.2.7",
- "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-18.2.7.tgz",
- "integrity": "sha512-BmnFxss6zGobGyq9Mi7736golbK8RLgF+zYCQZ+4/OfMMA1jKVoELnyJqNyAx+DQn3m1qKVBjtGEL7pTNpPzOw==",
+ "version": "18.2.8",
+ "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-18.2.8.tgz",
+ "integrity": "sha512-sq0kI8gEen4QlM6X8XqOYy7j4B8iLCYNo+iKxatV36ts4AXH0MuVkP56+oMaoH5oZNoSqd0RlfnotEHfvJAr8A==",
"dev": true,
"license": "MIT",
"engines": {
@@ -5691,23 +5708,23 @@
}
},
"node_modules/@nrwl/devkit": {
- "version": "19.8.3",
- "resolved": "https://registry.npmjs.org/@nrwl/devkit/-/devkit-19.8.3.tgz",
- "integrity": "sha512-67vZJRMCEA543A0uz8dPTZ5lX4wsAlgsr24KJafsUxBC2WCf9z4BqcLj0jVWfmRdKJmu2UwaxtD2UB1bekt3sg==",
+ "version": "19.8.4",
+ "resolved": "https://registry.npmjs.org/@nrwl/devkit/-/devkit-19.8.4.tgz",
+ "integrity": "sha512-OoIqDjj2mWzLs3aSF6w5OiC2xywYi/jBxHc7t7Lyi56Vc4dQq8vJMELa9WtG6qH0k05fF7N+jAoKlfvLgbbEFA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@nx/devkit": "19.8.3"
+ "@nx/devkit": "19.8.4"
}
},
"node_modules/@nrwl/tao": {
- "version": "19.8.3",
- "resolved": "https://registry.npmjs.org/@nrwl/tao/-/tao-19.8.3.tgz",
- "integrity": "sha512-byjBtOXx+xGjMu1wKopJSJbrR3gKqTsCEgp1+YSZ45+iFKxFdXLJrGsyhVqBovCKVBM+5/KtGuEkZoUPlP8JWg==",
+ "version": "19.8.4",
+ "resolved": "https://registry.npmjs.org/@nrwl/tao/-/tao-19.8.4.tgz",
+ "integrity": "sha512-03/+QZ4/6HmKbEmvzCutLI1XIclBspNYtiVHmGPRWuwhnZViqYfnyl8J7RWVdFEoKKA5fhJqpg7e28aGuoMBvQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "nx": "19.8.3",
+ "nx": "19.8.4",
"tslib": "^2.3.0"
},
"bin": {
@@ -5715,13 +5732,13 @@
}
},
"node_modules/@nx/devkit": {
- "version": "19.8.3",
- "resolved": "https://registry.npmjs.org/@nx/devkit/-/devkit-19.8.3.tgz",
- "integrity": "sha512-uX50CAM11tzhwswf0ftN0QfzW2FM3M4Mf/pD/nRRnmsTkcPTdMXVu4LHuLVTp4CMsaO+cOQlqgHXujHYfOIctg==",
+ "version": "19.8.4",
+ "resolved": "https://registry.npmjs.org/@nx/devkit/-/devkit-19.8.4.tgz",
+ "integrity": "sha512-FPFT8gVDFRSEmU0n7nRkT4Rnqy7OMznfPXLfDZtVuzEi5Cl6ftG3UBUvCgJcJFCYJVAZAUuv6vRSRarHd51XFQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@nrwl/devkit": "19.8.3",
+ "@nrwl/devkit": "19.8.4",
"ejs": "^3.1.7",
"enquirer": "~2.3.6",
"ignore": "^5.0.4",
@@ -5762,9 +5779,9 @@
}
},
"node_modules/@nx/nx-darwin-arm64": {
- "version": "19.8.3",
- "resolved": "https://registry.npmjs.org/@nx/nx-darwin-arm64/-/nx-darwin-arm64-19.8.3.tgz",
- "integrity": "sha512-ORHFFWMZcvFi0xcpCaXccXVEhFwAevSHOIKfW359+12H9w7VW2O42B+2NcVMK1mrDTOjlXTd+0AmAu7P4NzWFA==",
+ "version": "19.8.4",
+ "resolved": "https://registry.npmjs.org/@nx/nx-darwin-arm64/-/nx-darwin-arm64-19.8.4.tgz",
+ "integrity": "sha512-mbSGt63hYcVCSQ54kpHl0lFqr5CsbkGJ4L3liWE30Da7vXZJwUBr9f+b9DnQ64IZzlu6vAhNcaiYQXa9lAk0yQ==",
"cpu": [
"arm64"
],
@@ -5779,9 +5796,9 @@
}
},
"node_modules/@nx/nx-darwin-x64": {
- "version": "19.8.3",
- "resolved": "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-19.8.3.tgz",
- "integrity": "sha512-Ji9DPA0tuzygMcypD/FHRDQSPipcRqMNmSaNKxVpcCbozVTWHvqXFk0rloDIUnxnE0+zvE9LN71H2sS4ZHdTQA==",
+ "version": "19.8.4",
+ "resolved": "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-19.8.4.tgz",
+ "integrity": "sha512-lTcXUCXNvqHdLmrNCOyDF+u6pDx209Ew7nSR47sQPvkycIHYi0gvgk0yndFn1Swah0lP4OxWg7rzAfmOlZd6ew==",
"cpu": [
"x64"
],
@@ -5796,9 +5813,9 @@
}
},
"node_modules/@nx/nx-freebsd-x64": {
- "version": "19.8.3",
- "resolved": "https://registry.npmjs.org/@nx/nx-freebsd-x64/-/nx-freebsd-x64-19.8.3.tgz",
- "integrity": "sha512-Ys+PqtBZCS+QBNs7he3fnxVhMWz/lSSaBVUlVHoQcV1Y4clEpP2TWNQSsbaVnnpcB7pdmKN5ymWdaCaAQuqCMw==",
+ "version": "19.8.4",
+ "resolved": "https://registry.npmjs.org/@nx/nx-freebsd-x64/-/nx-freebsd-x64-19.8.4.tgz",
+ "integrity": "sha512-4BUplOxPZeUwlUNfzHHMmebNVgDFW/jNX6TWRS+jINwOHnpWLkLFAXu27G80/S3OaniVCzEQklXO9b+1UsdgXw==",
"cpu": [
"x64"
],
@@ -5813,9 +5830,9 @@
}
},
"node_modules/@nx/nx-linux-arm-gnueabihf": {
- "version": "19.8.3",
- "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-19.8.3.tgz",
- "integrity": "sha512-hGOlML60ELXkgkqLHB/w/sXbTbXFhOQGSXC72CjaP5G0u1gj8eTQKJ7WEsqPAFMk5SLFFxqM7eid0LmAYYuZWQ==",
+ "version": "19.8.4",
+ "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-19.8.4.tgz",
+ "integrity": "sha512-Wahul8oz9huEm/Jv3wud5IGWdZxkGG4tdJm9i5TV5wxfUMAWbKU9v2nzZZins452UYESWvwvDkiuBPZqSto3qw==",
"cpu": [
"arm"
],
@@ -5830,9 +5847,9 @@
}
},
"node_modules/@nx/nx-linux-arm64-gnu": {
- "version": "19.8.3",
- "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-19.8.3.tgz",
- "integrity": "sha512-K/5iVbLbhsx28YtZHvveJgF41rbr2kMdabooZeFqy6VReN7U/zGJMjpV1FzDlf3TNr9jyjPDZgVQRS+qXau2qA==",
+ "version": "19.8.4",
+ "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-19.8.4.tgz",
+ "integrity": "sha512-L0RVCZkNAtZDplLT7uJV7M9cXxq2Fxw+8ex3eb9XSp7eyLeFO21T0R6vTouJ42E/PEvGApCAcyGqtnyPNMZFfw==",
"cpu": [
"arm64"
],
@@ -5847,9 +5864,9 @@
}
},
"node_modules/@nx/nx-linux-arm64-musl": {
- "version": "19.8.3",
- "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-19.8.3.tgz",
- "integrity": "sha512-zqzWjFniZDXiI/3MYxbJ0yIenUKr56apLy70oABTBHx++dsUA3/DxLMNypMA82a8KQtsbePWUi3Pgtr+JIMNXw==",
+ "version": "19.8.4",
+ "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-19.8.4.tgz",
+ "integrity": "sha512-0q8r8I8WCsY3xowDI2j109SCUSkFns/BJ40aCfRh9hhrtaIIc5qXUw2YFTjxUZNcRJXx9j9+hTe9jBkUSIGvCw==",
"cpu": [
"arm64"
],
@@ -5864,9 +5881,9 @@
}
},
"node_modules/@nx/nx-linux-x64-gnu": {
- "version": "19.8.3",
- "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-19.8.3.tgz",
- "integrity": "sha512-W1RRCqsQvpur4BxP5g5cQwjZB6jhxYLSSXi3QQDaU5ITkaV5Pdj/L7D/G6YgRB8lzKZrXc57aLJ5UKY/Z+di7w==",
+ "version": "19.8.4",
+ "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-19.8.4.tgz",
+ "integrity": "sha512-XcRBNe0ws7KB0PMcUlpQqzzjjxMP8VdqirBz7CfB2XQ8xKmP3370p0cDvqs/4oKDHK4PCkmvVFX60tzakutylA==",
"cpu": [
"x64"
],
@@ -5881,9 +5898,9 @@
}
},
"node_modules/@nx/nx-linux-x64-musl": {
- "version": "19.8.3",
- "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-19.8.3.tgz",
- "integrity": "sha512-waTo0zBBGnmU7fS87IpOnVGx7EHa0umzSMlGG0LUoU6swOeNODezsBn1Vbvaw1o7sStWBzdEBlxLxHOQXRAidg==",
+ "version": "19.8.4",
+ "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-19.8.4.tgz",
+ "integrity": "sha512-JB4tAuZBCF0yqSnKF3pHXa0b7LA3ebi3Bw08QmMr//ON4aU+eXURGBuj9XvULD2prY+gpBrvf+MsG1XJAHL6Zg==",
"cpu": [
"x64"
],
@@ -5898,9 +5915,9 @@
}
},
"node_modules/@nx/nx-win32-arm64-msvc": {
- "version": "19.8.3",
- "resolved": "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-19.8.3.tgz",
- "integrity": "sha512-lio7ulblEMs1otMtVIrdfdMTBqKRZEHim57AcMHSVnwmtl2ENP6TR3YIgyigjfLlkPanNU7i0QQ4h6Nk2I/FRw==",
+ "version": "19.8.4",
+ "resolved": "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-19.8.4.tgz",
+ "integrity": "sha512-WvQag/pN9ofRWRDvOZxj3jvJoTetlvV1uyirnDrhupRgi+Fj67OlGGt2zVUHaXFGEa1MfCEG6Vhk6152m4KyaQ==",
"cpu": [
"arm64"
],
@@ -5915,9 +5932,9 @@
}
},
"node_modules/@nx/nx-win32-x64-msvc": {
- "version": "19.8.3",
- "resolved": "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-19.8.3.tgz",
- "integrity": "sha512-RU11iXJzdrw5CmogT2AwsjxK7g8vWf6Oy23NlrvsQFODtavjqAWoD5qpUY/H16s9lVDwrpzCbGbAXph0lbgLKA==",
+ "version": "19.8.4",
+ "resolved": "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-19.8.4.tgz",
+ "integrity": "sha512-//JntLrN3L7WL/WgP3D0FE34caYTPcG/GIMBguC9w7YDyTlEikLgLbobjdCPz+2f9OWGvIZbJgGmtHNjnETM/g==",
"cpu": [
"x64"
],
@@ -5931,6 +5948,312 @@
"node": ">= 10"
}
},
+ "node_modules/@parcel/watcher": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.4.1.tgz",
+ "integrity": "sha512-HNjmfLQEVRZmHRET336f20H/8kOozUGwk7yajvsonjNxbj2wBTK1WsQuHkD5yYh9RxFGL2EyDHryOihOwUoKDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "detect-libc": "^1.0.3",
+ "is-glob": "^4.0.3",
+ "micromatch": "^4.0.5",
+ "node-addon-api": "^7.0.0"
+ },
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "optionalDependencies": {
+ "@parcel/watcher-android-arm64": "2.4.1",
+ "@parcel/watcher-darwin-arm64": "2.4.1",
+ "@parcel/watcher-darwin-x64": "2.4.1",
+ "@parcel/watcher-freebsd-x64": "2.4.1",
+ "@parcel/watcher-linux-arm-glibc": "2.4.1",
+ "@parcel/watcher-linux-arm64-glibc": "2.4.1",
+ "@parcel/watcher-linux-arm64-musl": "2.4.1",
+ "@parcel/watcher-linux-x64-glibc": "2.4.1",
+ "@parcel/watcher-linux-x64-musl": "2.4.1",
+ "@parcel/watcher-win32-arm64": "2.4.1",
+ "@parcel/watcher-win32-ia32": "2.4.1",
+ "@parcel/watcher-win32-x64": "2.4.1"
+ }
+ },
+ "node_modules/@parcel/watcher-android-arm64": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.4.1.tgz",
+ "integrity": "sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-darwin-arm64": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.4.1.tgz",
+ "integrity": "sha512-ln41eihm5YXIY043vBrrHfn94SIBlqOWmoROhsMVTSXGh0QahKGy77tfEywQ7v3NywyxBBkGIfrWRHm0hsKtzA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-darwin-x64": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.4.1.tgz",
+ "integrity": "sha512-yrw81BRLjjtHyDu7J61oPuSoeYWR3lDElcPGJyOvIXmor6DEo7/G2u1o7I38cwlcoBHQFULqF6nesIX3tsEXMg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-freebsd-x64": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.4.1.tgz",
+ "integrity": "sha512-TJa3Pex/gX3CWIx/Co8k+ykNdDCLx+TuZj3f3h7eOjgpdKM+Mnix37RYsYU4LHhiYJz3DK5nFCCra81p6g050w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm-glibc": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.4.1.tgz",
+ "integrity": "sha512-4rVYDlsMEYfa537BRXxJ5UF4ddNwnr2/1O4MHM5PjI9cvV2qymvhwZSFgXqbS8YoTk5i/JR0L0JDs69BUn45YA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm64-glibc": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.4.1.tgz",
+ "integrity": "sha512-BJ7mH985OADVLpbrzCLgrJ3TOpiZggE9FMblfO65PlOCdG++xJpKUJ0Aol74ZUIYfb8WsRlUdgrZxKkz3zXWYA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm64-musl": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.4.1.tgz",
+ "integrity": "sha512-p4Xb7JGq3MLgAfYhslU2SjoV9G0kI0Xry0kuxeG/41UfpjHGOhv7UoUDAz/jb1u2elbhazy4rRBL8PegPJFBhA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-x64-glibc": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.4.1.tgz",
+ "integrity": "sha512-s9O3fByZ/2pyYDPoLM6zt92yu6P4E39a03zvO0qCHOTjxmt3GHRMLuRZEWhWLASTMSrrnVNWdVI/+pUElJBBBg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-x64-musl": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.4.1.tgz",
+ "integrity": "sha512-L2nZTYR1myLNST0O632g0Dx9LyMNHrn6TOt76sYxWLdff3cB22/GZX2UPtJnaqQPdCRoszoY5rcOj4oMTtp5fQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-win32-arm64": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.4.1.tgz",
+ "integrity": "sha512-Uq2BPp5GWhrq/lcuItCHoqxjULU1QYEcyjSO5jqqOK8RNFDBQnenMMx4gAl3v8GiWa59E9+uDM7yZ6LxwUIfRg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-win32-ia32": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.4.1.tgz",
+ "integrity": "sha512-maNRit5QQV2kgHFSYwftmPBxiuK5u4DXjbXx7q6eKjq5dsLXZ4FJiVvlcw35QXzk0KrUecJmuVFbj4uV9oYrcw==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-win32-x64": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.4.1.tgz",
+ "integrity": "sha512-+DvS92F9ezicfswqrvIRM2njcYJbd5mb9CUgtrHCHmvn7pPPa+nMDRu1o1bYYz/l5IB2NVGNJWiH7h1E58IF2A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher/node_modules/detect-libc": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
+ "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "detect-libc": "bin/detect-libc.js"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/@parcel/watcher/node_modules/node-addon-api": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
+ "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@pkgjs/parseargs": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
@@ -6247,14 +6570,14 @@
]
},
"node_modules/@schematics/angular": {
- "version": "18.2.7",
- "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-18.2.7.tgz",
- "integrity": "sha512-WOBzO11qstznHbC9tZXQf6/8+PqmaRI6QYcdTspqXNh9q9nNglvi43Xn4tSIpEhW8aSHea9hgWZV8sG+i/4W9Q==",
+ "version": "18.2.8",
+ "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-18.2.8.tgz",
+ "integrity": "sha512-62Sr7/j/dlhZorxH4GzQgpJy0s162BVts0Q7knZuEacP4VL+IWOUE1NS9OFkh/cbomoyXBdoewkZ5Zd1dVX78w==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@angular-devkit/core": "18.2.7",
- "@angular-devkit/schematics": "18.2.7",
+ "@angular-devkit/core": "18.2.8",
+ "@angular-devkit/schematics": "18.2.8",
"jsonc-parser": "3.3.1"
},
"engines": {
@@ -6264,73 +6587,73 @@
}
},
"node_modules/@sentry-internal/browser-utils": {
- "version": "8.33.1",
- "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-8.33.1.tgz",
- "integrity": "sha512-TW6/r+Gl5jiXv54iK1xZ3mlVgTS/jaBp4vcQ0xGMdgiQ3WchEPcFSeYovL+YHT3tSud0GZqVtDQCz+5i76puqA==",
+ "version": "8.34.0",
+ "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-8.34.0.tgz",
+ "integrity": "sha512-4AcYOzPzD1tL5eSRQ/GpKv5enquZf4dMVUez99/Bh3va8qiJrNP55AcM7UzZ7WZLTqKygIYruJTU5Zu2SpEAPQ==",
"license": "MIT",
"dependencies": {
- "@sentry/core": "8.33.1",
- "@sentry/types": "8.33.1",
- "@sentry/utils": "8.33.1"
+ "@sentry/core": "8.34.0",
+ "@sentry/types": "8.34.0",
+ "@sentry/utils": "8.34.0"
},
"engines": {
"node": ">=14.18"
}
},
"node_modules/@sentry-internal/feedback": {
- "version": "8.33.1",
- "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-8.33.1.tgz",
- "integrity": "sha512-qauMRTm3qDaLqZ3ibI03cj4gLF40y0ij65nj+cns6iWxGCtPrO8tjvXFWuQsE7Aye9dGMnBgmv7uN+NTUtC3RA==",
+ "version": "8.34.0",
+ "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-8.34.0.tgz",
+ "integrity": "sha512-aYSM2KPUs0FLPxxbJCFSwCYG70VMzlT04xepD1Y/tTlPPOja/02tSv2tyOdZbv8Uw7xslZs3/8Lhj74oYcTBxw==",
"license": "MIT",
"dependencies": {
- "@sentry/core": "8.33.1",
- "@sentry/types": "8.33.1",
- "@sentry/utils": "8.33.1"
+ "@sentry/core": "8.34.0",
+ "@sentry/types": "8.34.0",
+ "@sentry/utils": "8.34.0"
},
"engines": {
"node": ">=14.18"
}
},
"node_modules/@sentry-internal/replay": {
- "version": "8.33.1",
- "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-8.33.1.tgz",
- "integrity": "sha512-fm4coIOjmanU29NOVN9MyaP4fUCOYytbtFqVSKRFNZQ/xAgNeySiBIbUd6IjujMmnOk9bY0WEUMcdm3Uotjdog==",
+ "version": "8.34.0",
+ "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-8.34.0.tgz",
+ "integrity": "sha512-EoMh9NYljNewZK1quY23YILgtNdGgrkzJ9TPsj6jXUG0LZ0Q7N7eFWd0xOEDBvFxrmI3cSXF1i4d1sBb+eyKRw==",
"license": "MIT",
"dependencies": {
- "@sentry-internal/browser-utils": "8.33.1",
- "@sentry/core": "8.33.1",
- "@sentry/types": "8.33.1",
- "@sentry/utils": "8.33.1"
+ "@sentry-internal/browser-utils": "8.34.0",
+ "@sentry/core": "8.34.0",
+ "@sentry/types": "8.34.0",
+ "@sentry/utils": "8.34.0"
},
"engines": {
"node": ">=14.18"
}
},
"node_modules/@sentry-internal/replay-canvas": {
- "version": "8.33.1",
- "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-8.33.1.tgz",
- "integrity": "sha512-nsxTFTPCT10Ty/v6+AiST3+yotGP1sUb8xqfKB9fPnS1hZHFryp0NnEls7xFjBsBbZPU1GpFkzrk/E6JFzixDQ==",
+ "version": "8.34.0",
+ "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-8.34.0.tgz",
+ "integrity": "sha512-x8KhZcCDpbKHqFOykYXiamX6x0LRxv6N1OJHoH+XCrMtiDBZr4Yo30d/MaS6rjmKGMtSRij30v+Uq+YWIgxUrg==",
"license": "MIT",
"dependencies": {
- "@sentry-internal/replay": "8.33.1",
- "@sentry/core": "8.33.1",
- "@sentry/types": "8.33.1",
- "@sentry/utils": "8.33.1"
+ "@sentry-internal/replay": "8.34.0",
+ "@sentry/core": "8.34.0",
+ "@sentry/types": "8.34.0",
+ "@sentry/utils": "8.34.0"
},
"engines": {
"node": ">=14.18"
}
},
"node_modules/@sentry/angular": {
- "version": "8.33.1",
- "resolved": "https://registry.npmjs.org/@sentry/angular/-/angular-8.33.1.tgz",
- "integrity": "sha512-jt4oViLMl/eqOALQmD0dPzXsy75Xp8amfRExgXoPdyDg6sLDNdEzpzrX2p7nGl7vsW/0Vm8NZ2TkbEBCll5wfQ==",
+ "version": "8.34.0",
+ "resolved": "https://registry.npmjs.org/@sentry/angular/-/angular-8.34.0.tgz",
+ "integrity": "sha512-FjBN5s+SFzTFHQh5DqWUGUp19p3V7p86I7Dq1a7MBCzmQukGM1bcW8+n6wLj6CxlEoyLCPPZpTIXIO4ulheIwg==",
"license": "MIT",
"dependencies": {
- "@sentry/browser": "8.33.1",
- "@sentry/core": "8.33.1",
- "@sentry/types": "8.33.1",
- "@sentry/utils": "8.33.1",
+ "@sentry/browser": "8.34.0",
+ "@sentry/core": "8.34.0",
+ "@sentry/types": "8.34.0",
+ "@sentry/utils": "8.34.0",
"tslib": "^2.4.1"
},
"engines": {
@@ -6344,52 +6667,52 @@
}
},
"node_modules/@sentry/browser": {
- "version": "8.33.1",
- "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-8.33.1.tgz",
- "integrity": "sha512-c6zI/igexkLwZuGk+u8Rj26ChjxGgkhe6ZbKFsXCYaKAp5ep5X7HQRkkqgbxApiqlC0LduHdd/ymzh139JLg8w==",
+ "version": "8.34.0",
+ "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-8.34.0.tgz",
+ "integrity": "sha512-3HHG2NXxzHq1lVmDy2uRjYjGNf9NsJsTPlOC70vbQdOb+S49EdH/XMPy+J3ruIoyv6Cu0LwvA6bMOM6rHZOgNQ==",
"license": "MIT",
"dependencies": {
- "@sentry-internal/browser-utils": "8.33.1",
- "@sentry-internal/feedback": "8.33.1",
- "@sentry-internal/replay": "8.33.1",
- "@sentry-internal/replay-canvas": "8.33.1",
- "@sentry/core": "8.33.1",
- "@sentry/types": "8.33.1",
- "@sentry/utils": "8.33.1"
+ "@sentry-internal/browser-utils": "8.34.0",
+ "@sentry-internal/feedback": "8.34.0",
+ "@sentry-internal/replay": "8.34.0",
+ "@sentry-internal/replay-canvas": "8.34.0",
+ "@sentry/core": "8.34.0",
+ "@sentry/types": "8.34.0",
+ "@sentry/utils": "8.34.0"
},
"engines": {
"node": ">=14.18"
}
},
"node_modules/@sentry/core": {
- "version": "8.33.1",
- "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.33.1.tgz",
- "integrity": "sha512-3SS41suXLFzxL3OQvTMZ6q92ZapELVq2l2SoWlZopcamWhog2Ru0dp2vkunq97kFHb2TzKRTlFH4+4gbT8SJug==",
+ "version": "8.34.0",
+ "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.34.0.tgz",
+ "integrity": "sha512-adrXCTK/zsg5pJ67lgtZqdqHvyx6etMjQW3P82NgWdj83c8fb+zH+K79Z47pD4zQjX0ou2Ws5nwwi4wJbz4bfA==",
"license": "MIT",
"dependencies": {
- "@sentry/types": "8.33.1",
- "@sentry/utils": "8.33.1"
+ "@sentry/types": "8.34.0",
+ "@sentry/utils": "8.34.0"
},
"engines": {
"node": ">=14.18"
}
},
"node_modules/@sentry/types": {
- "version": "8.33.1",
- "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.33.1.tgz",
- "integrity": "sha512-GjoAMvwtpIemoF/IiwZ7A60g4nQv3qwzR21GvJqDVUoKD0e8pv9OLX+HyXoUat4wEDGSuDUcUyUKD2G+od73QA==",
+ "version": "8.34.0",
+ "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.34.0.tgz",
+ "integrity": "sha512-zLRc60CzohGCo6zNsNeQ9JF3SiEeRE4aDCP9fDDdIVCOKovS+mn1rtSip0qd0Vp2fidOu0+2yY0ALCz1A3PJSQ==",
"license": "MIT",
"engines": {
"node": ">=14.18"
}
},
"node_modules/@sentry/utils": {
- "version": "8.33.1",
- "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.33.1.tgz",
- "integrity": "sha512-uzuYpiiJuFY3N4WNHMBWUQX5oNv2t/TbG0OHRp3Rr7yeu+HSfD542TIp9/gMZ+G0Cxd8AmVO3wkKIFbk0TL4Qg==",
+ "version": "8.34.0",
+ "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.34.0.tgz",
+ "integrity": "sha512-W1KoRlFUjprlh3t86DZPFxLfM6mzjRzshVfMY7vRlJFymBelJsnJ3A1lPeBZM9nCraOSiw6GtOWu6k5BAkiGIg==",
"license": "MIT",
"dependencies": {
- "@sentry/types": "8.33.1"
+ "@sentry/types": "8.34.0"
},
"engines": {
"node": ">=14.18"
@@ -7037,9 +7360,9 @@
}
},
"node_modules/@types/node": {
- "version": "22.7.4",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.4.tgz",
- "integrity": "sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg==",
+ "version": "22.7.5",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz",
+ "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7243,17 +7566,17 @@
"license": "MIT"
},
"node_modules/@typescript-eslint/eslint-plugin": {
- "version": "8.8.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.8.0.tgz",
- "integrity": "sha512-wORFWjU30B2WJ/aXBfOm1LX9v9nyt9D3jsSOxC3cCaTQGCW5k4jNpmjFv3U7p/7s4yvdjHzwtv2Sd2dOyhjS0A==",
+ "version": "8.8.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.8.1.tgz",
+ "integrity": "sha512-xfvdgA8AP/vxHgtgU310+WBnLB4uJQ9XdyP17RebG26rLtDrQJV3ZYrcopX91GrHmMoH8bdSwMRh2a//TiJ1jQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/regexpp": "^4.10.0",
- "@typescript-eslint/scope-manager": "8.8.0",
- "@typescript-eslint/type-utils": "8.8.0",
- "@typescript-eslint/utils": "8.8.0",
- "@typescript-eslint/visitor-keys": "8.8.0",
+ "@typescript-eslint/scope-manager": "8.8.1",
+ "@typescript-eslint/type-utils": "8.8.1",
+ "@typescript-eslint/utils": "8.8.1",
+ "@typescript-eslint/visitor-keys": "8.8.1",
"graphemer": "^1.4.0",
"ignore": "^5.3.1",
"natural-compare": "^1.4.0",
@@ -7277,16 +7600,16 @@
}
},
"node_modules/@typescript-eslint/parser": {
- "version": "8.8.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.8.0.tgz",
- "integrity": "sha512-uEFUsgR+tl8GmzmLjRqz+VrDv4eoaMqMXW7ruXfgThaAShO9JTciKpEsB+TvnfFfbg5IpujgMXVV36gOJRLtZg==",
+ "version": "8.8.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.8.1.tgz",
+ "integrity": "sha512-hQUVn2Lij2NAxVFEdvIGxT9gP1tq2yM83m+by3whWFsWC+1y8pxxxHUFE1UqDu2VsGi2i6RLcv4QvouM84U+ow==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
- "@typescript-eslint/scope-manager": "8.8.0",
- "@typescript-eslint/types": "8.8.0",
- "@typescript-eslint/typescript-estree": "8.8.0",
- "@typescript-eslint/visitor-keys": "8.8.0",
+ "@typescript-eslint/scope-manager": "8.8.1",
+ "@typescript-eslint/types": "8.8.1",
+ "@typescript-eslint/typescript-estree": "8.8.1",
+ "@typescript-eslint/visitor-keys": "8.8.1",
"debug": "^4.3.4"
},
"engines": {
@@ -7306,14 +7629,14 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
- "version": "8.8.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.8.0.tgz",
- "integrity": "sha512-EL8eaGC6gx3jDd8GwEFEV091210U97J0jeEHrAYvIYosmEGet4wJ+g0SYmLu+oRiAwbSA5AVrt6DxLHfdd+bUg==",
+ "version": "8.8.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.8.1.tgz",
+ "integrity": "sha512-X4JdU+66Mazev/J0gfXlcC/dV6JI37h+93W9BRYXrSn0hrE64IoWgVkO9MSJgEzoWkxONgaQpICWg8vAN74wlA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "8.8.0",
- "@typescript-eslint/visitor-keys": "8.8.0"
+ "@typescript-eslint/types": "8.8.1",
+ "@typescript-eslint/visitor-keys": "8.8.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -7324,14 +7647,14 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
- "version": "8.8.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.8.0.tgz",
- "integrity": "sha512-IKwJSS7bCqyCeG4NVGxnOP6lLT9Okc3Zj8hLO96bpMkJab+10HIfJbMouLrlpyOr3yrQ1cA413YPFiGd1mW9/Q==",
+ "version": "8.8.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.8.1.tgz",
+ "integrity": "sha512-qSVnpcbLP8CALORf0za+vjLYj1Wp8HSoiI8zYU5tHxRVj30702Z1Yw4cLwfNKhTPWp5+P+k1pjmD5Zd1nhxiZA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/typescript-estree": "8.8.0",
- "@typescript-eslint/utils": "8.8.0",
+ "@typescript-eslint/typescript-estree": "8.8.1",
+ "@typescript-eslint/utils": "8.8.1",
"debug": "^4.3.4",
"ts-api-utils": "^1.3.0"
},
@@ -7349,9 +7672,9 @@
}
},
"node_modules/@typescript-eslint/types": {
- "version": "8.8.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.8.0.tgz",
- "integrity": "sha512-QJwc50hRCgBd/k12sTykOJbESe1RrzmX6COk8Y525C9l7oweZ+1lw9JiU56im7Amm8swlz00DRIlxMYLizr2Vw==",
+ "version": "8.8.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.8.1.tgz",
+ "integrity": "sha512-WCcTP4SDXzMd23N27u66zTKMuEevH4uzU8C9jf0RO4E04yVHgQgW+r+TeVTNnO1KIfrL8ebgVVYYMMO3+jC55Q==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7363,14 +7686,14 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
- "version": "8.8.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.8.0.tgz",
- "integrity": "sha512-ZaMJwc/0ckLz5DaAZ+pNLmHv8AMVGtfWxZe/x2JVEkD5LnmhWiQMMcYT7IY7gkdJuzJ9P14fRy28lUrlDSWYdw==",
+ "version": "8.8.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.8.1.tgz",
+ "integrity": "sha512-A5d1R9p+X+1js4JogdNilDuuq+EHZdsH9MjTVxXOdVFfTJXunKJR/v+fNNyO4TnoOn5HqobzfRlc70NC6HTcdg==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
- "@typescript-eslint/types": "8.8.0",
- "@typescript-eslint/visitor-keys": "8.8.0",
+ "@typescript-eslint/types": "8.8.1",
+ "@typescript-eslint/visitor-keys": "8.8.1",
"debug": "^4.3.4",
"fast-glob": "^3.3.2",
"is-glob": "^4.0.3",
@@ -7392,16 +7715,16 @@
}
},
"node_modules/@typescript-eslint/utils": {
- "version": "8.8.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.8.0.tgz",
- "integrity": "sha512-QE2MgfOTem00qrlPgyByaCHay9yb1+9BjnMFnSFkUKQfu7adBXDTnCAivURnuPPAG/qiB+kzKkZKmKfaMT0zVg==",
+ "version": "8.8.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.8.1.tgz",
+ "integrity": "sha512-/QkNJDbV0bdL7H7d0/y0qBbV2HTtf0TIyjSDTvvmQEzeVx8jEImEbLuOA4EsvE8gIgqMitns0ifb5uQhMj8d9w==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
- "@typescript-eslint/scope-manager": "8.8.0",
- "@typescript-eslint/types": "8.8.0",
- "@typescript-eslint/typescript-estree": "8.8.0"
+ "@typescript-eslint/scope-manager": "8.8.1",
+ "@typescript-eslint/types": "8.8.1",
+ "@typescript-eslint/typescript-estree": "8.8.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -7415,13 +7738,13 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
- "version": "8.8.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.8.0.tgz",
- "integrity": "sha512-8mq51Lx6Hpmd7HnA2fcHQo3YgfX1qbccxQOgZcb4tvasu//zXRaA1j5ZRFeCw/VRAdFi4mRM9DnZw0Nu0Q2d1g==",
+ "version": "8.8.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.8.1.tgz",
+ "integrity": "sha512-0/TdC3aeRAsW7MDvYRwEc1Uwm0TIBfzjPFgg60UU2Haj5qsCs9cc3zNgY71edqE3LbWfF/WoZQd3lJoDXFQpag==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "8.8.0",
+ "@typescript-eslint/types": "8.8.1",
"eslint-visitor-keys": "^3.4.3"
},
"engines": {
@@ -7929,6 +8252,7 @@
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dev": true,
"license": "ISC",
"dependencies": {
"normalize-path": "^3.0.0",
@@ -7942,6 +8266,7 @@
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=8.6"
@@ -8441,6 +8766,7 @@
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
"integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -8785,9 +9111,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001666",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001666.tgz",
- "integrity": "sha512-gD14ICmoV5ZZM1OdzPWmpx+q4GyefaK06zi8hmfHV5xe4/2nOQX3+Dw5o+fSqOws2xVwL9j+anOPFwHzdEdV4g==",
+ "version": "1.0.30001668",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001668.tgz",
+ "integrity": "sha512-nWLrdxqCdblixUO+27JtGJJE/txpJlyUy5YN1u53wLZkP0emYCo5zgS6QYft7VUYR42LGgi/S5hdLZTrnyIddw==",
"funding": [
{
"type": "opencollective",
@@ -8855,6 +9181,7 @@
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
"integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"anymatch": "~3.1.2",
@@ -8875,6 +9202,19 @@
"fsevents": "~2.3.2"
}
},
+ "node_modules/chokidar/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/chownr": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
@@ -9114,9 +9454,9 @@
}
},
"node_modules/code-block-writer": {
- "version": "13.0.2",
- "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-13.0.2.tgz",
- "integrity": "sha512-XfXzAGiStXSmCIwrkdfvc7FS5Dtj8yelCtyOf2p2skCAfvLd6zu0rGzuS9NSCO3bq1JKpFZ7tbKdKlcd5occQA==",
+ "version": "13.0.3",
+ "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-13.0.3.tgz",
+ "integrity": "sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==",
"dev": true,
"license": "MIT"
},
@@ -9366,19 +9706,6 @@
"webpack": "^5.1.0"
}
},
- "node_modules/copy-webpack-plugin/node_modules/glob-parent": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
- "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "is-glob": "^4.0.3"
- },
- "engines": {
- "node": ">=10.13.0"
- }
- },
"node_modules/core-js": {
"version": "3.38.1",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.38.1.tgz",
@@ -10497,9 +10824,9 @@
}
},
"node_modules/electron-to-chromium": {
- "version": "1.5.32",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.32.tgz",
- "integrity": "sha512-M+7ph0VGBQqqpTT2YrabjNKSQ2fEl9PVx6AK3N558gDH9NO8O6XN9SXXFWRo9u9PbEg/bWq+tjXQr+eXmxubCw==",
+ "version": "1.5.36",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.36.tgz",
+ "integrity": "sha512-HYTX8tKge/VNp6FGO+f/uVDmUkq+cEfcxYhKf15Akc4M5yxt5YmorwlAitKWjWhWQnKcDRBAQKXkhqqXMqcrjw==",
"license": "ISC"
},
"node_modules/emittery": {
@@ -11372,19 +11699,6 @@
"url": "https://opencollective.com/eslint"
}
},
- "node_modules/eslint/node_modules/glob-parent": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
- "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "is-glob": "^4.0.3"
- },
- "engines": {
- "node": ">=10.13.0"
- }
- },
"node_modules/eslint/node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -11737,6 +12051,18 @@
"node": ">=8.6.0"
}
},
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/fast-json-patch": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz",
@@ -12018,9 +12344,9 @@
}
},
"node_modules/form-data": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
- "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz",
+ "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -12151,6 +12477,7 @@
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
"hasInstallScript": true,
"license": "MIT",
"optional": true,
@@ -12346,15 +12673,16 @@
}
},
"node_modules/glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
"license": "ISC",
"dependencies": {
- "is-glob": "^4.0.1"
+ "is-glob": "^4.0.3"
},
"engines": {
- "node": ">= 6"
+ "node": ">=10.13.0"
}
},
"node_modules/glob-to-regexp": {
@@ -13107,6 +13435,7 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"binary-extensions": "^2.0.0"
@@ -16558,9 +16887,9 @@
}
},
"node_modules/memfs": {
- "version": "4.12.0",
- "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.12.0.tgz",
- "integrity": "sha512-74wDsex5tQDSClVkeK1vtxqYCAgCoXxx+K4NSHzgU/muYVYByFqa+0RnrPO9NM6naWm1+G9JmZ0p6QHhXmeYfA==",
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.13.0.tgz",
+ "integrity": "sha512-dIs5KGy24fbdDhIAg0RxXpFqQp3RwL6wgSMRF9OSuphL/Uc9a4u2/SDJKPLj/zUgtOGKuHrRMrj563+IErj4Cg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -16960,7 +17289,8 @@
"node_modules/monaco-editor": {
"version": "0.52.0",
"resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.52.0.tgz",
- "integrity": "sha512-OeWhNpABLCeTqubfqLMXGsqf6OmPU6pHM85kF3dhy6kq5hnhuVS1p3VrEW/XhWHc71P2tHyS5JFySD8mgs1crw=="
+ "integrity": "sha512-OeWhNpABLCeTqubfqLMXGsqf6OmPU6pHM85kF3dhy6kq5hnhuVS1p3VrEW/XhWHc71P2tHyS5JFySD8mgs1crw==",
+ "license": "MIT"
},
"node_modules/moo-color": {
"version": "1.0.3",
@@ -17063,9 +17393,9 @@
}
},
"node_modules/nan": {
- "version": "2.20.0",
- "resolved": "https://registry.npmjs.org/nan/-/nan-2.20.0.tgz",
- "integrity": "sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw==",
+ "version": "2.22.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.22.0.tgz",
+ "integrity": "sha512-nbajikzWTMwsW+eSsNm3QwlOs7het9gGJU5dDZzRTQGk03vyBOauxgI4VakDzE0PtsGTmXPsXTbbjVhRwR5mpw==",
"license": "MIT",
"optional": true
},
@@ -17455,6 +17785,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -17619,15 +17950,15 @@
"license": "MIT"
},
"node_modules/nx": {
- "version": "19.8.3",
- "resolved": "https://registry.npmjs.org/nx/-/nx-19.8.3.tgz",
- "integrity": "sha512-/3FF4tgwPGRu4bV6O+aHqhTnOGHKF0/HNVkApUwjimSC+YzOX9VH1uBx2eReb4XC1scxDWkIzVi9gkFSXSQDjQ==",
+ "version": "19.8.4",
+ "resolved": "https://registry.npmjs.org/nx/-/nx-19.8.4.tgz",
+ "integrity": "sha512-fc833c3UKo6kuoG4z0kSKet17yWym3VzcQ+yPWYspxxxd8GFVVk42+9wieyVQDi9YqtKZQ6PdQfSEPm59/M7SA==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
"@napi-rs/wasm-runtime": "0.2.4",
- "@nrwl/tao": "19.8.3",
+ "@nrwl/tao": "19.8.4",
"@yarnpkg/lockfile": "^1.1.0",
"@yarnpkg/parsers": "3.0.0-rc.46",
"@zkochan/js-yaml": "0.0.7",
@@ -17666,16 +17997,16 @@
"nx-cloud": "bin/nx-cloud.js"
},
"optionalDependencies": {
- "@nx/nx-darwin-arm64": "19.8.3",
- "@nx/nx-darwin-x64": "19.8.3",
- "@nx/nx-freebsd-x64": "19.8.3",
- "@nx/nx-linux-arm-gnueabihf": "19.8.3",
- "@nx/nx-linux-arm64-gnu": "19.8.3",
- "@nx/nx-linux-arm64-musl": "19.8.3",
- "@nx/nx-linux-x64-gnu": "19.8.3",
- "@nx/nx-linux-x64-musl": "19.8.3",
- "@nx/nx-win32-arm64-msvc": "19.8.3",
- "@nx/nx-win32-x64-msvc": "19.8.3"
+ "@nx/nx-darwin-arm64": "19.8.4",
+ "@nx/nx-darwin-x64": "19.8.4",
+ "@nx/nx-freebsd-x64": "19.8.4",
+ "@nx/nx-linux-arm-gnueabihf": "19.8.4",
+ "@nx/nx-linux-arm64-gnu": "19.8.4",
+ "@nx/nx-linux-arm64-musl": "19.8.4",
+ "@nx/nx-linux-x64-gnu": "19.8.4",
+ "@nx/nx-linux-x64-musl": "19.8.4",
+ "@nx/nx-win32-arm64-msvc": "19.8.4",
+ "@nx/nx-win32-x64-msvc": "19.8.4"
},
"peerDependencies": {
"@swc-node/register": "^1.8.0",
@@ -18554,9 +18885,9 @@
}
},
"node_modules/pdfjs-dist": {
- "version": "4.6.82",
- "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-4.6.82.tgz",
- "integrity": "sha512-BUOryeRFwvbLe0lOU6NhkJNuVQUp06WxlJVVCsxdmJ4y5cU3O3s3/0DunVdK1PMm7v2MUw52qKYaidhDH1Z9+w==",
+ "version": "4.7.76",
+ "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-4.7.76.tgz",
+ "integrity": "sha512-8y6wUgC/Em35IumlGjaJOCm3wV4aY/6sqnIT3fVW/67mXsOZ9HWBn8GDKmJUK0GSzpbmX3gQqwfoFayp78Mtqw==",
"license": "Apache-2.0",
"engines": {
"node": ">=18"
@@ -18891,9 +19222,9 @@
"license": "MIT"
},
"node_modules/posthog-js": {
- "version": "1.166.1",
- "resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.166.1.tgz",
- "integrity": "sha512-K8IpV8FJTCdwhsXFSbKj5vZ6IXNV079lukpG3cRtst2q5vMmUXRQiks7W3lOZLrjWyuJLKZDUiCeeDIUFORRuQ==",
+ "version": "1.167.0",
+ "resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.167.0.tgz",
+ "integrity": "sha512-/zXQ6tuJgiF1d4mgg3UsAi/uoyg7UnfFNQtikuALmaE53xFExpcAKbMfHPG/f54QgTvLxSHyGL1kFl/1uspkGg==",
"license": "MIT",
"dependencies": {
"fflate": "^0.4.8",
@@ -18902,9 +19233,9 @@
}
},
"node_modules/preact": {
- "version": "10.24.1",
- "resolved": "https://registry.npmjs.org/preact/-/preact-10.24.1.tgz",
- "integrity": "sha512-PnBAwFI3Yjxxcxw75n6VId/5TFxNW/81zexzWD9jn1+eSrOP84NdsS38H5IkF/UH3frqRPT+MvuCoVHjTDTnDw==",
+ "version": "10.24.2",
+ "resolved": "https://registry.npmjs.org/preact/-/preact-10.24.2.tgz",
+ "integrity": "sha512-1cSoF0aCC8uaARATfrlz4VCBqE8LwZwRfLgkxJOQwAlQt6ayTmi0D9OF7nXid1POI5SZidFuG9CnlXbDfLqY/Q==",
"license": "MIT",
"funding": {
"type": "opencollective",
@@ -19342,6 +19673,7 @@
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"picomatch": "^2.2.1"
@@ -19354,6 +19686,7 @@
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=8.6"
@@ -19470,9 +19803,9 @@
"license": "MIT"
},
"node_modules/regjsparser": {
- "version": "0.11.0",
- "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.11.0.tgz",
- "integrity": "sha512-vTbzVAjQDzwQdKuvj7qEq6OlAprCjE656khuGQ4QaBLg7abQ9I9ISpmLuc6inWe7zP75AECjqUa4g4sdQvOXhg==",
+ "version": "0.11.1",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.11.1.tgz",
+ "integrity": "sha512-1DHODs4B8p/mQHU9kr+jv8+wIC9mtG4eBHxWxIq5mhjE3D5oORhCc6deRKzTjs9DcfRFmj9BHSDguZklqCGFWQ==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
@@ -19894,12 +20227,13 @@
"license": "MIT"
},
"node_modules/sass": {
- "version": "1.79.4",
- "resolved": "https://registry.npmjs.org/sass/-/sass-1.79.4.tgz",
- "integrity": "sha512-K0QDSNPXgyqO4GZq2HO5Q70TLxTH6cIT59RdoCHMivrC8rqzaTw5ab9prjz9KUN1El4FLXrBXJhik61JR4HcGg==",
+ "version": "1.79.5",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.79.5.tgz",
+ "integrity": "sha512-W1h5kp6bdhqFh2tk3DsI771MoEJjvrSY/2ihJRJS4pjIyfJCw0nTsxqhnrUzaLMOJjFchj8rOvraI/YUVjtx5g==",
"dev": true,
"license": "MIT",
"dependencies": {
+ "@parcel/watcher": "^2.4.1",
"chokidar": "^4.0.0",
"immutable": "^4.0.0",
"source-map-js": ">=0.6.2 <2.0.0"
@@ -21075,9 +21409,9 @@
"license": "MIT"
},
"node_modules/synckit": {
- "version": "0.9.1",
- "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.1.tgz",
- "integrity": "sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==",
+ "version": "0.9.2",
+ "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.2.tgz",
+ "integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -21429,22 +21763,22 @@
"license": "MIT"
},
"node_modules/tldts": {
- "version": "6.1.50",
- "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.50.tgz",
- "integrity": "sha512-q9GOap6q3KCsLMdOjXhWU5jVZ8/1dIib898JBRLsN+tBhENpBDcAVQbE0epADOjw11FhQQy9AcbqKGBQPUfTQA==",
+ "version": "6.1.51",
+ "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.51.tgz",
+ "integrity": "sha512-33lfQoL0JsDogIbZ8fgRyvv77GnRtwkNE/MOKocwUgPO1WrSfsq7+vQRKxRQZai5zd+zg97Iv9fpFQSzHyWdLA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "tldts-core": "^6.1.50"
+ "tldts-core": "^6.1.51"
},
"bin": {
"tldts": "bin/cli.js"
}
},
"node_modules/tldts-core": {
- "version": "6.1.50",
- "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.50.tgz",
- "integrity": "sha512-na2EcZqmdA2iV9zHV7OHQDxxdciEpxrjbkp+aHmZgnZKHzoElLajP59np5/4+sare9fQBfixgvXKx8ev1d7ytw==",
+ "version": "6.1.51",
+ "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.51.tgz",
+ "integrity": "sha512-bu9oCYYWC1iRjx+3UnAjqCsfrWNZV1ghNQf49b3w5xE8J/tNShHTzp5syWJfwGH+pxUgTTLUnzHnfuydW7wmbg==",
"dev": true,
"license": "MIT"
},
@@ -22872,9 +23206,9 @@
}
},
"node_modules/webpack-dev-server/node_modules/http-proxy-middleware": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz",
- "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==",
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz",
+ "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==",
"dev": true,
"license": "MIT",
"dependencies": {
diff --git a/package.json b/package.json
index b1063f9a90e0..755adfae3d3e 100644
--- a/package.json
+++ b/package.json
@@ -13,18 +13,18 @@
"node_modules"
],
"dependencies": {
- "@angular/animations": "18.2.7",
- "@angular/cdk": "18.2.7",
- "@angular/common": "18.2.7",
- "@angular/compiler": "18.2.7",
- "@angular/core": "18.2.7",
- "@angular/forms": "18.2.7",
- "@angular/localize": "18.2.7",
- "@angular/material": "18.2.7",
- "@angular/platform-browser": "18.2.7",
- "@angular/platform-browser-dynamic": "18.2.7",
- "@angular/router": "18.2.7",
- "@angular/service-worker": "18.2.7",
+ "@angular/animations": "18.2.8",
+ "@angular/cdk": "18.2.8",
+ "@angular/common": "18.2.8",
+ "@angular/compiler": "18.2.8",
+ "@angular/core": "18.2.8",
+ "@angular/forms": "18.2.8",
+ "@angular/localize": "18.2.8",
+ "@angular/material": "18.2.8",
+ "@angular/platform-browser": "18.2.8",
+ "@angular/platform-browser-dynamic": "18.2.8",
+ "@angular/router": "18.2.8",
+ "@angular/service-worker": "18.2.8",
"@ctrl/ngx-emoji-mart": "9.2.0",
"@danielmoncada/angular-datetime-picker": "18.1.0",
"@fingerprintjs/fingerprintjs": "4.5.0",
@@ -36,7 +36,7 @@
"@ng-bootstrap/ng-bootstrap": "17.0.1",
"@ngx-translate/core": "15.0.0",
"@ngx-translate/http-loader": "8.0.0",
- "@sentry/angular": "8.33.1",
+ "@sentry/angular": "8.34.0",
"@siemens/ngx-datatable": "22.4.1",
"@swimlane/ngx-charts": "20.5.0",
"@swimlane/ngx-graph": "8.4.0",
@@ -62,8 +62,8 @@
"ngx-infinite-scroll": "18.0.0",
"ngx-webstorage": "18.0.0",
"papaparse": "5.4.1",
- "pdfjs-dist": "4.6.82",
- "posthog-js": "1.166.1",
+ "pdfjs-dist": "4.7.76",
+ "posthog-js": "1.167.0",
"rxjs": "7.8.1",
"showdown": "2.1.0",
"showdown-highlight": "3.1.0",
@@ -119,29 +119,29 @@
},
"devDependencies": {
"@angular-builders/jest": "18.0.0",
- "@angular-devkit/build-angular": "18.2.7",
+ "@angular-devkit/build-angular": "18.2.8",
"@angular-eslint/builder": "18.3.1",
"@angular-eslint/eslint-plugin": "18.3.1",
"@angular-eslint/eslint-plugin-template": "18.3.1",
"@angular-eslint/schematics": "18.3.1",
"@angular-eslint/template-parser": "18.3.1",
- "@angular/cli": "18.2.7",
- "@angular/compiler-cli": "18.2.7",
- "@angular/language-service": "18.2.7",
- "@sentry/types": "8.33.1",
+ "@angular/cli": "18.2.8",
+ "@angular/compiler-cli": "18.2.8",
+ "@angular/language-service": "18.2.8",
+ "@sentry/types": "8.34.0",
"@types/crypto-js": "4.2.2",
"@types/d3-shape": "3.1.6",
"@types/dompurify": "3.0.5",
"@types/jest": "29.5.13",
"@types/lodash-es": "4.17.12",
- "@types/node": "22.7.4",
+ "@types/node": "22.7.5",
"@types/papaparse": "5.3.14",
"@types/showdown": "2.0.6",
"@types/smoothscroll-polyfill": "0.3.4",
"@types/sockjs-client": "1.5.4",
"@types/uuid": "10.0.0",
- "@typescript-eslint/eslint-plugin": "8.8.0",
- "@typescript-eslint/parser": "8.8.0",
+ "@typescript-eslint/eslint-plugin": "8.8.1",
+ "@typescript-eslint/parser": "8.8.1",
"eslint": "9.12.0",
"eslint-config-prettier": "9.1.0",
"eslint-plugin-deprecation": "3.0.0",
@@ -162,7 +162,7 @@
"ng-mocks": "14.13.1",
"prettier": "3.3.3",
"rimraf": "6.0.1",
- "sass": "1.79.4",
+ "sass": "1.79.5",
"ts-jest": "29.2.5",
"typescript": "5.5.4",
"weak-napi": "2.0.2"
From 36f12605a68c8061ad503203c523be114035b9cd Mon Sep 17 00:00:00 2001
From: Stephan Krusche
Date: Sat, 12 Oct 2024 12:52:28 +0200
Subject: [PATCH 09/28] Development: Update server dependencies
---
build.gradle | 2 +-
gradle.properties | 8 ++++----
jest.config.js | 6 +++---
3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/build.gradle b/build.gradle
index cdad264bac58..163b2517748f 100644
--- a/build.gradle
+++ b/build.gradle
@@ -535,7 +535,7 @@ dependencies {
testImplementation "org.awaitility:awaitility:4.2.2"
testImplementation "org.apache.maven.shared:maven-invoker:3.3.0"
testImplementation "org.gradle:gradle-tooling-api:8.10.2"
- testImplementation "org.apache.maven.surefire:surefire-report-parser:3.5.0"
+ testImplementation "org.apache.maven.surefire:surefire-report-parser:3.5.1"
testImplementation "com.opencsv:opencsv:5.9"
testImplementation("io.zonky.test:embedded-database-spring-test:2.5.1") {
exclude group: "org.testcontainers", module: "mariadb"
diff --git a/gradle.properties b/gradle.properties
index 46526dddaf56..07ee79d07d25 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -25,17 +25,17 @@ jplag_version=5.1.0
# NOTE: we do not need to use the latest version 9.x here as long as Stanford CoreNLP does not reference it
lucene_version=8.11.4
slf4j_version=2.0.16
-sentry_version=7.14.0
+sentry_version=7.15.0
liquibase_version=4.29.2
docker_java_version=3.4.0
-logback_version=1.5.8
+logback_version=1.5.10
java_parser_version=3.26.2
-byte_buddy_version=1.15.3
+byte_buddy_version=1.15.4
# testing
# make sure both versions are compatible
junit_version=5.11.0
-junit_platform_version=1.11.1
+junit_platform_version=1.11.2
mockito_version=5.14.1
diff --git a/jest.config.js b/jest.config.js
index 48cac393d596..77fd322375d8 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -102,9 +102,9 @@ module.exports = {
coverageThreshold: {
global: {
// TODO: in the future, the following values should increase to at least 90%
- statements: 87.43,
- branches: 73.72,
- functions: 82.05,
+ statements: 87.44,
+ branches: 73.74,
+ functions: 82.10,
lines: 87.49,
},
},
From 3fd3dc54650282e41d7a187e4f43b03125bb7505 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Johannes=20St=C3=B6hr?=
<38322605+JohannesStoehr@users.noreply.github.com>
Date: Sat, 12 Oct 2024 13:23:26 +0200
Subject: [PATCH 10/28] Development: Use @EnforceAdmin annotation on class
level (#9422)
---
.../atlas/web/LearningPathResource.java | 12 +---
.../artemis/atlas/web/ScienceResource.java | 2 +-
.../web/StandardizedCompetencyResource.java | 5 +-
.../AdminStandardizedCompetencyResource.java | 18 +-----
.../AdminSystemNotificationResource.java | 4 +-
.../security/annotations/AnnotationUtils.java | 62 ++++++++++++++++---
.../security/annotations/EnforceAdmin.java | 5 +-
.../service/feature/FeatureToggleAspect.java | 20 +++---
...tResource.java => AdminAuditResource.java} | 8 +--
.../web/admin/AdminBuildJobQueueResource.java | 11 +---
.../core/web/admin/AdminCourseResource.java | 4 +-
.../web/admin/AdminDataExportResource.java | 2 +-
...e.java => AdminFeatureToggleResource.java} | 6 +-
.../core/web/admin/AdminImprintResource.java | 3 +-
...LogResource.java => AdminLogResource.java} | 5 +-
.../web/admin/AdminOrganizationResource.java | 15 +----
.../admin/AdminPrivacyStatementResource.java | 3 +-
.../web/admin/AdminStatisticsResource.java | 2 +-
.../core/web/admin/AdminUserResource.java | 11 +---
.../exam/web/admin/AdminExamResource.java | 2 +-
.../web/admin/AdminExerciseResource.java | 2 +-
.../web/admin/AdminIrisSettingsResource.java | 2 +-
.../admin/AdminLtiConfigurationResource.java | 6 +-
.../admin/AdminModelingExerciseResource.java | 4 +-
...ogrammingExerciseExportImportResource.java | 17 +++--
...ProgrammingExercisePlagiarismResource.java | 5 +-
.../AdminTextAssessmentEventResource.java | 2 +-
.../web/TutorialGroupFreePeriodResource.java | 5 +-
.../web/TutorialGroupResource.java | 15 +----
.../web/TutorialGroupSessionResource.java | 8 +--
.../TutorialGroupsConfigurationResource.java | 4 +-
.../AuthorizationArchitectureTest.java | 2 +-
...bstractModuleResourceArchitectureTest.java | 27 ++++++++
33 files changed, 137 insertions(+), 162 deletions(-)
rename src/main/java/de/tum/cit/aet/artemis/core/web/admin/{AuditResource.java => AdminAuditResource.java} (96%)
rename src/main/java/de/tum/cit/aet/artemis/core/web/admin/{FeatureToggleResource.java => AdminFeatureToggleResource.java} (91%)
rename src/main/java/de/tum/cit/aet/artemis/core/web/admin/{LogResource.java => AdminLogResource.java} (96%)
diff --git a/src/main/java/de/tum/cit/aet/artemis/atlas/web/LearningPathResource.java b/src/main/java/de/tum/cit/aet/artemis/atlas/web/LearningPathResource.java
index d940e50acc51..f69dae28f80c 100644
--- a/src/main/java/de/tum/cit/aet/artemis/atlas/web/LearningPathResource.java
+++ b/src/main/java/de/tum/cit/aet/artemis/atlas/web/LearningPathResource.java
@@ -59,6 +59,7 @@
import de.tum.cit.aet.artemis.lecture.service.LearningObjectService;
@Profile(PROFILE_CORE)
+@FeatureToggle(Feature.LearningPaths)
@RestController
@RequestMapping("api/")
public class LearningPathResource {
@@ -108,7 +109,6 @@ public LearningPathResource(CourseService courseService, CourseRepository course
* @return the ResponseEntity with status 200 (OK)
*/
@PutMapping("courses/{courseId}/learning-paths/enable")
- @FeatureToggle(Feature.LearningPaths)
@EnforceAtLeastInstructorInCourse
public ResponseEntity enableLearningPathsForCourse(@PathVariable long courseId) {
log.debug("REST request to enable learning paths for course with id: {}", courseId);
@@ -129,7 +129,6 @@ public ResponseEntity enableLearningPathsForCourse(@PathVariable long cour
* @return the ResponseEntity with status 200 (OK)
*/
@PutMapping("courses/{courseId}/learning-paths/generate-missing")
- @FeatureToggle(Feature.LearningPaths)
@EnforceAtLeastInstructorInCourse
public ResponseEntity generateMissingLearningPathsForCourse(@PathVariable long courseId) {
log.debug("REST request to generate missing learning paths for course with id: {}", courseId);
@@ -147,7 +146,6 @@ public ResponseEntity generateMissingLearningPathsForCourse(@PathVariable
* @return the ResponseEntity with status 200 (OK) and with body the desired page, sorted and matching the given query
*/
@GetMapping("courses/{courseId}/learning-paths")
- @FeatureToggle(Feature.LearningPaths)
@EnforceAtLeastInstructorInCourse
public ResponseEntity> getLearningPathsOnPage(@PathVariable long courseId, SearchTermPageableSearchDTO search) {
log.debug("REST request to get learning paths for course with id: {}", courseId);
@@ -162,7 +160,6 @@ public ResponseEntity> getLearni
* @return the ResponseEntity with status 200 (OK) and with body the health status
*/
@GetMapping("courses/{courseId}/learning-path-health")
- @FeatureToggle(Feature.LearningPaths)
@EnforceAtLeastInstructorInCourse
public ResponseEntity getHealthStatusForCourse(@PathVariable long courseId) {
log.debug("REST request to get health status of learning paths in course with id: {}", courseId);
@@ -177,7 +174,6 @@ public ResponseEntity getHealthStatusForCourse(@PathVaria
* @return the ResponseEntity with status 200 (OK) and with body the learning path
*/
@GetMapping("learning-path/{learningPathId}")
- @FeatureToggle(Feature.LearningPaths)
@EnforceAtLeastStudent
public ResponseEntity getLearningPath(@PathVariable long learningPathId) {
log.debug("REST request to get learning path with id: {}", learningPathId);
@@ -196,7 +192,6 @@ public ResponseEntity getLearningPath(@PathVariable
* @return the ResponseEntity with status 200 (OK) and with body the graph
*/
@GetMapping("learning-path/{learningPathId}/competency-graph")
- @FeatureToggle(Feature.LearningPaths)
@EnforceAtLeastStudent
public ResponseEntity getLearningPathCompetencyGraph(@PathVariable long learningPathId) {
log.debug("REST request to get competency graph for learning path with id: {}", learningPathId);
@@ -215,7 +210,6 @@ public ResponseEntity getLearningPathCompetencyG
* @return the ResponseEntity with status 200 (OK) and with body the ngx representation of the learning path
*/
@GetMapping("learning-path/{learningPathId}/graph")
- @FeatureToggle(Feature.LearningPaths)
@EnforceAtLeastStudent
public ResponseEntity getLearningPathNgxGraph(@PathVariable long learningPathId) {
log.debug("REST request to get ngx graph representation of learning path with id: {}", learningPathId);
@@ -229,7 +223,6 @@ public ResponseEntity getLearningPathNgxGraph(@PathVariable
* @return the ResponseEntity with status 200 (OK) and with body the ngx representation of the learning path
*/
@GetMapping("learning-path/{learningPathId}/path")
- @FeatureToggle(Feature.LearningPaths)
@EnforceAtLeastStudent
public ResponseEntity getLearningPathNgxPath(@PathVariable long learningPathId) {
log.debug("REST request to get ngx path representation of learning path with id: {}", learningPathId);
@@ -246,7 +239,6 @@ public ResponseEntity getLearningPathNgxPath(@PathVariable l
* @return the ResponseEntity with status 200 (OK) and with body the navigation information
*/
@GetMapping("learning-path/{learningPathId}/relative-navigation")
- @FeatureToggle(Feature.LearningPaths)
@EnforceAtLeastStudent
public ResponseEntity getRelativeLearningPathNavigation(@PathVariable @Valid long learningPathId, @RequestParam long learningObjectId,
@RequestParam LearningObjectType learningObjectType, @RequestParam long competencyId) {
@@ -265,7 +257,6 @@ public ResponseEntity getRelativeLearningPathNavigati
* @return the ResponseEntity with status 200 (OK) and with body the navigation information
*/
@GetMapping("learning-path/{learningPathId}/navigation")
- @FeatureToggle(Feature.LearningPaths)
@EnforceAtLeastStudent
public ResponseEntity getLearningPathNavigation(@PathVariable long learningPathId) {
log.debug("REST request to get navigation for learning path with id: {}", learningPathId);
@@ -281,7 +272,6 @@ public ResponseEntity getLearningPathNavigation(@Path
* @return the ResponseEntity with status 200 (OK) and with body the navigation overview
*/
@GetMapping("learning-path/{learningPathId}/navigation-overview")
- @FeatureToggle(Feature.LearningPaths)
@EnforceAtLeastStudent
public ResponseEntity getLearningPathNavigationOverview(@PathVariable @Valid long learningPathId) {
log.debug("REST request to get navigation overview for learning path with id: {}", learningPathId);
diff --git a/src/main/java/de/tum/cit/aet/artemis/atlas/web/ScienceResource.java b/src/main/java/de/tum/cit/aet/artemis/atlas/web/ScienceResource.java
index 7312cc824997..d4e1563df41c 100644
--- a/src/main/java/de/tum/cit/aet/artemis/atlas/web/ScienceResource.java
+++ b/src/main/java/de/tum/cit/aet/artemis/atlas/web/ScienceResource.java
@@ -21,6 +21,7 @@
* REST controller providing the science related endpoints.
*/
@Profile(PROFILE_CORE)
+@FeatureToggle(Feature.Science)
@RestController
@RequestMapping("api/")
public class ScienceResource {
@@ -40,7 +41,6 @@ public ScienceResource(ScienceEventService scienceEventService) {
* @return the ResponseEntity with status 200 (OK)
*/
@PutMapping(value = "science")
- @FeatureToggle(Feature.Science)
@EnforceAtLeastStudent
public ResponseEntity science(@RequestBody ScienceEventDTO event) {
log.debug("REST request to log science event of type {}", event);
diff --git a/src/main/java/de/tum/cit/aet/artemis/atlas/web/StandardizedCompetencyResource.java b/src/main/java/de/tum/cit/aet/artemis/atlas/web/StandardizedCompetencyResource.java
index 8b6316fcc51c..b205db140bc3 100644
--- a/src/main/java/de/tum/cit/aet/artemis/atlas/web/StandardizedCompetencyResource.java
+++ b/src/main/java/de/tum/cit/aet/artemis/atlas/web/StandardizedCompetencyResource.java
@@ -29,6 +29,7 @@
* REST controller for managing {@link StandardizedCompetency} entities.
*/
@Profile(PROFILE_CORE)
+@FeatureToggle(Feature.StandardizedCompetencies)
@RestController
@RequestMapping("api/standardized-competencies/")
public class StandardizedCompetencyResource {
@@ -58,7 +59,6 @@ public StandardizedCompetencyResource(StandardizedCompetencyService standardized
* @return the ResponseEntity with status 200 (OK) and with body containing the standardized competency, or with status 404 (Not Found)
*/
@GetMapping("{competencyId}")
- @FeatureToggle(Feature.StandardizedCompetencies)
@EnforceAtLeastInstructor
public ResponseEntity getStandardizedCompetency(@PathVariable long competencyId) {
log.debug("REST request to get standardized competency with id : {}", competencyId);
@@ -74,7 +74,6 @@ public ResponseEntity getStandardizedCompetency(@PathVar
* @return the ResponseEntity with status 200 (OK) and with body containing the knowledge areas
*/
@GetMapping("for-tree-view")
- @FeatureToggle(Feature.StandardizedCompetencies)
@EnforceAtLeastInstructor
public ResponseEntity> getAllForTreeView() {
log.debug("REST request to all knowledge areas for tree view");
@@ -91,7 +90,6 @@ public ResponseEntity> getAllForTreeView() {
* @return the ResponseEntity with status 200 (OK) and with body containing the knowledge area, or with status 404 (Not Found)
*/
@GetMapping("knowledge-areas/{knowledgeAreaId}")
- @FeatureToggle(Feature.StandardizedCompetencies)
@EnforceAtLeastInstructor
public ResponseEntity getKnowledgeArea(@PathVariable long knowledgeAreaId) {
log.debug("REST request to get knowledge area with id : {}", knowledgeAreaId);
@@ -107,7 +105,6 @@ public ResponseEntity getKnowledgeArea(@PathVariable long knowled
* @return the ResponseEntity with status 200 (OK) and with body containing the list of sources
*/
@GetMapping("sources")
- @FeatureToggle(Feature.StandardizedCompetencies)
@EnforceAtLeastInstructor
public ResponseEntity> getSources() {
log.debug("REST request to get all sources");
diff --git a/src/main/java/de/tum/cit/aet/artemis/atlas/web/admin/AdminStandardizedCompetencyResource.java b/src/main/java/de/tum/cit/aet/artemis/atlas/web/admin/AdminStandardizedCompetencyResource.java
index 376cedb132dc..5c974101f8bb 100644
--- a/src/main/java/de/tum/cit/aet/artemis/atlas/web/admin/AdminStandardizedCompetencyResource.java
+++ b/src/main/java/de/tum/cit/aet/artemis/atlas/web/admin/AdminStandardizedCompetencyResource.java
@@ -38,6 +38,8 @@
* Admin REST controller for managing {@link StandardizedCompetency} entities.
*/
@Profile(PROFILE_CORE)
+@FeatureToggle(Feature.StandardizedCompetencies)
+@EnforceAdmin
@RestController
@RequestMapping("api/admin/")
public class AdminStandardizedCompetencyResource {
@@ -61,8 +63,6 @@ public AdminStandardizedCompetencyResource(StandardizedCompetencyService standar
* @throws URISyntaxException if the Location URI syntax is incorrect
*/
@PostMapping("standardized-competencies")
- @FeatureToggle(Feature.StandardizedCompetencies)
- @EnforceAdmin
public ResponseEntity createStandardizedCompetency(@RequestBody @Valid StandardizedCompetencyRequestDTO competency) throws URISyntaxException {
log.debug("REST request to create standardized competency : {}", competency);
@@ -79,8 +79,6 @@ public ResponseEntity createStandardizedCompete
* @return the ResponseEntity with status 200 (OK) and with body the updated standardized competency
*/
@PutMapping("standardized-competencies/{competencyId}")
- @FeatureToggle(Feature.StandardizedCompetencies)
- @EnforceAdmin
public ResponseEntity updateStandardizedCompetency(@PathVariable long competencyId,
@RequestBody @Valid StandardizedCompetencyRequestDTO competency) {
log.debug("REST request to update standardized competency : {}", competency);
@@ -97,8 +95,6 @@ public ResponseEntity updateStandardizedCompete
* @return the ResponseEntity with status 200 (OK)
*/
@DeleteMapping("standardized-competencies/{competencyId}")
- @FeatureToggle(Feature.StandardizedCompetencies)
- @EnforceAdmin
public ResponseEntity deleteStandardizedCompetency(@PathVariable long competencyId) {
log.debug("REST request to delete standardized competency : {}", competencyId);
@@ -115,8 +111,6 @@ public ResponseEntity deleteStandardizedCompetency(@PathVariable long comp
* @throws URISyntaxException if the Location URI syntax is incorrect
*/
@PostMapping("standardized-competencies/knowledge-areas")
- @FeatureToggle(Feature.StandardizedCompetencies)
- @EnforceAdmin
public ResponseEntity createKnowledgeArea(@RequestBody @Valid KnowledgeAreaRequestDTO knowledgeArea) throws URISyntaxException {
log.debug("REST request to create knowledge area : {}", knowledgeArea);
@@ -134,8 +128,6 @@ public ResponseEntity createKnowledgeArea(@RequestBody @
* @return the ResponseEntity with status 200 (OK) and with body the updated knowledge area
*/
@PutMapping("standardized-competencies/knowledge-areas/{knowledgeAreaId}")
- @FeatureToggle(Feature.StandardizedCompetencies)
- @EnforceAdmin
public ResponseEntity updateKnowledgeArea(@PathVariable long knowledgeAreaId, @RequestBody @Valid KnowledgeAreaRequestDTO knowledgeArea) {
log.debug("REST request to update knowledge area : {}", knowledgeArea);
@@ -151,8 +143,6 @@ public ResponseEntity updateKnowledgeArea(@PathVariable
* @return the ResponseEntity with status 200 (OK)
*/
@DeleteMapping("standardized-competencies/knowledge-areas/{knowledgeAreaId}")
- @FeatureToggle(Feature.StandardizedCompetencies)
- @EnforceAdmin
public ResponseEntity deleteKnowledgeArea(@PathVariable long knowledgeAreaId) {
log.debug("REST request to delete knowledge area : {}", knowledgeAreaId);
@@ -168,8 +158,6 @@ public ResponseEntity deleteKnowledgeArea(@PathVariable long knowledgeArea
* @return the ResponseEntity with status 200 (OK)
*/
@PutMapping("standardized-competencies/import")
- @FeatureToggle(Feature.StandardizedCompetencies)
- @EnforceAdmin
public ResponseEntity importStandardizedCompetencyCatalog(@RequestBody @Valid StandardizedCompetencyCatalogDTO standardizedCompetencyCatalogDTO) {
log.debug("REST request to import standardized competency catalog");
@@ -184,8 +172,6 @@ public ResponseEntity importStandardizedCompetencyCatalog(@RequestBody @Va
* @return the ResponseEntity with status 200 (OK) and the body containing the JSON string of the standardized competency catalog
*/
@GetMapping("standardized-competencies/export")
- @FeatureToggle(Feature.StandardizedCompetencies)
- @EnforceAdmin
public ResponseEntity exportStandardizedCompetencyCatalog() {
log.debug("REST request to export standardized competency catalog");
diff --git a/src/main/java/de/tum/cit/aet/artemis/communication/web/admin/AdminSystemNotificationResource.java b/src/main/java/de/tum/cit/aet/artemis/communication/web/admin/AdminSystemNotificationResource.java
index 6850598633e9..4e94766284d6 100644
--- a/src/main/java/de/tum/cit/aet/artemis/communication/web/admin/AdminSystemNotificationResource.java
+++ b/src/main/java/de/tum/cit/aet/artemis/communication/web/admin/AdminSystemNotificationResource.java
@@ -30,6 +30,7 @@
* REST controller for administrating system notifications.
*/
@Profile(PROFILE_CORE)
+@EnforceAdmin
@RestController
@RequestMapping("api/admin/")
public class AdminSystemNotificationResource {
@@ -58,7 +59,6 @@ public AdminSystemNotificationResource(SystemNotificationRepository systemNotifi
* @throws URISyntaxException if the Location URI syntax is incorrect
*/
@PostMapping("system-notifications")
- @EnforceAdmin
public ResponseEntity createSystemNotification(@RequestBody SystemNotification systemNotification) throws URISyntaxException {
log.debug("REST request to save SystemNotification : {}", systemNotification);
if (systemNotification.getId() != null) {
@@ -79,7 +79,6 @@ public ResponseEntity createSystemNotification(@RequestBody System
* status 500 (Internal Server Error) if the system notification couldn't be updated
*/
@PutMapping("system-notifications")
- @EnforceAdmin
public ResponseEntity updateSystemNotification(@RequestBody SystemNotification systemNotification) {
log.debug("REST request to update SystemNotification : {}", systemNotification);
if (systemNotification.getId() == null) {
@@ -101,7 +100,6 @@ public ResponseEntity updateSystemNotification(@RequestBody
* @return the ResponseEntity with status 200 (OK)
*/
@DeleteMapping("system-notifications/{notificationId}")
- @EnforceAdmin
public ResponseEntity deleteSystemNotification(@PathVariable Long notificationId) {
log.debug("REST request to delete SystemNotification : {}", notificationId);
systemNotificationRepository.deleteById(notificationId);
diff --git a/src/main/java/de/tum/cit/aet/artemis/core/security/annotations/AnnotationUtils.java b/src/main/java/de/tum/cit/aet/artemis/core/security/annotations/AnnotationUtils.java
index c5aef335defb..028342bfeee9 100644
--- a/src/main/java/de/tum/cit/aet/artemis/core/security/annotations/AnnotationUtils.java
+++ b/src/main/java/de/tum/cit/aet/artemis/core/security/annotations/AnnotationUtils.java
@@ -3,7 +3,9 @@
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
import java.util.Optional;
import jakarta.validation.constraints.NotBlank;
@@ -22,7 +24,8 @@ private AnnotationUtils() {
}
/**
- * Extracts the annotation from the method or type
+ * Extracts the annotation from the method or type and all super classes.
+ * In case multiple versions of the annotation are present, the one closest to the method is returned.
*
* @param clazz the annotation class
* @param joinPoint the join point
@@ -33,26 +36,71 @@ private AnnotationUtils() {
public static Optional getAnnotation(@NotNull Class clazz, @NotNull ProceedingJoinPoint joinPoint) {
final var method = ((MethodSignature) joinPoint.getSignature()).getMethod();
T annotation = method.getAnnotation(clazz);
+
+ Optional foundAnnotation = getAnnotation(clazz, method.getDeclaredAnnotations(), annotation);
+ if (foundAnnotation.isPresent()) {
+ return foundAnnotation;
+ }
+
+ for (Class> declaringClass = method.getDeclaringClass(); declaringClass != null; declaringClass = declaringClass.getSuperclass()) {
+ annotation = declaringClass.getAnnotation(clazz);
+ foundAnnotation = getAnnotation(clazz, declaringClass.getDeclaredAnnotations(), annotation);
+ if (foundAnnotation.isPresent()) {
+ return foundAnnotation;
+ }
+ }
+
+ return Optional.empty();
+ }
+
+ private static Optional getAnnotation(Class clazz, Annotation[] declaredAnnotations, T annotation) {
if (annotation != null) {
return Optional.of(annotation);
}
- for (Annotation a : method.getDeclaredAnnotations()) {
+ for (Annotation a : declaredAnnotations) {
annotation = a.annotationType().getAnnotation(clazz);
if (annotation != null) {
return Optional.of(annotation);
}
}
- annotation = method.getDeclaringClass().getAnnotation(clazz);
+ return Optional.empty();
+ }
+
+ /**
+ * Extracts the annotations from the method or type and all super classes.
+ * In case multiple versions of the annotation are present, all are returned.
+ *
+ * @param clazz the annotation class
+ * @param joinPoint the join point
+ * @param the type of the annotation
+ * @return the annotations if they are present, empty otherwise
+ */
+ public static List getAnnotations(@NotNull Class clazz, @NotNull ProceedingJoinPoint joinPoint) {
+ List annotations = new ArrayList<>();
+
+ final var method = ((MethodSignature) joinPoint.getSignature()).getMethod();
+ T annotation = method.getAnnotation(clazz);
+
+ addAnnotations(clazz, method.getDeclaredAnnotations(), annotation, annotations);
+
+ for (Class> declaringClass = method.getDeclaringClass(); declaringClass != null; declaringClass = declaringClass.getSuperclass()) {
+ annotation = declaringClass.getAnnotation(clazz);
+ addAnnotations(clazz, declaringClass.getDeclaredAnnotations(), annotation, annotations);
+ }
+
+ return annotations;
+ }
+
+ private static void addAnnotations(Class clazz, Annotation[] declaredAnnotations, T annotation, List annotations) {
if (annotation != null) {
- return Optional.of(annotation);
+ annotations.add(annotation);
}
- for (Annotation a : method.getDeclaringClass().getDeclaredAnnotations()) {
+ for (Annotation a : declaredAnnotations) {
annotation = a.annotationType().getAnnotation(clazz);
if (annotation != null) {
- return Optional.of(annotation);
+ annotations.add(annotation);
}
}
- return Optional.empty();
}
/**
diff --git a/src/main/java/de/tum/cit/aet/artemis/core/security/annotations/EnforceAdmin.java b/src/main/java/de/tum/cit/aet/artemis/core/security/annotations/EnforceAdmin.java
index 5adbcd73c16c..9fdbf88d9d82 100644
--- a/src/main/java/de/tum/cit/aet/artemis/core/security/annotations/EnforceAdmin.java
+++ b/src/main/java/de/tum/cit/aet/artemis/core/security/annotations/EnforceAdmin.java
@@ -10,11 +10,8 @@
/**
* This annotation is used to enforce that the user is an admin.
* It should only be used with endpoints starting with {@code /api/admin/}
- *
- * It's only addable to methods. The intention is that a developer can see the required role without the need to scroll up.
- * This also prevents overrides of the annotation.
*/
-@Target(ElementType.METHOD)
+@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@PreAuthorize("hasRole('ADMIN')")
public @interface EnforceAdmin {
diff --git a/src/main/java/de/tum/cit/aet/artemis/core/service/feature/FeatureToggleAspect.java b/src/main/java/de/tum/cit/aet/artemis/core/service/feature/FeatureToggleAspect.java
index 87785e123cec..ffeed9cfa513 100644
--- a/src/main/java/de/tum/cit/aet/artemis/core/service/feature/FeatureToggleAspect.java
+++ b/src/main/java/de/tum/cit/aet/artemis/core/service/feature/FeatureToggleAspect.java
@@ -1,8 +1,11 @@
package de.tum.cit.aet.artemis.core.service.feature;
import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_CORE;
+import static de.tum.cit.aet.artemis.core.security.annotations.AnnotationUtils.getAnnotations;
import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Stream;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
@@ -26,25 +29,24 @@ public FeatureToggleAspect(FeatureToggleService featureToggleService) {
/**
* Pointcut around all methods or classes annotated with {@link FeatureToggle}.
- *
- * @param featureToggle The feature toggle annotation containing the relevant features
*/
- @Pointcut("@within(featureToggle) || @annotation(featureToggle)")
- public void callAt(FeatureToggle featureToggle) {
+ @Pointcut("@within(de.tum.cit.aet.artemis.core.service.feature.FeatureToggle) || @annotation(de.tum.cit.aet.artemis.core.service.feature.FeatureToggle) || execution(@(@de.tum.cit.aet.artemis.core.service.feature.FeatureToggle *) * *(..))")
+ protected void callAt() {
}
/**
* Aspect around all methods for which a feature toggle has been activated. Will check all specified features and only
* execute the underlying method if all features are enabled. Will otherwise return forbidden (as response entity)
*
- * @param joinPoint Proceeding join point of the aspect
- * @param featureToggle The feature toggle annotation containing all features that should get checked
+ * @param joinPoint Proceeding join point of the aspect
* @return The original return value of the called method, if all features are enabled, a forbidden response entity otherwise
* @throws Throwable If there was any error during method execution (both the aspect or the actual called method)
*/
- @Around(value = "callAt(featureToggle)", argNames = "joinPoint,featureToggle")
- public Object around(ProceedingJoinPoint joinPoint, FeatureToggle featureToggle) throws Throwable {
- if (Arrays.stream(featureToggle.value()).allMatch(featureToggleService::isFeatureEnabled)) {
+ @Around(value = "callAt()", argNames = "joinPoint")
+ public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
+ List featureToggleAnnotations = getAnnotations(FeatureToggle.class, joinPoint);
+ Stream features = featureToggleAnnotations.stream().flatMap(featureToggle -> Arrays.stream(featureToggle.value()));
+ if (features.allMatch(featureToggleService::isFeatureEnabled)) {
return joinPoint.proceed();
}
else {
diff --git a/src/main/java/de/tum/cit/aet/artemis/core/web/admin/AuditResource.java b/src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminAuditResource.java
similarity index 96%
rename from src/main/java/de/tum/cit/aet/artemis/core/web/admin/AuditResource.java
rename to src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminAuditResource.java
index fe8af9ff7eb0..7c0a339d9717 100644
--- a/src/main/java/de/tum/cit/aet/artemis/core/web/admin/AuditResource.java
+++ b/src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminAuditResource.java
@@ -30,13 +30,14 @@
* REST controller for getting the audit events.
*/
@Profile(PROFILE_CORE)
+@EnforceAdmin
@RestController
@RequestMapping("api/admin/")
-public class AuditResource {
+public class AdminAuditResource {
private final AuditEventService auditEventService;
- public AuditResource(AuditEventService auditEventService) {
+ public AdminAuditResource(AuditEventService auditEventService) {
this.auditEventService = auditEventService;
}
@@ -47,7 +48,6 @@ public AuditResource(AuditEventService auditEventService) {
* @return the ResponseEntity with status 200 (OK) and the list of AuditEvents in body
*/
@GetMapping("audits")
- @EnforceAdmin
public ResponseEntity> getAll(Pageable pageable) {
Page page = auditEventService.findAll(pageable);
HttpHeaders headers = generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page);
@@ -63,7 +63,6 @@ public ResponseEntity> getAll(Pageable pageable) {
* @return the ResponseEntity with status 200 (OK) and the list of AuditEvents in body
*/
@GetMapping(value = "audits", params = { "fromDate", "toDate" })
- @EnforceAdmin
public ResponseEntity> getByDates(@RequestParam(value = "fromDate") LocalDate fromDate, @RequestParam(value = "toDate") LocalDate toDate, Pageable pageable) {
Instant from = fromDate.atStartOfDay(ZoneId.systemDefault()).toInstant();
@@ -81,7 +80,6 @@ public ResponseEntity> getByDates(@RequestParam(value = "fromDa
* @return the ResponseEntity with status 200 (OK) and the AuditEvent in body, or status 404 (Not Found)
*/
@GetMapping("audits/{id:.+}")
- @EnforceAdmin
public ResponseEntity get(@PathVariable Long id) {
return ResponseUtil.wrapOrNotFound(auditEventService.find(id));
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminBuildJobQueueResource.java b/src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminBuildJobQueueResource.java
index bd1bcc4dea1b..db71ab34c05a 100644
--- a/src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminBuildJobQueueResource.java
+++ b/src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminBuildJobQueueResource.java
@@ -33,6 +33,7 @@
import tech.jhipster.web.util.PaginationUtil;
@Profile(PROFILE_LOCALCI)
+@EnforceAdmin
@RestController
@RequestMapping("api/admin/")
public class AdminBuildJobQueueResource {
@@ -54,7 +55,6 @@ public AdminBuildJobQueueResource(SharedQueueManagementService localCIBuildJobQu
* @return the queued build jobs
*/
@GetMapping("queued-jobs")
- @EnforceAdmin
public ResponseEntity> getQueuedBuildJobs() {
log.debug("REST request to get the queued build jobs");
List buildJobQueue = localCIBuildJobQueueService.getQueuedJobs();
@@ -67,7 +67,6 @@ public ResponseEntity> getQueuedBuildJobs() {
* @return the running build jobs
*/
@GetMapping("running-jobs")
- @EnforceAdmin
public ResponseEntity> getRunningBuildJobs() {
log.debug("REST request to get the running build jobs");
List runningBuildJobs = localCIBuildJobQueueService.getProcessingJobs();
@@ -80,7 +79,6 @@ public ResponseEntity> getRunningBuildJobs() {
* @return list of build agents information
*/
@GetMapping("build-agents")
- @EnforceAdmin
public ResponseEntity> getBuildAgentSummary() {
log.debug("REST request to get information on available build agents");
List buildAgentSummary = localCIBuildJobQueueService.getBuildAgentInformationWithoutRecentBuildJobs();
@@ -94,7 +92,6 @@ public ResponseEntity> getBuildAgentSummary() {
* @return the build agent information
*/
@GetMapping("build-agent")
- @EnforceAdmin
public ResponseEntity getBuildAgentDetails(@RequestParam String agentName) {
log.debug("REST request to get information on build agent {}", agentName);
BuildAgentInformation buildAgentDetails = localCIBuildJobQueueService.getBuildAgentInformation().stream().filter(agent -> agent.name().equals(agentName)).findFirst()
@@ -109,7 +106,6 @@ public ResponseEntity getBuildAgentDetails(@RequestParam
* @return the ResponseEntity with the result of the cancellation
*/
@DeleteMapping("cancel-job/{buildJobId}")
- @EnforceAdmin
public ResponseEntity cancelBuildJob(@PathVariable String buildJobId) {
log.debug("REST request to cancel the build job with id {}", buildJobId);
// Call the cancelBuildJob method in LocalCIBuildJobManagementService
@@ -124,7 +120,6 @@ public ResponseEntity cancelBuildJob(@PathVariable String buildJobId) {
* @return the ResponseEntity with the result of the cancellation
*/
@DeleteMapping("cancel-all-queued-jobs")
- @EnforceAdmin
public ResponseEntity cancelAllQueuedBuildJobs() {
log.debug("REST request to cancel all queued build jobs");
// Call the cancelAllQueuedBuildJobs method in LocalCIBuildJobManagementService
@@ -139,7 +134,6 @@ public ResponseEntity cancelAllQueuedBuildJobs() {
* @return the ResponseEntity with the result of the cancellation
*/
@DeleteMapping("cancel-all-running-jobs")
- @EnforceAdmin
public ResponseEntity cancelAllRunningBuildJobs() {
log.debug("REST request to cancel all running build jobs");
// Call the cancelAllRunningBuildJobs method in LocalCIBuildJobManagementService
@@ -155,7 +149,6 @@ public ResponseEntity cancelAllRunningBuildJobs() {
* @return the ResponseEntity with the result of the cancellation
*/
@DeleteMapping("cancel-all-running-jobs-for-agent")
- @EnforceAdmin
public ResponseEntity cancelAllRunningBuildJobsForAgent(@RequestParam String agentName) {
log.debug("REST request to cancel all running build jobs for agent {}", agentName);
// Call the cancelAllRunningBuildJobsForAgent method in LocalCIBuildJobManagementService
@@ -171,7 +164,6 @@ public ResponseEntity cancelAllRunningBuildJobsForAgent(@RequestParam Stri
* @return the page of finished build jobs
*/
@GetMapping("finished-jobs")
- @EnforceAdmin
public ResponseEntity> getFinishedBuildJobs(FinishedBuildJobPageableSearchDTO search) {
log.debug("REST request to get a page of finished build jobs with build status {}, build agent address {}, start date {} and end date {}", search.buildStatus(),
search.buildAgentAddress(), search.startDate(), search.endDate());
@@ -190,7 +182,6 @@ public ResponseEntity> getFinishedBuildJobs(FinishedBu
* @return the build job statistics
*/
@GetMapping("build-job-statistics")
- @EnforceAdmin
public ResponseEntity getBuildJobStatistics(@RequestParam(required = false, defaultValue = "7") int span) {
log.debug("REST request to get the build job statistics");
List buildJobResultCountDtos = buildJobRepository.getBuildJobsResultsStatistics(ZonedDateTime.now().minusDays(span), null);
diff --git a/src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminCourseResource.java b/src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminCourseResource.java
index a75b2e2d4a0a..9cdcc9486f52 100644
--- a/src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminCourseResource.java
+++ b/src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminCourseResource.java
@@ -48,6 +48,7 @@
* REST controller for managing Course.
*/
@Profile(PROFILE_CORE)
+@EnforceAdmin
@RestController
@RequestMapping("api/admin/")
public class AdminCourseResource {
@@ -90,7 +91,6 @@ public AdminCourseResource(UserRepository userRepository, CourseService courseSe
* @return the list of groups (the user has access to)
*/
@GetMapping("courses/groups")
- @EnforceAdmin
public ResponseEntity> getAllGroupsForAllCourses() {
log.debug("REST request to get all Groups for all Courses");
List courses = courseRepository.findAll();
@@ -113,7 +113,6 @@ public ResponseEntity> getAllGroupsForAllCourses() {
* @throws URISyntaxException if the Location URI syntax is incorrect
*/
@PostMapping(value = "courses", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
- @EnforceAdmin
public ResponseEntity createCourse(@RequestPart Course course, @RequestPart(required = false) MultipartFile file) throws URISyntaxException {
log.debug("REST request to save Course : {}", course);
if (course.getId() != null) {
@@ -167,7 +166,6 @@ public ResponseEntity createCourse(@RequestPart Course course, @RequestP
* @return the ResponseEntity with status 200 (OK)
*/
@DeleteMapping("courses/{courseId}")
- @EnforceAdmin
public ResponseEntity deleteCourse(@PathVariable long courseId) {
log.info("REST request to delete Course : {}", courseId);
Course course = courseRepository.findByIdWithExercisesAndLecturesAndLectureUnitsAndCompetenciesElseThrow(courseId);
diff --git a/src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminDataExportResource.java b/src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminDataExportResource.java
index 0e1f17de42c1..6547fd7ef57a 100644
--- a/src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminDataExportResource.java
+++ b/src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminDataExportResource.java
@@ -17,6 +17,7 @@
* REST controller for requesting data exports for another user as admin.
*/
@Profile(PROFILE_CORE)
+@EnforceAdmin
@RestController
@RequestMapping("api/admin/")
public class AdminDataExportResource {
@@ -34,7 +35,6 @@ public AdminDataExportResource(DataExportService dataExportService) {
* @return the ResponseEntity with status 200 (OK) and with body a DTO containing the id, the state and the request date of the data export
*/
@PostMapping("data-exports/{login}")
- @EnforceAdmin
public ResponseEntity requestDataExportForUser(@PathVariable String login) {
return ResponseEntity.ok(dataExportService.requestDataExportForUserAsAdmin(login));
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/core/web/admin/FeatureToggleResource.java b/src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminFeatureToggleResource.java
similarity index 91%
rename from src/main/java/de/tum/cit/aet/artemis/core/web/admin/FeatureToggleResource.java
rename to src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminFeatureToggleResource.java
index 84a58f7918aa..e2d24720efbd 100644
--- a/src/main/java/de/tum/cit/aet/artemis/core/web/admin/FeatureToggleResource.java
+++ b/src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminFeatureToggleResource.java
@@ -18,13 +18,14 @@
import de.tum.cit.aet.artemis.core.service.feature.FeatureToggleService;
@Profile(PROFILE_CORE)
+@EnforceAdmin
@RestController
@RequestMapping("api/admin/")
-public class FeatureToggleResource {
+public class AdminFeatureToggleResource {
private final FeatureToggleService featureToggleService;
- public FeatureToggleResource(FeatureToggleService featureToggleService) {
+ public AdminFeatureToggleResource(FeatureToggleService featureToggleService) {
this.featureToggleService = featureToggleService;
}
@@ -36,7 +37,6 @@ public FeatureToggleResource(FeatureToggleService featureToggleService) {
* @see FeatureToggleService
*/
@PutMapping("feature-toggle")
- @EnforceAdmin
public ResponseEntity> toggleFeatures(@RequestBody Map features) {
featureToggleService.updateFeatureToggles(features);
diff --git a/src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminImprintResource.java b/src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminImprintResource.java
index 1e705926232c..58c99393679a 100644
--- a/src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminImprintResource.java
+++ b/src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminImprintResource.java
@@ -22,6 +22,7 @@
* REST controller for editing the imprint as an admin.
*/
@Profile(PROFILE_CORE)
+@EnforceAdmin
@RestController
@RequestMapping("api/admin/")
public class AdminImprintResource {
@@ -40,7 +41,6 @@ public AdminImprintResource(LegalDocumentService legalDocumentService) {
* @return the ResponseEntity with status 200 (OK) and with body the imprint with the given language
*/
@GetMapping("imprint-for-update")
- @EnforceAdmin
public ResponseEntity getImprintForUpdate(@RequestParam("language") String language) {
if (!Language.isValidShortName(language)) {
throw new BadRequestException("Language not supported");
@@ -55,7 +55,6 @@ public ResponseEntity getImprintForUpdate(@RequestParam("language")
* @return the ResponseEntity with status 200 (OK) and with body the updated imprint
*/
@PutMapping("imprint")
- @EnforceAdmin
public ResponseEntity updateImprint(@RequestBody ImprintDTO imprint) {
return ResponseEntity.ok(legalDocumentService.updateImprint(imprint));
}
diff --git a/src/main/java/de/tum/cit/aet/artemis/core/web/admin/LogResource.java b/src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminLogResource.java
similarity index 96%
rename from src/main/java/de/tum/cit/aet/artemis/core/web/admin/LogResource.java
rename to src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminLogResource.java
index 375deea352f6..a0855aa92929 100644
--- a/src/main/java/de/tum/cit/aet/artemis/core/web/admin/LogResource.java
+++ b/src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminLogResource.java
@@ -23,9 +23,10 @@
* Controller for view and managing Log Level at runtime.
*/
@Profile(PROFILE_CORE)
+@EnforceAdmin
@RestController
@RequestMapping("api/admin/")
-public class LogResource {
+public class AdminLogResource {
/**
* GET logs -- Gets the current log levels.
@@ -33,7 +34,6 @@ public class LogResource {
* @return A list of all loggers with their log level
*/
@GetMapping("logs")
- @EnforceAdmin
public ResponseEntity> getList() {
LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
return ResponseEntity.ok(context.getLoggerList().stream().map(LoggerVM::new).toList());
@@ -46,7 +46,6 @@ public ResponseEntity> getList() {
* @return The updated logger
*/
@PutMapping("logs")
- @EnforceAdmin
public ResponseEntity changeLevel(@RequestBody LoggerVM jsonLogger) {
LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
Logger logger = context.getLogger(jsonLogger.getName());
diff --git a/src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminOrganizationResource.java b/src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminOrganizationResource.java
index 75d3719b9c6e..c62673b6178f 100644
--- a/src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminOrganizationResource.java
+++ b/src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminOrganizationResource.java
@@ -36,6 +36,7 @@
* REST controller for administrating the Organization entities
*/
@Profile(PROFILE_CORE)
+@EnforceAdmin
@RestController
@RequestMapping("api/admin/")
public class AdminOrganizationResource {
@@ -72,7 +73,6 @@ public AdminOrganizationResource(OrganizationService organizationService, Organi
* @return empty ResponseEntity with status 200 (OK), or 404 (Not Found) otherwise
*/
@PostMapping("organizations/{organizationId}/courses/{courseId}")
- @EnforceAdmin
public ResponseEntity addCourseToOrganization(@PathVariable Long courseId, @PathVariable Long organizationId) {
log.debug("REST request to add course to organization : {}", organizationId);
Organization organization = organizationRepository.findByIdElseThrow(organizationId);
@@ -90,7 +90,6 @@ public ResponseEntity addCourseToOrganization(@PathVariable Long courseId,
* @return empty ResponseEntity with status 200 (OK), or 404 (Not Found) otherwise
*/
@DeleteMapping("organizations/{organizationId}/courses/{courseId}")
- @EnforceAdmin
public ResponseEntity removeCourseFromOrganization(@PathVariable Long courseId, @PathVariable Long organizationId) {
Organization organization = organizationRepository.findByIdElseThrow(organizationId);
courseRepository.removeOrganizationFromCourse(courseId, organization);
@@ -107,7 +106,6 @@ public ResponseEntity removeCourseFromOrganization(@PathVariable Long cour
* @return empty ResponseEntity with status 200 (OK), or 404 (Not Found) otherwise
*/
@PostMapping("organizations/{organizationId}/users/{userLogin}")
- @EnforceAdmin
public ResponseEntity addUserToOrganization(@PathVariable String userLogin, @PathVariable Long organizationId) {
User user = userRepository.getUserByLoginElseThrow(userLogin);
Organization organization = organizationRepository.findByIdElseThrow(organizationId);
@@ -128,7 +126,6 @@ public ResponseEntity addUserToOrganization(@PathVariable String userLogin
* @return empty ResponseEntity with status 200 (OK), or 404 (Not Found) otherwise
*/
@DeleteMapping("organizations/{organizationId}/users/{userLogin}")
- @EnforceAdmin
public ResponseEntity removeUserFromOrganization(@PathVariable String userLogin, @PathVariable Long organizationId) {
log.debug("REST request to remove course to organization : {}", organizationId);
User user = userRepository.getUserByLoginElseThrow(userLogin);
@@ -145,7 +142,6 @@ public ResponseEntity removeUserFromOrganization(@PathVariable String user
* @return the ResponseEntity containing the added organization with status 200 (OK), or 404 (Not Found) otherwise
*/
@PostMapping("organizations")
- @EnforceAdmin
public ResponseEntity addOrganization(@RequestBody Organization organization) {
log.debug("REST request to add new organization : {}", organization);
Organization created = organizationService.add(organization);
@@ -161,7 +157,6 @@ public ResponseEntity addOrganization(@RequestBody Organization or
* @return the ResponseEntity containing the updated organization with status 200 (OK), or 404 (Not Found) otherwise
*/
@PutMapping("organizations/{organizationId}")
- @EnforceAdmin
public ResponseEntity updateOrganization(@PathVariable Long organizationId, @RequestBody Organization organization) {
log.debug("REST request to update organization : {}", organization);
if (organization.getId() == null) {
@@ -182,7 +177,6 @@ public ResponseEntity updateOrganization(@PathVariable Long organi
* @return empty ResponseEntity with status 200 (OK), or 404 (Not Found) otherwise
*/
@DeleteMapping("organizations/{organizationId}")
- @EnforceAdmin
public ResponseEntity deleteOrganization(@PathVariable Long organizationId) {
log.debug("REST request to delete organization : {}", organizationId);
organizationService.deleteOrganization(organizationId);
@@ -195,7 +189,6 @@ public ResponseEntity deleteOrganization(@PathVariable Long organizationId
* @return ResponseEntity containing a list of all organizations with status 200 (OK)
*/
@GetMapping("organizations")
- @EnforceAdmin
public ResponseEntity> getAllOrganizations() {
log.debug("REST request to get all organizations");
// TODO: we should avoid findAll() and instead load batches of organizations
@@ -210,7 +203,6 @@ public ResponseEntity> getAllOrganizations() {
* @return ResponseEntity containing a map containing the numbers of users and courses
*/
@GetMapping("organizations/{organizationId}/count")
- @EnforceAdmin
public ResponseEntity getNumberOfUsersAndCoursesByOrganization(@PathVariable long organizationId) {
log.debug("REST request to get number of users and courses of organization : {}", organizationId);
@@ -227,7 +219,6 @@ public ResponseEntity getNumberOfUsersAndCoursesByOrganiza
* containing their relative numbers of users and courses
*/
@GetMapping("organizations/count-all")
- @EnforceAdmin
public ResponseEntity> getNumberOfUsersAndCoursesOfAllOrganizations() {
log.debug("REST request to get number of users and courses of all organizations");
@@ -250,7 +241,6 @@ public ResponseEntity> getNumberOfUsersAndCoursesOfAl
* if exists, else with status 404 (Not Found)
*/
@GetMapping("organizations/{organizationId}")
- @EnforceAdmin
public ResponseEntity