Backend: Fix container images management in the webui
- Update image list template to use ShortID instead of full ID - Reorganize handler files
- commit
- fb6df0a092fc226d94e4e90b3e17a459036e88f2
- author
- bamen · · 2024-08-28 12:38 UTC
- committer
- bamen · · 2024-08-28 12:43 UTC
- parent
- bb4151a
- signature
- unsigned
7 files · +43 -23
R internal/httpserve/handler/adminroutes.go → internal/httpserve/handler/admin-view.go +0 -0 renamed, 100% similar
renamed, 100% similar
R internal/httpserve/handler/clientendpoins.go → internal/httpserve/handler/cli-endpoints.go +0 -0 renamed, 100% similar
renamed, 100% similar
M internal/httpserve/handler/containers.go +0 -1
| @@ -135,7 +135,6 @@ func ImageManagerDelete(c echo.Context, a *server.App) error { | |||
| 135 | 135 | ShortID := c.Param("ID") | |
| 136 | 136 | ||
| 137 | 137 | imageID, exists := safelyInteractWithIDMap(Fetch, ShortID) | |
| 138 | - | ||
| 139 | 138 | if !exists { | |
| 140 | 139 | return c.String(http.StatusBadRequest, "Invalid ShortImgID") | |
| 141 | 140 | } | |
| @@ -135,7 +135,6 @@ func ImageManagerDelete(c echo.Context, a *server.App) error { | |||||
| 135 | ShortID := c.Param("ID") | 135 | ShortID := c.Param("ID") | ||
| 136 | 136 | ||||
| 137 | imageID, exists := safelyInteractWithIDMap(Fetch, ShortID) | 137 | imageID, exists := safelyInteractWithIDMap(Fetch, ShortID) | ||
| 138 | - | ||||
| 139 | if !exists { | 138 | if !exists { | ||
| 140 | return c.String(http.StatusBadRequest, "Invalid ShortImgID") | 139 | return c.String(http.StatusBadRequest, "Invalid ShortImgID") | ||
| 141 | } | 140 | } | ||
R internal/httpserve/handler/uploadcontainerimage.go → internal/httpserve/handler/upload-image.go +0 -0 renamed, 100% similar
renamed, 100% similar
M internal/templating/models/html/fragments/imagelist.gohtml +13 -13
| @@ -22,9 +22,9 @@ | |||
| 22 | 22 | {{ | |
| 23 | 23 | range.Images | |
| 24 | 24 | }} | |
| 25 | - | <tr id="img-{{.ID}}" hx-ext="response-targets" class=" hover:bg-slate-100"> | |
| 25 | + | <tr id="img-{{.ShortID}}" hx-ext="response-targets" class=" hover:bg-slate-100"> | |
| 26 | 26 | <td> | |
| 27 | - | <span title="{{.ID}}">{{.Name}}</span> | |
| 27 | + | <span title="{{.ShortID}}">{{.Name}}</span> | |
| 28 | 28 | </td> | |
| 29 | 29 | <td> | |
| 30 | 30 | <span title="Image creation date">{{.CreatedStr}}</span> | |
| @@ -33,22 +33,22 @@ | |||
| 33 | 33 | <td align="right"> | |
| 34 | 34 | ||
| 35 | 35 | <button | |
| 36 | - | id="add-button-img-{{.ID}}" | |
| 37 | - | hx-get="/htmx/create-container/{{.ID}}" | |
| 38 | - | hx-target="#create-container-{{.ID}}" | |
| 39 | - | hx-target-*="#error-message-div-{{.ID}}" | |
| 36 | + | id="add-button-img-{{.ShortID}}" | |
| 37 | + | hx-get="/htmx/create-container/{{.ShortID}}" | |
| 38 | + | hx-target="#create-container-{{.ShortID}}" | |
| 39 | + | hx-target-*="#error-message-div-{{.ShortID}}" | |
| 40 | 40 | hx-swap="innerHTML" | |
| 41 | 41 | class="py-2 px-4" | |
| 42 | - | _="on click toggle between .visible and .hidden on #create-container-{{.ID}} then add .hidden to #upload-image" | |
| 42 | + | _="on click toggle between .visible and .hidden on #create-container-{{.ShortID}} then add .hidden to #upload-image" | |
| 43 | 43 | > | |
| 44 | 44 | <span title="Deploy a container using this image" class="iconf text-xl text-blue-600 hover:text-gordonmascot-hblue"></span> | |
| 45 | 45 | </button> | |
| 46 | 46 | ||
| 47 | 47 | <button | |
| 48 | - | id="remove-button-img-{{.ID}}" | |
| 49 | - | hx-delete="/htmx/image-manager/delete/{{.ID}}" | |
| 50 | - | hx-target="#img-{{.ID}}" | |
| 51 | - | hx-target-*="#error-message-div-{{.ID}}" | |
| 48 | + | id="remove-button-img-{{.ShortID}}" | |
| 49 | + | hx-delete="/htmx/image-manager/delete/{{.ShortID}}" | |
| 50 | + | hx-target="#img-{{.ShortID}}" | |
| 51 | + | hx-target-*="#error-message-div-{{.ShortID}}" | |
| 52 | 52 | hx-swap="innerHTML" | |
| 53 | 53 | hx-confirm="Are you sure you want to delete this container image?" | |
| 54 | 54 | class="py-2 px-4" | |
| @@ -59,8 +59,8 @@ | |||
| 59 | 59 | </tr> | |
| 60 | 60 | <t> | |
| 61 | 61 | <td colspan="4"> | |
| 62 | - | <div id="error-message-div-{{.ID}}" class="text-red-500"></div> | |
| 63 | - | <div class="create-container" id="create-container-{{.ID}}"></div> | |
| 62 | + | <div id="error-message-div-{{.ShortID}}" class="text-red-500"></div> | |
| 63 | + | <div class="create-container" id="create-container-{{.ShortID}}"></div> | |
| 64 | 64 | </td> | |
| 65 | 65 | </tr> | |
| 66 | 66 | {{ else }} | |
| @@ -22,9 +22,9 @@ | |||||
| 22 | {{ | 22 | {{ | ||
| 23 | range.Images | 23 | range.Images | ||
| 24 | }} | 24 | }} | ||
| 25 | - | <tr id="img-{{.ID}}" hx-ext="response-targets" class=" hover:bg-slate-100"> | 25 | + | <tr id="img-{{.ShortID}}" hx-ext="response-targets" class=" hover:bg-slate-100"> |
| 26 | <td> | 26 | <td> | ||
| 27 | - | <span title="{{.ID}}">{{.Name}}</span> | 27 | + | <span title="{{.ShortID}}">{{.Name}}</span> |
| 28 | </td> | 28 | </td> | ||
| 29 | <td> | 29 | <td> | ||
| 30 | <span title="Image creation date">{{.CreatedStr}}</span> | 30 | <span title="Image creation date">{{.CreatedStr}}</span> | ||
| @@ -33,22 +33,22 @@ | |||||
| 33 | <td align="right"> | 33 | <td align="right"> | ||
| 34 | 34 | ||||
| 35 | <button | 35 | <button | ||
| 36 | - | id="add-button-img-{{.ID}}" | 36 | + | id="add-button-img-{{.ShortID}}" |
| 37 | - | hx-get="/htmx/create-container/{{.ID}}" | 37 | + | hx-get="/htmx/create-container/{{.ShortID}}" |
| 38 | - | hx-target="#create-container-{{.ID}}" | 38 | + | hx-target="#create-container-{{.ShortID}}" |
| 39 | - | hx-target-*="#error-message-div-{{.ID}}" | 39 | + | hx-target-*="#error-message-div-{{.ShortID}}" |
| 40 | hx-swap="innerHTML" | 40 | hx-swap="innerHTML" | ||
| 41 | class="py-2 px-4" | 41 | class="py-2 px-4" | ||
| 42 | - | _="on click toggle between .visible and .hidden on #create-container-{{.ID}} then add .hidden to #upload-image" | 42 | + | _="on click toggle between .visible and .hidden on #create-container-{{.ShortID}} then add .hidden to #upload-image" |
| 43 | > | 43 | > | ||
| 44 | <span title="Deploy a container using this image" class="iconf text-xl text-blue-600 hover:text-gordonmascot-hblue"></span> | 44 | <span title="Deploy a container using this image" class="iconf text-xl text-blue-600 hover:text-gordonmascot-hblue"></span> | ||
| 45 | </button> | 45 | </button> | ||
| 46 | 46 | ||||
| 47 | <button | 47 | <button | ||
| 48 | - | id="remove-button-img-{{.ID}}" | 48 | + | id="remove-button-img-{{.ShortID}}" |
| 49 | - | hx-delete="/htmx/image-manager/delete/{{.ID}}" | 49 | + | hx-delete="/htmx/image-manager/delete/{{.ShortID}}" |
| 50 | - | hx-target="#img-{{.ID}}" | 50 | + | hx-target="#img-{{.ShortID}}" |
| 51 | - | hx-target-*="#error-message-div-{{.ID}}" | 51 | + | hx-target-*="#error-message-div-{{.ShortID}}" |
| 52 | hx-swap="innerHTML" | 52 | hx-swap="innerHTML" | ||
| 53 | hx-confirm="Are you sure you want to delete this container image?" | 53 | hx-confirm="Are you sure you want to delete this container image?" | ||
| 54 | class="py-2 px-4" | 54 | class="py-2 px-4" | ||
| @@ -59,8 +59,8 @@ | |||||
| 59 | </tr> | 59 | </tr> | ||
| 60 | <t> | 60 | <t> | ||
| 61 | <td colspan="4"> | 61 | <td colspan="4"> | ||
| 62 | - | <div id="error-message-div-{{.ID}}" class="text-red-500"></div> | 62 | + | <div id="error-message-div-{{.ShortID}}" class="text-red-500"></div> |
| 63 | - | <div class="create-container" id="create-container-{{.ID}}"></div> | 63 | + | <div class="create-container" id="create-container-{{.ShortID}}"></div> |
| 64 | </td> | 64 | </td> | ||
| 65 | </tr> | 65 | </tr> | ||
| 66 | {{ else }} | 66 | {{ else }} | ||
M internal/webui/public/assets/css/tailwind.css +29 -9
| @@ -6,7 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | 7 | /* Embeded path : assets/css/cutsom.css */ | |
| 8 | 8 | ||
| 9 | - | /*! tailwindcss v3.3.3 | MIT License | https://tailwindcss.com | |
| 9 | + | /*! tailwindcss v3.4.3 | MIT License | https://tailwindcss.com | |
| 10 | 10 | */ | |
| 11 | 11 | ||
| 12 | 12 | /* | |
| @@ -39,9 +39,11 @@ | |||
| 39 | 39 | 4. Use the user's configured `sans` font-family by default. | |
| 40 | 40 | 5. Use the user's configured `sans` font-feature-settings by default. | |
| 41 | 41 | 6. Use the user's configured `sans` font-variation-settings by default. | |
| 42 | + | 7. Disable tap highlights on iOS | |
| 42 | 43 | */ | |
| 43 | 44 | ||
| 44 | - | html { | |
| 45 | + | html, | |
| 46 | + | :host { | |
| 45 | 47 | line-height: 1.5; | |
| 46 | 48 | /* 1 */ | |
| 47 | 49 | -webkit-text-size-adjust: 100%; | |
| @@ -51,12 +53,14 @@ html { | |||
| 51 | 53 | -o-tab-size: 4; | |
| 52 | 54 | tab-size: 4; | |
| 53 | 55 | /* 3 */ | |
| 54 | - | font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; | |
| 56 | + | font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; | |
| 55 | 57 | /* 4 */ | |
| 56 | 58 | font-feature-settings: normal; | |
| 57 | 59 | /* 5 */ | |
| 58 | 60 | font-variation-settings: normal; | |
| 59 | 61 | /* 6 */ | |
| 62 | + | -webkit-tap-highlight-color: transparent; | |
| 63 | + | /* 7 */ | |
| 60 | 64 | } | |
| 61 | 65 | ||
| 62 | 66 | /* | |
| @@ -128,8 +132,10 @@ strong { | |||
| 128 | 132 | } | |
| 129 | 133 | ||
| 130 | 134 | /* | |
| 131 | - | 1. Use the user's configured `mono` font family by default. | |
| 132 | - | 2. Correct the odd `em` font sizing in all browsers. | |
| 135 | + | 1. Use the user's configured `mono` font-family by default. | |
| 136 | + | 2. Use the user's configured `mono` font-feature-settings by default. | |
| 137 | + | 3. Use the user's configured `mono` font-variation-settings by default. | |
| 138 | + | 4. Correct the odd `em` font sizing in all browsers. | |
| 133 | 139 | */ | |
| 134 | 140 | ||
| 135 | 141 | code, | |
| @@ -138,8 +144,12 @@ samp, | |||
| 138 | 144 | pre { | |
| 139 | 145 | font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; | |
| 140 | 146 | /* 1 */ | |
| 141 | - | font-size: 1em; | |
| 147 | + | font-feature-settings: normal; | |
| 142 | 148 | /* 2 */ | |
| 149 | + | font-variation-settings: normal; | |
| 150 | + | /* 3 */ | |
| 151 | + | font-size: 1em; | |
| 152 | + | /* 4 */ | |
| 143 | 153 | } | |
| 144 | 154 | ||
| 145 | 155 | /* | |
| @@ -208,6 +218,8 @@ textarea { | |||
| 208 | 218 | /* 1 */ | |
| 209 | 219 | line-height: inherit; | |
| 210 | 220 | /* 1 */ | |
| 221 | + | letter-spacing: inherit; | |
| 222 | + | /* 1 */ | |
| 211 | 223 | color: inherit; | |
| 212 | 224 | /* 1 */ | |
| 213 | 225 | margin: 0; | |
| @@ -231,9 +243,9 @@ select { | |||
| 231 | 243 | */ | |
| 232 | 244 | ||
| 233 | 245 | button, | |
| 234 | - | [type='button'], | |
| 235 | - | [type='reset'], | |
| 236 | - | [type='submit'] { | |
| 246 | + | input:where([type='button']), | |
| 247 | + | input:where([type='reset']), | |
| 248 | + | input:where([type='submit']) { | |
| 237 | 249 | -webkit-appearance: button; | |
| 238 | 250 | /* 1 */ | |
| 239 | 251 | background-color: transparent; | |
| @@ -489,6 +501,10 @@ video { | |||
| 489 | 501 | --tw-backdrop-opacity: ; | |
| 490 | 502 | --tw-backdrop-saturate: ; | |
| 491 | 503 | --tw-backdrop-sepia: ; | |
| 504 | + | --tw-contain-size: ; | |
| 505 | + | --tw-contain-layout: ; | |
| 506 | + | --tw-contain-paint: ; | |
| 507 | + | --tw-contain-style: ; | |
| 492 | 508 | } | |
| 493 | 509 | ||
| 494 | 510 | ::backdrop { | |
| @@ -539,6 +555,10 @@ video { | |||
| 539 | 555 | --tw-backdrop-opacity: ; | |
| 540 | 556 | --tw-backdrop-saturate: ; | |
| 541 | 557 | --tw-backdrop-sepia: ; | |
| 558 | + | --tw-contain-size: ; | |
| 559 | + | --tw-contain-layout: ; | |
| 560 | + | --tw-contain-paint: ; | |
| 561 | + | --tw-contain-style: ; | |
| 542 | 562 | } | |
| 543 | 563 | ||
| 544 | 564 | .container { | |
| @@ -6,7 +6,7 @@ | |||||
| 6 | 6 | ||||
| 7 | /* Embeded path : assets/css/cutsom.css */ | 7 | /* Embeded path : assets/css/cutsom.css */ | ||
| 8 | 8 | ||||
| 9 | - | /*! tailwindcss v3.3.3 | MIT License | https://tailwindcss.com | 9 | + | /*! tailwindcss v3.4.3 | MIT License | https://tailwindcss.com |
| 10 | */ | 10 | */ | ||
| 11 | 11 | ||||
| 12 | /* | 12 | /* | ||
| @@ -39,9 +39,11 @@ | |||||
| 39 | 4. Use the user's configured `sans` font-family by default. | 39 | 4. Use the user's configured `sans` font-family by default. | ||
| 40 | 5. Use the user's configured `sans` font-feature-settings by default. | 40 | 5. Use the user's configured `sans` font-feature-settings by default. | ||
| 41 | 6. Use the user's configured `sans` font-variation-settings by default. | 41 | 6. Use the user's configured `sans` font-variation-settings by default. | ||
| 42 | + | 7. Disable tap highlights on iOS | |||
| 42 | */ | 43 | */ | ||
| 43 | 44 | ||||
| 44 | - | html { | 45 | + | html, |
| 46 | + | :host { | |||
| 45 | line-height: 1.5; | 47 | line-height: 1.5; | ||
| 46 | /* 1 */ | 48 | /* 1 */ | ||
| 47 | -webkit-text-size-adjust: 100%; | 49 | -webkit-text-size-adjust: 100%; | ||
| @@ -51,12 +53,14 @@ html { | |||||
| 51 | -o-tab-size: 4; | 53 | -o-tab-size: 4; | ||
| 52 | tab-size: 4; | 54 | tab-size: 4; | ||
| 53 | /* 3 */ | 55 | /* 3 */ | ||
| 54 | - | font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; | 56 | + | font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; |
| 55 | /* 4 */ | 57 | /* 4 */ | ||
| 56 | font-feature-settings: normal; | 58 | font-feature-settings: normal; | ||
| 57 | /* 5 */ | 59 | /* 5 */ | ||
| 58 | font-variation-settings: normal; | 60 | font-variation-settings: normal; | ||
| 59 | /* 6 */ | 61 | /* 6 */ | ||
| 62 | + | -webkit-tap-highlight-color: transparent; | |||
| 63 | + | /* 7 */ | |||
| 60 | } | 64 | } | ||
| 61 | 65 | ||||
| 62 | /* | 66 | /* | ||
| @@ -128,8 +132,10 @@ strong { | |||||
| 128 | } | 132 | } | ||
| 129 | 133 | ||||
| 130 | /* | 134 | /* | ||
| 131 | - | 1. Use the user's configured `mono` font family by default. | 135 | + | 1. Use the user's configured `mono` font-family by default. |
| 132 | - | 2. Correct the odd `em` font sizing in all browsers. | 136 | + | 2. Use the user's configured `mono` font-feature-settings by default. |
| 137 | + | 3. Use the user's configured `mono` font-variation-settings by default. | |||
| 138 | + | 4. Correct the odd `em` font sizing in all browsers. | |||
| 133 | */ | 139 | */ | ||
| 134 | 140 | ||||
| 135 | code, | 141 | code, | ||
| @@ -138,8 +144,12 @@ samp, | |||||
| 138 | pre { | 144 | pre { | ||
| 139 | font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; | 145 | font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; | ||
| 140 | /* 1 */ | 146 | /* 1 */ | ||
| 141 | - | font-size: 1em; | 147 | + | font-feature-settings: normal; |
| 142 | /* 2 */ | 148 | /* 2 */ | ||
| 149 | + | font-variation-settings: normal; | |||
| 150 | + | /* 3 */ | |||
| 151 | + | font-size: 1em; | |||
| 152 | + | /* 4 */ | |||
| 143 | } | 153 | } | ||
| 144 | 154 | ||||
| 145 | /* | 155 | /* | ||
| @@ -208,6 +218,8 @@ textarea { | |||||
| 208 | /* 1 */ | 218 | /* 1 */ | ||
| 209 | line-height: inherit; | 219 | line-height: inherit; | ||
| 210 | /* 1 */ | 220 | /* 1 */ | ||
| 221 | + | letter-spacing: inherit; | |||
| 222 | + | /* 1 */ | |||
| 211 | color: inherit; | 223 | color: inherit; | ||
| 212 | /* 1 */ | 224 | /* 1 */ | ||
| 213 | margin: 0; | 225 | margin: 0; | ||
| @@ -231,9 +243,9 @@ select { | |||||
| 231 | */ | 243 | */ | ||
| 232 | 244 | ||||
| 233 | button, | 245 | button, | ||
| 234 | - | [type='button'], | 246 | + | input:where([type='button']), |
| 235 | - | [type='reset'], | 247 | + | input:where([type='reset']), |
| 236 | - | [type='submit'] { | 248 | + | input:where([type='submit']) { |
| 237 | -webkit-appearance: button; | 249 | -webkit-appearance: button; | ||
| 238 | /* 1 */ | 250 | /* 1 */ | ||
| 239 | background-color: transparent; | 251 | background-color: transparent; | ||
| @@ -489,6 +501,10 @@ video { | |||||
| 489 | --tw-backdrop-opacity: ; | 501 | --tw-backdrop-opacity: ; | ||
| 490 | --tw-backdrop-saturate: ; | 502 | --tw-backdrop-saturate: ; | ||
| 491 | --tw-backdrop-sepia: ; | 503 | --tw-backdrop-sepia: ; | ||
| 504 | + | --tw-contain-size: ; | |||
| 505 | + | --tw-contain-layout: ; | |||
| 506 | + | --tw-contain-paint: ; | |||
| 507 | + | --tw-contain-style: ; | |||
| 492 | } | 508 | } | ||
| 493 | 509 | ||||
| 494 | ::backdrop { | 510 | ::backdrop { | ||
| @@ -539,6 +555,10 @@ video { | |||||
| 539 | --tw-backdrop-opacity: ; | 555 | --tw-backdrop-opacity: ; | ||
| 540 | --tw-backdrop-saturate: ; | 556 | --tw-backdrop-saturate: ; | ||
| 541 | --tw-backdrop-sepia: ; | 557 | --tw-backdrop-sepia: ; | ||
| 558 | + | --tw-contain-size: ; | |||
| 559 | + | --tw-contain-layout: ; | |||
| 560 | + | --tw-contain-paint: ; | |||
| 561 | + | --tw-contain-style: ; | |||
| 542 | } | 562 | } | ||
| 543 | 563 | ||||
| 544 | .container { | 564 | .container { | ||
M package.json +1 -0
| @@ -10,6 +10,7 @@ | |||
| 10 | 10 | "dev:css": "tailwindcss -i internal/webui/public/assets/css/custom.css -o internal/webui/public/assets/css/tailwind.css --watch" | |
| 11 | 11 | }, | |
| 12 | 12 | "dependencies": { | |
| 13 | + | "caniuse-lite": "^1.0.30001653", | |
| 13 | 14 | "dotenv": "^16.4.5" | |
| 14 | 15 | } | |
| 15 | 16 | } | |
| @@ -10,6 +10,7 @@ | |||||
| 10 | "dev:css": "tailwindcss -i internal/webui/public/assets/css/custom.css -o internal/webui/public/assets/css/tailwind.css --watch" | 10 | "dev:css": "tailwindcss -i internal/webui/public/assets/css/custom.css -o internal/webui/public/assets/css/tailwind.css --watch" | ||
| 11 | }, | 11 | }, | ||
| 12 | "dependencies": { | 12 | "dependencies": { | ||
| 13 | + | "caniuse-lite": "^1.0.30001653", | |||
| 13 | "dotenv": "^16.4.5" | 14 | "dotenv": "^16.4.5" | ||
| 14 | } | 15 | } | ||
| 15 | } | 16 | } | ||