From 7d775fe26d52ea5f046253513e77a81be76727a2 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Mon, 31 Mar 2025 15:42:07 +0200 Subject: [PATCH 1/5] admin: New page to list forge link per theme and exercice --- admin/api/exercice.go | 66 +++++++++++++++++++++ admin/static.go | 3 + admin/static/js/app.js | 14 +++++ admin/static/views/exercices-forgelink.html | 14 +++++ admin/static/views/theme-list.html | 1 + 5 files changed, 98 insertions(+) create mode 100644 admin/static/views/exercices-forgelink.html diff --git a/admin/api/exercice.go b/admin/api/exercice.go index c2554269..2c196153 100644 --- a/admin/api/exercice.go +++ b/admin/api/exercice.go @@ -20,6 +20,7 @@ import ( func declareGlobalExercicesRoutes(router *gin.RouterGroup) { router.GET("/resolutions.json", exportResolutionMovies) router.GET("/exercices_stats.json", getExercicesStats) + router.GET("/exercices_forge_bindings.json", getExercicesForgeLinks) router.GET("/tags", listTags) } @@ -487,6 +488,71 @@ func getExercicesStats(c *gin.Context) { c.JSON(http.StatusOK, ret) } +type themeForgeBinding struct { + ThemeName string `json:"name"` + ThemePath string `json:"path"` + ForgeLink string `json:"forge_link"` + Exercices []exerciceForgeBinding `json:"exercices"` +} + +type exerciceForgeBinding struct { + ExerciceName string `json:"name"` + ExercicePath string `json:"path"` + ForgeLink string `json:"forge_link"` +} + +func getExercicesForgeLinks(c *gin.Context) { + themes, err := fic.GetThemesExtended() + if err != nil { + log.Println("Unable to listThemes:", err.Error()) + c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "An error occurs during themes listing."}) + return + } + + fli, ok := sync.GlobalImporter.(sync.ForgeLinkedImporter) + if !ok { + c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": "Current importer is not compatible with ForgeLinkedImporter"}) + return + } + + ret := []themeForgeBinding{} + for _, theme := range themes { + exercices, err := theme.GetExercices() + if err != nil { + log.Println("Unable to listExercices:", err.Error()) + c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "An error occurs during exercice listing."}) + return + } + + var exlinks []exerciceForgeBinding + for _, exercice := range exercices { + var forgelink string + if u, _ := fli.GetExerciceLink(exercice); u != nil { + forgelink = u.String() + } + + exlinks = append(exlinks, exerciceForgeBinding{ + ExerciceName: exercice.Title, + ExercicePath: exercice.Path, + ForgeLink: forgelink, + }) + } + + var forgelink string + if u, _ := fli.GetThemeLink(theme); u != nil { + forgelink = u.String() + } + ret = append(ret, themeForgeBinding{ + ThemeName: theme.Name, + ThemePath: theme.Path, + ForgeLink: forgelink, + Exercices: exlinks, + }) + } + + c.JSON(http.StatusOK, ret) +} + func AssigneeCookieHandler(c *gin.Context) { myassignee, err := c.Cookie("myassignee") if err != nil { diff --git a/admin/static.go b/admin/static.go index 82772993..23ad6da6 100644 --- a/admin/static.go +++ b/admin/static.go @@ -80,6 +80,9 @@ func declareStaticRoutes(router *gin.RouterGroup, cfg *settings.Settings, baseUR router.GET("/files", func(c *gin.Context) { serveIndex(c) }) + router.GET("/forge-links", func(c *gin.Context) { + serveIndex(c) + }) router.GET("/public/*_", func(c *gin.Context) { serveIndex(c) }) diff --git a/admin/static/js/app.js b/admin/static/js/app.js index 915de87d..9b6fc13b 100644 --- a/admin/static/js/app.js +++ b/admin/static/js/app.js @@ -49,6 +49,10 @@ angular.module("FICApp", ["ngRoute", "ngResource", "ngSanitize"]) controller: "ExerciceController", templateUrl: "views/exercice-resolution.html" }) + .when("/forge-links", { + controller: "ForgeLinksController", + templateUrl: "views/exercices-forgelink.html" + }) .when("/tags", { controller: "TagsListController", templateUrl: "views/tags.html" @@ -2189,6 +2193,16 @@ angular.module("FICApp") }; }) + .controller("ForgeLinksController", function ($scope, $http) { + $http({ + url: "api/exercices_forge_bindings.json", + }).then(function (response) { + $scope.forge_links = response.data; + }, function (response) { + $scope.addToast('danger', 'An error occurs when generating exercice forge links: ', response.data.errmsg); + }); + }) + .controller("ExerciceTagsController", function ($scope, ExerciceTags, $routeParams, $rootScope) { $scope.tags = ExerciceTags.query({ exerciceId: $routeParams.exerciceId }); diff --git a/admin/static/views/exercices-forgelink.html b/admin/static/views/exercices-forgelink.html new file mode 100644 index 00000000..4f6dd8df --- /dev/null +++ b/admin/static/views/exercices-forgelink.html @@ -0,0 +1,14 @@ +

Accès rapide aux exercices

+ +
+

+ + {{ theme.name }} +  : {{ theme.path }} +

+ +
diff --git a/admin/static/views/theme-list.html b/admin/static/views/theme-list.html index aed9b4ca..c5a292f7 100644 --- a/admin/static/views/theme-list.html +++ b/admin/static/views/theme-list.html @@ -2,6 +2,7 @@ Thèmes + Liens d'accès à la forge

From 56efb4ae9422e8ca2ed0addba8d570b851e33fb2 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Mon, 31 Mar 2025 15:42:23 +0200 Subject: [PATCH 2/5] sync: Fix non-trimed git links --- admin/static/views/exercices-forgelink.html | 4 +--- admin/sync/importer_gitbin.go | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/admin/static/views/exercices-forgelink.html b/admin/static/views/exercices-forgelink.html index 4f6dd8df..2588ebc4 100644 --- a/admin/static/views/exercices-forgelink.html +++ b/admin/static/views/exercices-forgelink.html @@ -2,9 +2,7 @@

- - {{ theme.name }} -  : {{ theme.path }} + {{ theme.name }} : {{ theme.path }}

  • diff --git a/admin/sync/importer_gitbin.go b/admin/sync/importer_gitbin.go index 4b4b0683..7d511265 100644 --- a/admin/sync/importer_gitbin.go +++ b/admin/sync/importer_gitbin.go @@ -205,7 +205,7 @@ func (i GitImporter) GetThemeLink(th *fic.Theme) (u *url.URL, err error) { return } - u.Path = path.Join(u.Path, "-", "tree", i.Branch, strings.TrimPrefix(th.Path, prefix)) + u.Path = path.Join(u.Path, "-", "tree", i.Branch, strings.TrimPrefix("/"+th.Path, prefix)) return } @@ -241,7 +241,7 @@ func (i GitImporter) GetExerciceLink(e *fic.Exercice) (u *url.URL, err error) { return } - u.Path = path.Join(u.Path, "-", "tree", i.Branch, strings.TrimPrefix(e.Path, prefix)) + u.Path = path.Join(u.Path, "-", "tree", i.Branch, strings.TrimPrefix("/"+e.Path, prefix)) return } From ee544dfe1ce0f07a4a75c7d92f10e864b5c470c3 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 31 Mar 2025 16:18:05 +0000 Subject: [PATCH 3/5] chore(deps): update dependency eslint-plugin-svelte to v3.4.1 --- frontend/fic/package-lock.json | 6 +++--- qa/ui/package-lock.json | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/frontend/fic/package-lock.json b/frontend/fic/package-lock.json index d08b942c..3fe17ca0 100644 --- a/frontend/fic/package-lock.json +++ b/frontend/fic/package-lock.json @@ -1898,9 +1898,9 @@ } }, "node_modules/eslint-plugin-svelte": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-3.4.0.tgz", - "integrity": "sha512-L0eX0W6M0YhIUhWRlOAaornY1lIz6xRSVKVJuiRovMM5wHUBQZmefwJRR0y+sqR0CHtJpFmxYiQbw3UaO8h5KA==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-3.4.1.tgz", + "integrity": "sha512-wgbRwN/6FampBBiIuuLSmp4QRqmuHuexbuRJwx+kqzsxKOhakU8o8sVgGhsf/bQiZkOmWF/5Mrj2CHmVMwY+YQ==", "dev": true, "license": "MIT", "dependencies": { diff --git a/qa/ui/package-lock.json b/qa/ui/package-lock.json index 775181b2..34b13a07 100644 --- a/qa/ui/package-lock.json +++ b/qa/ui/package-lock.json @@ -1528,9 +1528,9 @@ } }, "node_modules/eslint-plugin-svelte": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-3.4.0.tgz", - "integrity": "sha512-L0eX0W6M0YhIUhWRlOAaornY1lIz6xRSVKVJuiRovMM5wHUBQZmefwJRR0y+sqR0CHtJpFmxYiQbw3UaO8h5KA==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-3.4.1.tgz", + "integrity": "sha512-wgbRwN/6FampBBiIuuLSmp4QRqmuHuexbuRJwx+kqzsxKOhakU8o8sVgGhsf/bQiZkOmWF/5Mrj2CHmVMwY+YQ==", "dev": true, "license": "MIT", "dependencies": { From e6f6686a39a686724683e2c883b6d064a01b251b Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Tue, 1 Apr 2025 12:47:58 +0200 Subject: [PATCH 4/5] admin: Fix team stats --- admin/static/views/team-stats.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admin/static/views/team-stats.html b/admin/static/views/team-stats.html index 7c264afb..4bb75eb1 100644 --- a/admin/static/views/team-stats.html +++ b/admin/static/views/team-stats.html @@ -37,7 +37,7 @@
From 1c3f641fb3e0436238a27cb993bee20c2c663e48 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Tue, 1 Apr 2025 11:18:05 +0000 Subject: [PATCH 5/5] chore(deps): update dependency eslint-plugin-svelte to v3.4.1 --- frontend/fic/package-lock.json | 6 +++--- qa/ui/package-lock.json | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/frontend/fic/package-lock.json b/frontend/fic/package-lock.json index d08b942c..3fe17ca0 100644 --- a/frontend/fic/package-lock.json +++ b/frontend/fic/package-lock.json @@ -1898,9 +1898,9 @@ } }, "node_modules/eslint-plugin-svelte": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-3.4.0.tgz", - "integrity": "sha512-L0eX0W6M0YhIUhWRlOAaornY1lIz6xRSVKVJuiRovMM5wHUBQZmefwJRR0y+sqR0CHtJpFmxYiQbw3UaO8h5KA==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-3.4.1.tgz", + "integrity": "sha512-wgbRwN/6FampBBiIuuLSmp4QRqmuHuexbuRJwx+kqzsxKOhakU8o8sVgGhsf/bQiZkOmWF/5Mrj2CHmVMwY+YQ==", "dev": true, "license": "MIT", "dependencies": { diff --git a/qa/ui/package-lock.json b/qa/ui/package-lock.json index 775181b2..34b13a07 100644 --- a/qa/ui/package-lock.json +++ b/qa/ui/package-lock.json @@ -1528,9 +1528,9 @@ } }, "node_modules/eslint-plugin-svelte": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-3.4.0.tgz", - "integrity": "sha512-L0eX0W6M0YhIUhWRlOAaornY1lIz6xRSVKVJuiRovMM5wHUBQZmefwJRR0y+sqR0CHtJpFmxYiQbw3UaO8h5KA==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-3.4.1.tgz", + "integrity": "sha512-wgbRwN/6FampBBiIuuLSmp4QRqmuHuexbuRJwx+kqzsxKOhakU8o8sVgGhsf/bQiZkOmWF/5Mrj2CHmVMwY+YQ==", "dev": true, "license": "MIT", "dependencies": {