You've already forked woodpecker
							
							
				mirror of
				https://github.com/woodpecker-ci/woodpecker.git
				synced 2025-10-30 23:27:39 +02:00 
			
		
		
		
	Migrate from Windi to Tailwind (#4614)
Co-authored-by: Robert Kaussow <mail@thegeeklab.de>
This commit is contained in:
		| @@ -112,7 +112,7 @@ vscode: | ||||
|     - 'EditorConfig.EditorConfig' | ||||
|     - 'dbaeumer.vscode-eslint' | ||||
|     - 'esbenp.prettier-vscode' | ||||
|     - 'voorjaar.windicss-intellisense' | ||||
|     - 'bradlc.vscode-tailwindcss' | ||||
|     - 'Vue.volar' | ||||
|     - 'redhat.vscode-yaml' | ||||
|     - 'davidanson.vscode-markdownlint' | ||||
|   | ||||
							
								
								
									
										2
									
								
								.vscode/extensions.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.vscode/extensions.json
									
									
									
									
										vendored
									
									
								
							| @@ -5,7 +5,7 @@ | ||||
|     "EditorConfig.EditorConfig", | ||||
|     "dbaeumer.vscode-eslint", | ||||
|     "esbenp.prettier-vscode", | ||||
|     "voorjaar.windicss-intellisense", | ||||
|     "bradlc.vscode-tailwindcss", | ||||
|     "Vue.volar", | ||||
|     "redhat.vscode-yaml", | ||||
|     "davidanson.vscode-markdownlint", | ||||
|   | ||||
| @@ -6,6 +6,7 @@ ignore-from-file: | ||||
|   - .gitignore | ||||
|   - server/store/datastore/migration/test-files/.gitignore | ||||
|   - web/.gitignore | ||||
|   - web/.yamlignore | ||||
|  | ||||
| rules: | ||||
|   line-length: disable | ||||
|   | ||||
| @@ -21,9 +21,9 @@ The following list contains some tools and frameworks used by the Woodpecker UI. | ||||
|   - use `setup` and composition api | ||||
|   - place (re-usable) components in `web/src/components/` | ||||
|   - views should have a route in `web/src/router.ts` and are located in `web/src/views/` | ||||
| - [Windicss](https://windicss.org/) (similar to Tailwind) | ||||
|   - use Windicss classes where possible | ||||
|   - if needed extend the Windicss config to use new classes | ||||
| - [Tailwind CSS](https://tailwindcss.com/) | ||||
|   - use Tailwind classes where possible | ||||
|   - if needed extend the Tailwind config to use new classes | ||||
|   - classes are sorted following the [prettier tailwind sort plugin](https://tailwindcss.com/blog/automatic-class-sorting-with-prettier) | ||||
| - [Vite](https://vitejs.dev/) (similar to Webpack) | ||||
| - [Typescript](https://www.typescriptlang.org/) | ||||
|   | ||||
							
								
								
									
										1
									
								
								web/.yamlignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								web/.yamlignore
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| .pnpm-lock.yaml | ||||
| @@ -20,21 +20,28 @@ | ||||
|   "dependencies": { | ||||
|     "@kyvg/vue3-notification": "^3.4.1", | ||||
|     "@mdi/js": "^7.4.47", | ||||
|     "@vueuse/core": "^12.2.0", | ||||
|     "@tailwindcss/postcss": "4.0.0-beta.8", | ||||
|     "@tailwindcss/typography": "^0.5.15", | ||||
|     "@tailwindcss/vite": "4.0.0-beta.8", | ||||
|     "@vueuse/core": "^12.3.0", | ||||
|     "ansi_up": "^6.0.2", | ||||
|     "autoprefixer": "^10.4.20", | ||||
|     "dompurify": "^3.2.3", | ||||
|     "fuse.js": "^7.0.0", | ||||
|     "js-base64": "^3.7.7", | ||||
|     "lodash": "^4.17.21", | ||||
|     "marked": "^15.0.4", | ||||
|     "marked": "^15.0.5", | ||||
|     "node-emoji": "^2.2.0", | ||||
|     "pinia": "^2.3.0", | ||||
|     "postcss": "^8.4.49", | ||||
|     "prettier-plugin-tailwindcss": "^0.6.9", | ||||
|     "prismjs": "^1.29.0", | ||||
|     "semver": "^7.6.3", | ||||
|     "simple-icons": "^14.0.0", | ||||
|     "simple-icons": "^14.1.0", | ||||
|     "tailwindcss": "^3.4.17", | ||||
|     "textlint": "^14.4.2", | ||||
|     "vue": "^3.5.13", | ||||
|     "vue-i18n": "^11.0.0", | ||||
|     "vue-i18n": "^11.0.1", | ||||
|     "vue-router": "^4.5.0" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
| @@ -42,10 +49,10 @@ | ||||
|     "@eslint/js": "^9.17.0", | ||||
|     "@ianvs/prettier-plugin-sort-imports": "^4.4.0", | ||||
|     "@intlify/eslint-plugin-vue-i18n": "3.2.0", | ||||
|     "@intlify/unplugin-vue-i18n": "^6.0.2", | ||||
|     "@intlify/unplugin-vue-i18n": "^6.0.3", | ||||
|     "@types/eslint__js": "^8.42.3", | ||||
|     "@types/lodash": "^4.17.13", | ||||
|     "@types/node": "^22.10.2", | ||||
|     "@types/lodash": "^4.17.14", | ||||
|     "@types/node": "^22.10.5", | ||||
|     "@types/prismjs": "^1.26.5", | ||||
|     "@types/semver": "^7.5.8", | ||||
|     "@types/tinycolor2": "^1.4.6", | ||||
| @@ -58,14 +65,13 @@ | ||||
|     "jsdom": "^25.0.1", | ||||
|     "prettier": "^3.4.2", | ||||
|     "tinycolor2": "^1.6.0", | ||||
|     "ts-node": "^10.9.2", | ||||
|     "typescript": "5.7.2", | ||||
|     "vite": "^6.0.5", | ||||
|     "vite": "^6.0.7", | ||||
|     "vite-plugin-prismjs": "^0.0.11", | ||||
|     "vite-plugin-windicss": "^1.9.4", | ||||
|     "vite-svg-loader": "^5.1.0", | ||||
|     "vitest": "^2.1.8", | ||||
|     "vue-tsc": "^2.2.0", | ||||
|     "windicss": "^3.5.6" | ||||
|     "vue-tsc": "^2.2.0" | ||||
|   }, | ||||
|   "pnpm": { | ||||
|     "overrides": { | ||||
|   | ||||
							
								
								
									
										2312
									
								
								web/pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2312
									
								
								web/pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										7
									
								
								web/postcss.config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								web/postcss.config.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| // postcss.config.js | ||||
| export default { | ||||
|   plugins: { | ||||
|     tailwindcss: {}, | ||||
|     autoprefixer: {}, | ||||
|   }, | ||||
| }; | ||||
| @@ -1,5 +1,5 @@ | ||||
| <template> | ||||
|   <div class="app bg-wp-background-200 dark:bg-wp-background-100 m-auto flex h-full w-full flex-col"> | ||||
|   <div class="app m-auto flex h-full w-full flex-col bg-wp-background-200 dark:bg-wp-background-100"> | ||||
|     <router-view v-if="blank" /> | ||||
|     <template v-else> | ||||
|       <Navbar /> | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| <template> | ||||
|   <div v-if="stats" class="flex justify-center"> | ||||
|     <div | ||||
|       class="border-wp-background-300 bg-wp-background-200 dark:bg-wp-background-100 text-wp-text-100 w-full rounded-md border px-5 py-5" | ||||
|       class="w-full rounded-md border border-wp-background-300 bg-wp-background-200 px-5 py-5 text-wp-text-100 dark:bg-wp-background-100" | ||||
|     > | ||||
|       <div class="flex w-full"> | ||||
|         <h3 class="flex-1 text-lg font-semibold uppercase leading-tight"> | ||||
| @@ -33,7 +33,7 @@ | ||||
|               v-for="(item, index) in data" | ||||
|               :key="item.key" | ||||
|               class="px-4 sm:w-full md:w-1/4" | ||||
|               :class="{ 'border-gray-300 md:border-l dark:border-gray-600': index !== 0 }" | ||||
|               :class="{ 'border-gray-300 dark:border-gray-600 md:border-l': index !== 0 }" | ||||
|             > | ||||
|               <div class="overflow-hidden text-ellipsis whitespace-nowrap text-sm"> | ||||
|                 <span class="mr-1 inline-block h-2 w-2 rounded-full align-middle" :class="`${item.color}`"> </span> | ||||
|   | ||||
| @@ -1,9 +1,9 @@ | ||||
| <template> | ||||
|   <div v-if="!props.loading" class="text-wp-text-100 space-y-4"> | ||||
|   <div v-if="!props.loading" class="space-y-4 text-wp-text-100"> | ||||
|     <ListItem | ||||
|       v-for="agent in props.agents" | ||||
|       :key="agent.id" | ||||
|       class="!bg-wp-background-200 !dark:bg-wp-background-100 items-center" | ||||
|       class="items-center !bg-wp-background-200 dark:!bg-wp-background-100" | ||||
|     > | ||||
|       <span>{{ agent.name || `Agent ${agent.id}` }}</span> | ||||
|       <span class="ml-auto"> | ||||
| @@ -30,7 +30,7 @@ | ||||
|       <IconButton | ||||
|         icon="trash" | ||||
|         :title="$t('admin.settings.agents.delete_agent')" | ||||
|         class="hover:text-wp-error-100 ml-2 h-8 w-8" | ||||
|         class="ml-2 h-8 w-8 hover:text-wp-error-100" | ||||
|         :is-loading="props.isDeleting" | ||||
|         @click="$emit('delete', agent)" | ||||
|       /> | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| <template> | ||||
|   <span class="inline-flex text-xs font-medium"> | ||||
|     <span | ||||
|       class="bg-wp-state-neutral-100 border-wp-state-neutral-100 flex items-center rounded-l-full border-2 py-0.5 pl-2 pr-1 text-gray-300" | ||||
|       class="flex items-center rounded-l-full border-2 border-wp-state-neutral-100 bg-wp-state-neutral-100 py-0.5 pl-2 pr-1 text-gray-300" | ||||
|       :class="{ | ||||
|         'rounded-r-full pr-2': value === undefined, | ||||
|       }" | ||||
| @@ -10,7 +10,7 @@ | ||||
|     </span> | ||||
|     <span | ||||
|       v-if="value !== undefined" | ||||
|       class="border-wp-state-neutral-100 flex items-center rounded-r-full border-2 py-0.5 pl-1 pr-2" | ||||
|       class="flex items-center rounded-r-full border-2 border-wp-state-neutral-100 py-0.5 pl-1 pr-2" | ||||
|     > | ||||
|       {{ value }} | ||||
|     </span> | ||||
|   | ||||
| @@ -4,11 +4,11 @@ | ||||
|     v-bind="btnAttrs" | ||||
|     class="relative flex flex-shrink-0 cursor-pointer items-center overflow-hidden whitespace-nowrap rounded-md border px-2 py-1 shadow-sm transition-all duration-150 disabled:cursor-not-allowed disabled:opacity-50" | ||||
|     :class="{ | ||||
|       'bg-wp-control-neutral-100 hover:bg-wp-control-neutral-200 border-wp-control-neutral-300 text-wp-text-100': | ||||
|       'border-wp-control-neutral-300 bg-wp-control-neutral-100 text-wp-text-100 hover:bg-wp-control-neutral-200': | ||||
|         color === 'gray', | ||||
|       'bg-wp-control-ok-100 hover:bg-wp-control-ok-200 border-wp-control-ok-300 text-white': color === 'green', | ||||
|       'bg-wp-control-info-100 hover:bg-wp-control-info-200 border-wp-control-info-300 text-white': color === 'blue', | ||||
|       'bg-wp-error-100 dark:bg-wp-error-200 hover:bg-wp-error-300 border-wp-error-300 text-white': color === 'red', | ||||
|       'border-wp-control-ok-300 bg-wp-control-ok-100 text-white hover:bg-wp-control-ok-200': color === 'green', | ||||
|       'border-wp-control-info-300 bg-wp-control-info-100 text-white hover:bg-wp-control-info-200': color === 'blue', | ||||
|       'border-wp-error-300 bg-wp-error-100 text-white hover:bg-wp-error-200': color === 'red', | ||||
|       ...passedClasses, | ||||
|     }" | ||||
|     :title="title" | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| <template> | ||||
|   <span | ||||
|     class="bg-wp-background-300 dark:bg-wp-background-100 text-wp-text-100 inline-block min-w-5 rounded-full px-1.5 py-0.5 text-center text-xs font-bold leading-4" | ||||
|     class="inline-block min-w-5 rounded-full bg-wp-background-300 px-1.5 py-0.5 text-center text-xs font-bold leading-4 text-wp-text-100 dark:bg-wp-background-100" | ||||
|   > | ||||
|     {{ value }} | ||||
|   </span> | ||||
|   | ||||
| @@ -3,7 +3,7 @@ | ||||
|     :href="`${docsUrl}`" | ||||
|     :title="$t('documentation_for', { topic })" | ||||
|     target="_blank" | ||||
|     class="text-wp-link-100 hover:text-wp-link-200 cursor-pointer" | ||||
|     class="cursor-pointer text-wp-link-100 hover:text-wp-link-200" | ||||
|   > | ||||
|     <Icon name="question" class="!h-5 !w-5" /> | ||||
|   </a> | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| <template> | ||||
|   <div | ||||
|     class="border-wp-error-300 dark:border-wp-error-300 bg-wp-error-100 dark:bg-wp-error-200 border-l-6 flex items-center gap-2 rounded-md border border-solid p-2 text-white" | ||||
|     class="flex items-center gap-2 rounded-md border border-l-4 border-solid border-wp-error-200 bg-wp-error-100 p-2 text-white" | ||||
|   > | ||||
|     <Icon v-if="!textOnly" name="alert" /> | ||||
|     <slot> | ||||
|   | ||||
| @@ -39,7 +39,7 @@ | ||||
|   <SvgIcon v-else-if="name === 'heal'" :path="mdiWrenchCogOutline" size="1.3rem" /> | ||||
|   <SvgIcon v-else-if="name === 'turn-off'" :path="mdiPower" size="1.3rem" /> | ||||
|   <SvgIcon v-else-if="name === 'chevron-right'" :path="mdiChevronRight" size="1.3rem" /> | ||||
|   <SvgIcon v-else-if="name === 'close'" :path="mdiCloseCircle" size="1.3rem" /> | ||||
|   <SvgIcon v-else-if="name === 'close'" :path="mdiClose" size="1.3rem" /> | ||||
|   <SvgIcon v-else-if="name === 'edit'" :path="mdiPencilOutline" size="1.3rem" /> | ||||
|   <SvgIcon v-else-if="name === 'download'" :path="mdiDownloadOutline" size="1.3rem" /> | ||||
|   <SvgIcon v-else-if="name === 'stopwatch'" :path="mdiAlarm" size="1.3rem" /> | ||||
| @@ -89,6 +89,7 @@ import { | ||||
|   mdiCheckCircle, | ||||
|   mdiChevronRight, | ||||
|   mdiClockTimeEightOutline, | ||||
|   mdiClose, | ||||
|   mdiCloseCircle, | ||||
|   mdiCog, | ||||
|   mdiCogOutline, | ||||
|   | ||||
| @@ -2,9 +2,9 @@ | ||||
|   <component | ||||
|     :is="to ? 'router-link' : clickable ? 'button' : 'div'" | ||||
|     :to="to" | ||||
|     class="bg-wp-background-100 border-wp-background-400 dark:bg-wp-background-200 flex w-full overflow-hidden rounded-md border p-4" | ||||
|     class="flex w-full overflow-hidden rounded-md border border-wp-background-400 bg-wp-background-100 p-4 dark:bg-wp-background-200" | ||||
|     :class="{ | ||||
|       'hover:bg-wp-background-300 dark:hover:bg-wp-background-300 cursor-pointer hover:shadow-md': clickable || to, | ||||
|       'cursor-pointer hover:bg-wp-background-300 hover:shadow-md dark:hover:bg-wp-background-300': clickable || to, | ||||
|     }" | ||||
|   > | ||||
|     <slot /> | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| <template> | ||||
|   <div | ||||
|     class="border-l-6 border-wp-hint-warn-200 bg-wp-hint-warn-100 flex items-center gap-4 rounded-md border border-solid p-4 font-bold text-gray-700" | ||||
|     class="flex items-center gap-4 rounded-md border border-l-4 border-solid border-wp-hint-warn-200 bg-wp-hint-warn-100 p-4 font-bold text-gray-700" | ||||
|   > | ||||
|     <Icon v-if="!textOnly" name="alert" class="flex-shrink-0" /> | ||||
|     <slot> | ||||
|   | ||||
| @@ -3,13 +3,13 @@ | ||||
|     <input | ||||
|       :id="`checkbox-${id}`" | ||||
|       type="checkbox" | ||||
|       class="border-wp-control-neutral-200 checked:border-wp-control-ok-200 focus-visible:border-wp-control-neutral-300 checked:focus-visible:border-wp-control-ok-300 bg-wp-control-neutral-100 checked:bg-wp-control-ok-200 checkbox relative h-5 w-5 flex-shrink-0 cursor-pointer rounded-md border transition-colors duration-150" | ||||
|       class="checkbox relative h-5 w-5 flex-shrink-0 cursor-pointer rounded-md border border-wp-control-neutral-200 bg-wp-control-neutral-100 transition-colors duration-150 checked:border-wp-control-ok-200 checked:bg-wp-control-ok-200 focus-visible:border-wp-control-neutral-300 checked:focus-visible:border-wp-control-ok-300" | ||||
|       :checked="innerValue" | ||||
|       @click="innerValue = !innerValue" | ||||
|     /> | ||||
|     <div class="ml-4 flex flex-col"> | ||||
|       <label class="text-wp-text-100 cursor-pointer" :for="`checkbox-${id}`">{{ label }}</label> | ||||
|       <span v-if="description" class="text-wp-text-alt-100 text-sm">{{ description }}</span> | ||||
|       <label class="cursor-pointer text-wp-text-100" :for="`checkbox-${id}`">{{ label }}</label> | ||||
|       <span v-if="description" class="text-sm text-wp-text-alt-100">{{ description }}</span> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| <template> | ||||
|   <div class="mb-4 mt-2 flex flex-col"> | ||||
|     <div class="mb-2 flex items-center"> | ||||
|       <label class="text-wp-text-100 font-bold" :for="id" v-bind="$attrs">{{ label }}</label> | ||||
|       <label class="font-bold text-wp-text-100" :for="id" v-bind="$attrs">{{ label }}</label> | ||||
|       <DocsLink v-if="docsUrl" :topic="label" :url="docsUrl" class="ml-2" /> | ||||
|       <slot v-else-if="$slots.titleActions" name="titleActions" /> | ||||
|     </div> | ||||
|     <slot :id="id" /> | ||||
|     <div v-if="$slots.description" class="text-wp-text-alt-100 ml-1 mt-1"> | ||||
|     <div v-if="$slots.description" class="ml-1 mt-1 text-wp-text-alt-100"> | ||||
|       <slot name="description" /> | ||||
|     </div> | ||||
|   </div> | ||||
|   | ||||
| @@ -3,14 +3,14 @@ | ||||
|     <input | ||||
|       :id="`radio-${id}-${option.value}`" | ||||
|       type="radio" | ||||
|       class="border-wp-control-neutral-200 checked:border-wp-control-ok-200 focus-visible:border-wp-control-neutral-300 checked:focus-visible:border-wp-control-ok-300 bg-wp-control-neutral-100 checked:bg-wp-control-ok-200 radio relative h-5 w-5 flex-shrink-0 cursor-pointer rounded-full border" | ||||
|       class="radio relative h-5 w-5 flex-shrink-0 cursor-pointer rounded-full border border-wp-control-neutral-200 bg-wp-control-neutral-100 checked:border-wp-control-ok-200 checked:bg-wp-control-ok-200 focus-visible:border-wp-control-neutral-300 checked:focus-visible:border-wp-control-ok-300" | ||||
|       :value="option.value" | ||||
|       :checked="innerValue?.includes(option.value)" | ||||
|       @click="innerValue = option.value" | ||||
|     /> | ||||
|     <div class="ml-4 flex flex-col"> | ||||
|       <label class="text-wp-text-100 cursor-pointer" :for="`radio-${id}-${option.value}`">{{ option.text }}</label> | ||||
|       <span v-if="option.description" class="text-wp-text-alt-100 text-sm">{{ option.description }}</span> | ||||
|       <label class="cursor-pointer text-wp-text-100" :for="`radio-${id}-${option.value}`">{{ option.text }}</label> | ||||
|       <span v-if="option.description" class="text-sm text-wp-text-alt-100">{{ option.description }}</span> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| <template> | ||||
|   <select | ||||
|     v-model="innerValue" | ||||
|     class="bg-wp-control-neutral-100 text-wp-text-100 border-wp-control-neutral-200 w-full rounded-md border px-2 py-1" | ||||
|     class="w-full rounded-md border border-wp-control-neutral-200 bg-wp-control-neutral-100 px-2 py-1 text-wp-text-100" | ||||
|   > | ||||
|     <option v-if="placeholder" value="" class="hidden">{{ placeholder }}</option> | ||||
|     <option v-for="option in options" :key="option.value" :value="option.value" class="text-wp-text-100"> | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|   <input | ||||
|     v-if="lines === 1" | ||||
|     v-model="innerValue" | ||||
|     class="border-wp-control-neutral-200 bg-wp-background-100 focus-visible:border-wp-control-neutral-300 w-full rounded-md border px-2 py-1 focus-visible:outline-none" | ||||
|     class="w-full rounded-md border border-wp-control-neutral-200 bg-wp-background-100 px-2 py-1 focus-visible:border-wp-control-neutral-300 focus-visible:outline-none" | ||||
|     :class="{ 'opacity-50': disabled }" | ||||
|     :disabled="disabled" | ||||
|     :type="type" | ||||
| @@ -11,7 +11,7 @@ | ||||
|   <textarea | ||||
|     v-else | ||||
|     v-model="innerValue" | ||||
|     class="border-wp-control-neutral-200 bg-wp-background-100 focus-visible:border-wp-control-neutral-300 w-full rounded-md border px-2 py-1 focus-visible:outline-none" | ||||
|     class="w-full rounded-md border border-wp-control-neutral-200 bg-wp-background-100 px-2 py-1 focus-visible:border-wp-control-neutral-300 focus-visible:outline-none" | ||||
|     :class="{ 'opacity-50': disabled }" | ||||
|     :disabled="disabled" | ||||
|     :placeholder="placeholder" | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| <template> | ||||
|   <div | ||||
|     class="bg-wp-background-100 dark:bg-wp-background-200 border-wp-background-400 w-full overflow-hidden rounded-md border shadow" | ||||
|     class="w-full overflow-hidden rounded-md border border-wp-background-400 bg-wp-background-100 shadow dark:bg-wp-background-200" | ||||
|   > | ||||
|     <component | ||||
|       :is="collapsable ? 'button' : 'div'" | ||||
|       v-if="title" | ||||
|       type="button" | ||||
|       class="bg-wp-background-400 text-wp-text-100 flex w-full gap-2 px-4 py-2 font-bold" | ||||
|       class="flex w-full gap-2 bg-wp-background-400 px-4 py-2 font-bold text-wp-text-100" | ||||
|       @click="_collapsed = !_collapsed" | ||||
|     > | ||||
|       <Icon | ||||
| @@ -22,9 +22,9 @@ | ||||
|         'max-h-auto': !collapsed, | ||||
|         'max-h-0': collapsed, | ||||
|       }" | ||||
|       class="transition-height overflow-hidden duration-150" | ||||
|       class="overflow-hidden transition-height duration-150" | ||||
|     > | ||||
|       <div class="text-wp-text-100 w-full p-4"> | ||||
|       <div class="w-full p-4 text-wp-text-100"> | ||||
|         <slot /> | ||||
|       </div> | ||||
|     </div> | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
|   <!-- overlay end --> | ||||
|   <div | ||||
|     v-if="open" | ||||
|     class="max-w-1/3 <md:max-w-4/5 max-h-3/5 z-1000 fixed left-1/2 top-1/2 flex -translate-x-1/2 -translate-y-1/2 transform print:hidden" | ||||
|     class="max-w-1/3 max-w-4/5 md:max-h-3/5 z-1000 fixed left-1/2 top-1/2 flex -translate-x-1/2 -translate-y-1/2 transform print:hidden" | ||||
|   > | ||||
|     <div class="shadow-all m-auto flex h-auto flex-col"> | ||||
|       <slot /> | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| <template> | ||||
|   <Panel> | ||||
|     <div class="dark:border-wp-background-100 mb-4 flex flex-col justify-center border-b pb-4"> | ||||
|     <div class="mb-4 flex flex-col justify-center border-b pb-4 dark:border-wp-background-100"> | ||||
|       <div class="flex items-center justify-between"> | ||||
|         <h1 class="text-wp-text-100 flex items-center gap-1 text-xl"> | ||||
|         <h1 class="flex items-center gap-1 text-xl text-wp-text-100"> | ||||
|           {{ title }} | ||||
|           <DocsLink v-if="docsUrl" :topic="title" :url="docsUrl" /> | ||||
|         </h1> | ||||
| @@ -10,7 +10,7 @@ | ||||
|       </div> | ||||
|  | ||||
|       <div class="flex flex-wrap items-center justify-between gap-x-4 gap-y-2"> | ||||
|         <p v-if="description" class="text-wp-text-alt-100 text-sm">{{ description }}</p> | ||||
|         <p v-if="description" class="text-sm text-wp-text-alt-100">{{ description }}</p> | ||||
|         <div v-if="$slots.headerActions"> | ||||
|           <slot name="headerActions" /> | ||||
|         </div> | ||||
|   | ||||
| @@ -41,7 +41,7 @@ onMounted(async () => { | ||||
|   overflow: hidden; | ||||
| } | ||||
| .spinner::before { | ||||
|   @apply bg-wp-primary-200 dark:bg-wp-primary-300 absolute; | ||||
|   @apply absolute bg-wp-primary-200 dark:bg-wp-primary-300; | ||||
|   content: ''; | ||||
|   left: -50%; | ||||
|   top: -50%; | ||||
| @@ -55,7 +55,7 @@ onMounted(async () => { | ||||
|   animation: rotate 1.5s linear infinite; | ||||
| } | ||||
| .spinner::after { | ||||
|   @apply bg-wp-primary-200 dark:bg-wp-primary-300 absolute inset-0.5; | ||||
|   @apply absolute inset-0.5 bg-wp-primary-200 dark:bg-wp-primary-300; | ||||
|   /* | ||||
|   The nested border radius needs to be calculated correctly to look right: | ||||
|   https://www.30secondsofcode.org/css/s/nested-border-radius/ | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| <template> | ||||
|   <nav | ||||
|     class="border-wp-background-100 bg-wp-primary-200 dark:bg-wp-primary-300 text-neutral-content text-wp-primary-text-100 flex border-b p-4 font-bold" | ||||
|     class="text-neutral-content flex border-b border-wp-background-100 bg-wp-primary-200 p-4 font-bold text-wp-primary-text-100 dark:bg-wp-primary-300" | ||||
|   > | ||||
|     <div class="flex items-center space-x-2"> | ||||
|       <router-link :to="{ name: 'home' }" class="-my-2 flex flex-col px-2"> | ||||
| @@ -26,7 +26,7 @@ | ||||
|         :to="{ name: 'admin-settings' }" | ||||
|       > | ||||
|         <Icon name="settings" /> | ||||
|         <div v-if="version?.needsUpdate" class="bg-int-wp-error-100 absolute right-2 top-2 h-3 w-3 rounded-full" /> | ||||
|         <div v-if="version?.needsUpdate" class="absolute right-2 top-2 h-3 w-3 rounded-full bg-wp-error-100" /> | ||||
|       </IconButton> | ||||
|  | ||||
|       <ActivePipelines v-if="user" class="navbar-icon !p-1.5" /> | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|   <Popup :open="open" @close="$emit('close')"> | ||||
|     <Panel v-if="!loading"> | ||||
|       <form @submit.prevent="triggerDeployPipeline"> | ||||
|         <span class="text-wp-text-100 text-xl">{{ | ||||
|         <span class="text-xl text-wp-text-100">{{ | ||||
|           $t('repo.deploy_pipeline.title', { pipelineId: pipelineNumber }) | ||||
|         }}</span> | ||||
|         <InputField v-slot="{ id }" :label="$t('repo.deploy_pipeline.enter_target')"> | ||||
| @@ -12,7 +12,7 @@ | ||||
|           <TextField :id="id" v-model="payload.task" /> | ||||
|         </InputField> | ||||
|         <InputField v-slot="{ id }" :label="$t('repo.deploy_pipeline.variables.title')"> | ||||
|           <span class="text-wp-text-alt-100 mb-2 text-sm">{{ $t('repo.deploy_pipeline.variables.desc') }}</span> | ||||
|           <span class="mb-2 text-sm text-wp-text-alt-100">{{ $t('repo.deploy_pipeline.variables.desc') }}</span> | ||||
|           <KeyValueEditor | ||||
|             :id="id" | ||||
|             v-model="payload.variables" | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| <template> | ||||
|   <header | ||||
|     class="border-wp-background-400 dark:border-wp-background-100 bg-wp-background-100 dark:bg-wp-background-300 border-b-1 text-wp-text-100" | ||||
|     class="border-b border-wp-background-400 bg-wp-background-100 text-wp-text-100 dark:border-wp-background-100 dark:bg-wp-background-300" | ||||
|     :class="{ 'md:px-4': fullWidth }" | ||||
|   > | ||||
|     <Container :full-width="fullWidth" class="!py-0"> | ||||
| @@ -15,16 +15,16 @@ | ||||
|             v-if="goBack" | ||||
|             icon="back" | ||||
|             :title="$t('back')" | ||||
|             class="<md:hidden mr-2 h-8 w-8 flex-shrink-0 md:justify-between" | ||||
|             class="md:display-unset mr-2 hidden h-8 w-8 flex-shrink-0 md:justify-between" | ||||
|             @click="goBack" | ||||
|           /> | ||||
|           <h1 class="text-wp-text-100 flex min-w-0 items-center gap-x-2 text-xl"> | ||||
|           <h1 class="flex min-w-0 items-center gap-x-2 text-xl text-wp-text-100"> | ||||
|             <slot name="title" /> | ||||
|           </h1> | ||||
|         </div> | ||||
|         <TextField | ||||
|           v-if="searchBoxPresent" | ||||
|           class="<md:w-full <md:order-3 w-auto flex-grow" | ||||
|           class="order-3 w-full flex-grow md:order-none md:w-auto" | ||||
|           :aria-label="$t('search')" | ||||
|           :placeholder="$t('search')" | ||||
|           :model-value="search" | ||||
| @@ -42,7 +42,7 @@ | ||||
|       </div> | ||||
|  | ||||
|       <div v-if="enableTabs" class="flex flex-col py-2 md:flex-row md:items-center md:justify-between md:py-0"> | ||||
|         <Tabs class="<md:order-2" /> | ||||
|         <Tabs class="order-2 md:order-none" /> | ||||
|         <div v-if="$slots.headerActions" class="flex content-start md:justify-end"> | ||||
|           <slot name="tabActions" /> | ||||
|         </div> | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
|       :key="tab.title" | ||||
|       v-slot="{ isActive, isExactActive }" | ||||
|       :to="tab.to" | ||||
|       class="text-wp-text-100 flex w-full cursor-pointer items-center border-transparent py-1 md:w-auto md:border-b-2" | ||||
|       class="flex w-full cursor-pointer items-center border-transparent py-1 text-wp-text-100 md:w-auto md:border-b-2" | ||||
|       :active-class="tab.matchChildren ? '!border-wp-text-100' : ''" | ||||
|       :exact-active-class="tab.matchChildren ? '' : '!border-wp-text-100'" | ||||
|     > | ||||
| @@ -16,7 +16,7 @@ | ||||
|       /> | ||||
|       <Icon v-else name="blank" class="md:hidden" /> | ||||
|       <span | ||||
|         class="dark:hover:bg-wp-background-100 hover:bg-wp-background-200 flex w-full min-w-20 flex-row items-center gap-2 rounded-md px-2 py-1 md:justify-center" | ||||
|         class="flex w-full min-w-20 flex-row items-center gap-2 rounded-md px-2 py-1 hover:bg-wp-background-200 dark:hover:bg-wp-background-100 md:justify-center" | ||||
|       > | ||||
|         <Icon v-if="tab.icon" :name="tab.icon" :class="tab.iconClass" class="flex-shrink-0" /> | ||||
|         <span>{{ tab.title }}</span> | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| <template> | ||||
|   <div v-if="pipeline" class="text-wp-text-100 flex w-full"> | ||||
|   <div v-if="pipeline" class="flex w-full text-wp-text-100"> | ||||
|     <PipelineStatusIcon :status="pipeline.status" class="flex items-center" /> | ||||
|     <div class="ml-4 flex min-w-0 flex-col"> | ||||
|       <router-link | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|   <aside | ||||
|     v-if="isOpen" | ||||
|     ref="target" | ||||
|     class="bg-wp-background-100 dark:bg-wp-background-200 border-wp-background-400 z-50 flex flex-col items-center overflow-y-auto" | ||||
|     class="z-50 flex flex-col items-center overflow-y-auto border-wp-background-400 bg-wp-background-100 dark:bg-wp-background-200" | ||||
|     :aria-label="$t('pipeline_feed')" | ||||
|   > | ||||
|     <router-link | ||||
| @@ -12,12 +12,12 @@ | ||||
|         name: 'repo-pipeline', | ||||
|         params: { repoId: pipeline.repo_id, pipelineId: pipeline.number }, | ||||
|       }" | ||||
|       class="border-wp-background-400 hover:bg-wp-background-300 dark:hover:bg-wp-background-400 flex w-full border-b px-2 py-4 hover:shadow-sm" | ||||
|       class="flex w-full border-b border-wp-background-400 px-2 py-4 hover:bg-wp-background-300 hover:shadow-sm dark:hover:bg-wp-background-400" | ||||
|     > | ||||
|       <PipelineFeedItem :pipeline="pipeline" /> | ||||
|     </router-link> | ||||
|  | ||||
|     <span v-if="sortedPipelines.length === 0" class="text-wp-text-100 m-4">{{ $t('repo.pipeline.no_pipelines') }}</span> | ||||
|     <span v-if="sortedPipelines.length === 0" class="m-4 text-wp-text-100">{{ $t('repo.pipeline.no_pipelines') }}</span> | ||||
|   </aside> | ||||
| </template> | ||||
|  | ||||
|   | ||||
| @@ -1,9 +1,9 @@ | ||||
| <template> | ||||
|   <div class="text-wp-text-100 space-y-4"> | ||||
|   <div class="space-y-4 text-wp-text-100"> | ||||
|     <ListItem | ||||
|       v-for="registry in registries" | ||||
|       :key="registry.id" | ||||
|       class="!bg-wp-background-200 !dark:bg-wp-background-100 items-center" | ||||
|       class="items-center !bg-wp-background-200 dark:!bg-wp-background-100" | ||||
|     > | ||||
|       <span>{{ registry.address }}</span> | ||||
|       <IconButton | ||||
| @@ -15,7 +15,7 @@ | ||||
|       <IconButton | ||||
|         v-if="!registry.readonly" | ||||
|         icon="trash" | ||||
|         class="hover:text-wp-error-100 h-8 w-8" | ||||
|         class="h-8 w-8 hover:text-wp-error-100" | ||||
|         :is-loading="isDeleting" | ||||
|         :title="$t('registries.delete')" | ||||
|         @click="deleteRegistry(registry)" | ||||
|   | ||||
| @@ -2,11 +2,11 @@ | ||||
|   <router-link | ||||
|     v-if="repo" | ||||
|     :to="{ name: 'repo', params: { repoId: repo.id } }" | ||||
|     class="bg-wp-background-100 border-wp-background-400 dark:bg-wp-background-200 hover:bg-wp-background-300 dark:hover:bg-wp-background-300 flex cursor-pointer flex-col overflow-hidden rounded-md border p-4 hover:shadow-md" | ||||
|     class="flex cursor-pointer flex-col overflow-hidden rounded-md border border-wp-background-400 bg-wp-background-100 p-4 hover:bg-wp-background-300 hover:shadow-md dark:bg-wp-background-200 dark:hover:bg-wp-background-300" | ||||
|   > | ||||
|     <div class="grid grid-cols-[auto,1fr] items-center gap-y-4"> | ||||
|       <div class="text-wp-text-100 text-lg">{{ `${repo.owner} / ${repo.name}` }}</div> | ||||
|       <div class="text-wp-text-100 ml-auto"> | ||||
|       <div class="text-lg text-wp-text-100">{{ `${repo.owner} / ${repo.name}` }}</div> | ||||
|       <div class="ml-auto text-wp-text-100"> | ||||
|         <div | ||||
|           v-if="repo.visibility === RepoVisibility.Private" | ||||
|           :title="`${$t('repo.visibility.visibility')}: ${$t(`repo.visibility.private.private`)}`" | ||||
| @@ -21,7 +21,7 @@ | ||||
|         </div> | ||||
|       </div> | ||||
|  | ||||
|       <div class="text-wp-text-100 col-span-2 flex w-full gap-x-4"> | ||||
|       <div class="col-span-2 flex w-full gap-x-4 text-wp-text-100"> | ||||
|         <template v-if="lastPipeline"> | ||||
|           <div class="flex min-w-0 flex-1 items-center gap-x-1"> | ||||
|             <PipelineStatusIcon v-if="lastPipeline" :status="lastPipeline.status" /> | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| <template> | ||||
|   <ListItem v-if="pipeline" class="w-full p-0"> | ||||
|   <ListItem v-if="pipeline" class="w-full !p-0"> | ||||
|     <div class="flex w-11 items-center"> | ||||
|       <div | ||||
|         class="h-full w-3" | ||||
| @@ -17,19 +17,19 @@ | ||||
|       </div> | ||||
|     </div> | ||||
|  | ||||
|     <div class="<md:flex-wrap flex min-w-0 flex-grow px-4 py-2"> | ||||
|       <div class="<md:hidden flex flex-shrink-0 items-center"> | ||||
|     <div class="flex min-w-0 flex-grow flex-wrap px-4 py-2 md:flex-nowrap"> | ||||
|       <div class="hidden flex-shrink-0 items-center md:flex"> | ||||
|         <Icon v-if="pipeline.event === 'cron'" name="stopwatch" class="text-wp-text-100" /> | ||||
|         <img v-else class="w-6 rounded-md" :src="pipeline.author_avatar" /> | ||||
|       </div> | ||||
|  | ||||
|       <div class="flex w-full min-w-0 items-center md:mx-4 md:w-auto"> | ||||
|         <!-- eslint-disable-next-line @intlify/vue-i18n/no-raw-text --> | ||||
|         <span class="text-wp-text-alt-100 <md:hidden">#{{ pipeline.number }}</span> | ||||
|         <span class="md:display-unset hidden text-wp-text-alt-100">#{{ pipeline.number }}</span> | ||||
|         <!-- eslint-disable-next-line @intlify/vue-i18n/no-raw-text --> | ||||
|         <span class="text-wp-text-alt-100 <md:hidden mx-2">-</span> | ||||
|         <span class="md:display-unset mx-2 hidden text-wp-text-alt-100">-</span> | ||||
|         <span | ||||
|           class="text-wp-text-100 <md:underline overflow-hidden overflow-ellipsis whitespace-nowrap" | ||||
|           class="overflow-hidden overflow-ellipsis whitespace-nowrap text-wp-text-100 underline md:no-underline" | ||||
|           :title="message" | ||||
|         > | ||||
|           {{ shortMessage }} | ||||
| @@ -37,7 +37,7 @@ | ||||
|       </div> | ||||
|  | ||||
|       <div | ||||
|         class="text-wp-text-100 grid w-full flex-shrink-0 grid-flow-col grid-cols-2 grid-rows-2 gap-x-4 gap-y-2 py-2 md:ml-auto md:w-96" | ||||
|         class="grid w-full flex-shrink-0 grid-flow-col grid-cols-2 grid-rows-2 gap-x-4 gap-y-2 py-2 text-wp-text-100 md:ml-auto md:w-96" | ||||
|       > | ||||
|         <div class="flex min-w-0 items-center space-x-2"> | ||||
|           <span :title="pipelineEventTitle"> | ||||
|   | ||||
| @@ -1,13 +1,15 @@ | ||||
| <template> | ||||
|   <div v-if="pipeline" class="flex flex-col pt-10 md:pt-0"> | ||||
|     <div | ||||
|       class="code-box-log !md:rounded-md flex flex-grow flex-col overflow-hidden !rounded-none !p-0 shadow md:mt-0" | ||||
|       class="code-box-log flex flex-grow flex-col overflow-hidden !p-0 shadow md:mt-0 md:!rounded-md" | ||||
|       @mouseover="showActions = true" | ||||
|       @mouseleave="showActions = false" | ||||
|     > | ||||
|       <div class="<md:fixed <md:top-0 <md:left-0 bg-wp-code-100 flex w-full flex-row items-center px-4 py-2"> | ||||
|         <span class="text-wp-code-text-alt-100 text-base font-bold"> | ||||
|           <span class="<md:hidden">{{ $t('repo.pipeline.log_title') }}</span> | ||||
|       <div | ||||
|         class="fixed left-0 top-0 flex w-full flex-row items-center bg-wp-code-100 px-4 py-2 md:relative md:left-auto md:top-auto" | ||||
|       > | ||||
|         <span class="text-base font-bold text-wp-code-text-alt-100"> | ||||
|           <span class="md:display-unset hidden">{{ $t('repo.pipeline.log_title') }}</span> | ||||
|           <span class="md:hidden">{{ step?.name }}</span> | ||||
|         </span> | ||||
|  | ||||
| @@ -16,14 +18,14 @@ | ||||
|             v-if="step?.finished !== undefined && hasLogs" | ||||
|             :is-loading="downloadInProgress" | ||||
|             :title="$t('repo.pipeline.actions.log_download')" | ||||
|             class="!hover:bg-white !hover:bg-opacity-10" | ||||
|             class="hover:!bg-white hover:!bg-opacity-10" | ||||
|             icon="download" | ||||
|             @click="download" | ||||
|           /> | ||||
|           <IconButton | ||||
|             v-if="step?.finished !== undefined && hasLogs && hasPushPermission" | ||||
|             :title="$t('repo.pipeline.actions.log_delete')" | ||||
|             class="!hover:bg-white !hover:bg-opacity-10" | ||||
|             class="hover:!bg-white hover:!bg-opacity-10" | ||||
|             icon="trash" | ||||
|             @click="deleteLogs" | ||||
|           /> | ||||
| @@ -32,12 +34,12 @@ | ||||
|             :title=" | ||||
|               autoScroll ? $t('repo.pipeline.actions.log_auto_scroll_off') : $t('repo.pipeline.actions.log_auto_scroll') | ||||
|             " | ||||
|             class="!hover:bg-white !hover:bg-opacity-10" | ||||
|             class="hover:!bg-white hover:!bg-opacity-10" | ||||
|             :icon="autoScroll ? 'auto-scroll' : 'auto-scroll-off'" | ||||
|             @click="autoScroll = !autoScroll" | ||||
|           /> | ||||
|           <IconButton | ||||
|             class="!hover:bg-white !hover:bg-opacity-10 !md:hidden" | ||||
|             class="hover:!bg-white hover:!bg-opacity-10 md:!hidden" | ||||
|             icon="close" | ||||
|             @click="$emit('update:step-id', null)" | ||||
|           /> | ||||
| @@ -53,7 +55,7 @@ | ||||
|           <a | ||||
|             :id="`L${line.number}`" | ||||
|             :href="`#L${line.number}`" | ||||
|             class="text-wp-code-text-alt-100 select-none whitespace-nowrap pl-2 pr-6 text-right" | ||||
|             class="select-none whitespace-nowrap pl-2 pr-6 text-right text-wp-code-text-alt-100" | ||||
|             :class="{ | ||||
|               'bg-red-600 bg-opacity-40 dark:bg-red-800 dark:bg-opacity-50': line.type === 'error', | ||||
|               'bg-yellow-600 bg-opacity-40 dark:bg-yellow-800 dark:bg-opacity-50': line.type === 'warning', | ||||
| @@ -75,7 +77,7 @@ | ||||
|           /> | ||||
|           <!-- eslint-enable vue/no-v-html --> | ||||
|           <span | ||||
|             class="text-wp-code-text-alt-100 select-none whitespace-nowrap pr-1 text-right" | ||||
|             class="select-none whitespace-nowrap pr-1 text-right text-wp-code-text-alt-100" | ||||
|             :class="{ | ||||
|               'bg-red-600 bg-opacity-40 dark:bg-red-800 dark:bg-opacity-50': line.type === 'error', | ||||
|               'bg-yellow-600 bg-opacity-40 dark:bg-yellow-800 dark:bg-opacity-50': line.type === 'warning', | ||||
| @@ -87,7 +89,7 @@ | ||||
|         </div> | ||||
|       </div> | ||||
|  | ||||
|       <div class="text-wp-text-alt-100 m-auto text-xl"> | ||||
|       <div class="m-auto text-xl text-wp-text-alt-100"> | ||||
|         <span v-if="step?.state === 'skipped'">{{ $t('repo.pipeline.actions.canceled') }}</span> | ||||
|         <span v-else-if="!step?.started">{{ $t('repo.pipeline.step_not_started') }}</span> | ||||
|         <div v-else-if="!loadedLogs">{{ $t('repo.pipeline.loading') }}</div> | ||||
| @@ -96,7 +98,7 @@ | ||||
|  | ||||
|       <div | ||||
|         v-if="step?.finished !== undefined" | ||||
|         class="bg-wp-code-100 text-md text-wp-code-text-alt-100 flex w-full items-center p-4 font-bold" | ||||
|         class="text-md flex w-full items-center bg-wp-code-100 p-4 font-bold text-wp-code-text-alt-100" | ||||
|       > | ||||
|         <PipelineStatusIcon :status="step.state" class="!h-4 !w-4" /> | ||||
|         <span v-if="step?.error" class="px-2">{{ step.error }}</span> | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| <template> | ||||
|   <div class="md:min-w-xs text-wp-text-100 flex w-full flex-col gap-2 pb-2 md:w-3/12 md:max-w-md"> | ||||
|   <div class="md:min-w-xs flex w-full flex-col gap-2 pb-2 text-wp-text-100 md:w-3/12 md:max-w-md"> | ||||
|     <div | ||||
|       class="border-wp-background-400 bg-wp-background-100 dark:bg-wp-background-200 flex flex-shrink-0 flex-wrap justify-between gap-1 rounded-md border p-4" | ||||
|       class="flex flex-shrink-0 flex-wrap justify-between gap-1 rounded-md border border-wp-background-400 bg-wp-background-100 p-4 dark:bg-wp-background-200" | ||||
|     > | ||||
|       <div class="flex flex-shrink-0 items-center space-x-1"> | ||||
|         <div class="flex items-center"> | ||||
| @@ -12,7 +12,7 @@ | ||||
|       </div> | ||||
|       <a | ||||
|         v-if="pipeline.event === 'pull_request' || pipeline.event === 'pull_request_closed'" | ||||
|         class="text-wp-link-100 hover:text-wp-link-200 flex min-w-0 items-center space-x-1" | ||||
|         class="flex min-w-0 items-center space-x-1 text-wp-link-100 hover:text-wp-link-200" | ||||
|         :href="pipeline.forge_url" | ||||
|       > | ||||
|         <Icon name="pull-request" /> | ||||
| @@ -20,7 +20,7 @@ | ||||
|       </a> | ||||
|       <router-link | ||||
|         v-else-if="pipeline.event === 'push' || pipeline.event === 'manual' || pipeline.event === 'deployment'" | ||||
|         class="text-wp-link-100 hover:text-wp-link-200 flex min-w-0 items-center space-x-1" | ||||
|         class="flex min-w-0 items-center space-x-1 text-wp-link-100 hover:text-wp-link-200" | ||||
|         :to="{ name: 'repo-branch', params: { branch: prettyRef } }" | ||||
|       > | ||||
|         <Icon v-if="pipeline.event === 'manual'" name="manual-pipeline" /> | ||||
| @@ -40,7 +40,7 @@ | ||||
|         </template> | ||||
|         <a | ||||
|           v-else | ||||
|           class="text-wp-link-100 hover:text-wp-link-200 flex items-center" | ||||
|           class="flex items-center text-wp-link-100 hover:text-wp-link-200" | ||||
|           :href="pipeline.forge_url" | ||||
|           target="_blank" | ||||
|         > | ||||
| @@ -59,7 +59,7 @@ | ||||
|         <div | ||||
|           v-for="workflow in pipeline.workflows" | ||||
|           :key="workflow.id" | ||||
|           class="border-wp-background-400 bg-wp-background-100 dark:bg-wp-background-200 rounded-md border p-2 shadow" | ||||
|           class="rounded-md border border-wp-background-400 bg-wp-background-100 p-2 shadow dark:bg-wp-background-200" | ||||
|         > | ||||
|           <div class="flex flex-col gap-2"> | ||||
|             <div v-if="workflow.environ" class="flex flex-wrap justify-end gap-x-1 gap-y-2 pr-1 pt-1 text-xs"> | ||||
| @@ -71,7 +71,7 @@ | ||||
|               v-if="!singleConfig" | ||||
|               type="button" | ||||
|               :title="workflow.name" | ||||
|               class="hover:bg-wp-background-300 dark:hover:bg-wp-background-400 hover-effect flex items-center gap-2 rounded-md px-1 py-2" | ||||
|               class="hover-effect flex items-center gap-2 rounded-md px-1 py-2 hover:bg-wp-background-300 dark:hover:bg-wp-background-400" | ||||
|               @click="workflowsCollapsed[workflow.id] = !workflowsCollapsed[workflow.id]" | ||||
|             > | ||||
|               <Icon | ||||
| @@ -89,7 +89,7 @@ | ||||
|             </button> | ||||
|           </div> | ||||
|           <div | ||||
|             class="transition-height overflow-hidden duration-150" | ||||
|             class="overflow-hidden transition-height duration-150" | ||||
|             :class="{ 'max-h-0': workflowsCollapsed[workflow.id], 'ml-[1.6rem]': !singleConfig }" | ||||
|           > | ||||
|             <button | ||||
| @@ -97,7 +97,7 @@ | ||||
|               :key="step.pid" | ||||
|               type="button" | ||||
|               :title="step.name" | ||||
|               class="hover:bg-wp-background-300 dark:hover:bg-wp-background-400 hover-effect flex w-full items-center gap-2 rounded-md border-2 border-transparent p-2" | ||||
|               class="hover-effect flex w-full items-center gap-2 rounded-md border-2 border-transparent p-2 hover:bg-wp-background-300 dark:hover:bg-wp-background-400" | ||||
|               :class="{ | ||||
|                 'bg-wp-background-300 dark:bg-wp-background-400': selectedStepId && selectedStepId === step.pid, | ||||
|                 'mt-1': !singleConfig || (workflow.children && step.pid !== workflow.children[0].pid), | ||||
|   | ||||
| @@ -22,7 +22,7 @@ | ||||
|       </InputField> | ||||
|  | ||||
|       <InputField v-slot="{ id }" :label="$t('secrets.plugins.images')"> | ||||
|         <span class="text-wp-text-alt-100 mb-2 ml-1">{{ $t('secrets.plugins.desc') }}</span> | ||||
|         <span class="mb-2 ml-1 text-wp-text-alt-100">{{ $t('secrets.plugins.desc') }}</span> | ||||
|  | ||||
|         <div class="flex flex-col gap-2"> | ||||
|           <div v-for="image in innerValue.images" :key="image" class="flex gap-2"> | ||||
|   | ||||
| @@ -1,9 +1,9 @@ | ||||
| <template> | ||||
|   <div class="text-wp-text-100 space-y-4"> | ||||
|   <div class="space-y-4 text-wp-text-100"> | ||||
|     <ListItem | ||||
|       v-for="secret in secrets" | ||||
|       :key="secret.id" | ||||
|       class="!bg-wp-background-200 !dark:bg-wp-background-100 items-center" | ||||
|       class="items-center !bg-wp-background-200 dark:!bg-wp-background-100" | ||||
|     > | ||||
|       <span>{{ secret.name }}</span> | ||||
|       <Badge | ||||
| @@ -11,19 +11,19 @@ | ||||
|         class="ml-2" | ||||
|         :label="secret.org_id === 0 ? $t('global_level_secret') : $t('org_level_secret')" | ||||
|       /> | ||||
|       <div class="<md:hidden ml-auto space-x-2"> | ||||
|       <div class="md:display-unset ml-auto hidden space-x-2"> | ||||
|         <Badge v-for="event in secret.events" :key="event" :label="event" /> | ||||
|       </div> | ||||
|       <template v-if="secret.edit !== false"> | ||||
|         <IconButton | ||||
|           icon="edit" | ||||
|           class="<md:ml-auto ml-2 h-8 w-8" | ||||
|           class="ml-auto h-8 w-8 md:ml-2" | ||||
|           :title="$t('secrets.edit')" | ||||
|           @click="editSecret(secret)" | ||||
|         /> | ||||
|         <IconButton | ||||
|           icon="trash" | ||||
|           class="hover:text-wp-error-100 ml-2 h-8 w-8" | ||||
|           class="ml-2 h-8 w-8 hover:text-wp-error-100" | ||||
|           :is-loading="isDeleting" | ||||
|           :title="$t('secrets.delete')" | ||||
|           @click="deleteSecret(secret)" | ||||
|   | ||||
| @@ -14,7 +14,7 @@ function updateTheme() { | ||||
|     document.documentElement.classList.remove('light'); | ||||
|     document.documentElement.classList.add('dark'); | ||||
|     document.documentElement.setAttribute('data-theme', 'dark'); | ||||
|     document.querySelector('meta[name=theme-color]')?.setAttribute('content', '#2A2E3A'); // internal-wp-secondary-600 (see windi.config.ts) | ||||
|     document.querySelector('meta[name=theme-color]')?.setAttribute('content', '#2A2E3A'); // internal-wp-secondary-600 (see tailwind.config.ts) | ||||
|   } else { | ||||
|     document.documentElement.classList.remove('dark'); | ||||
|     document.documentElement.classList.add('light'); | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| import 'windi.css'; | ||||
| import '~/compositions/useFavicon'; | ||||
| import '~/tailwind.css'; | ||||
| import '~/style.css'; | ||||
|  | ||||
| import { createPinia } from 'pinia'; | ||||
|   | ||||
| @@ -81,8 +81,8 @@ | ||||
|   --wp-control-ok-200: theme('colors.int-wp-control-ok-dark.200'); | ||||
|   --wp-control-ok-300: theme('colors.int-wp-control-ok-dark.300'); | ||||
|  | ||||
|   --wp-error-100: theme('colors.int-wp-error.100'); | ||||
|   --wp-error-200: theme('colors.int-wp-error.200'); | ||||
|   --wp-error-100: theme('colors.int-wp-error.200'); | ||||
|   --wp-error-200: theme('colors.int-wp-error.300'); | ||||
|   --wp-error-300: theme('colors.int-wp-error.300'); | ||||
|  | ||||
|   --wp-state-neutral-100: theme('colors.int-wp-state-neutral.100'); | ||||
| @@ -117,7 +117,7 @@ body, | ||||
| } | ||||
|  | ||||
| .vue-notification { | ||||
|   @apply border-l-6 rounded-md text-base; | ||||
|   @apply rounded-md border-l-4 text-base; | ||||
| } | ||||
|  | ||||
| .vue-notification .notification-title { | ||||
| @@ -125,15 +125,15 @@ body, | ||||
| } | ||||
|  | ||||
| .vue-notification.success { | ||||
|   @apply !bg-wp-control-ok-100 !border-l-wp-control-ok-300; | ||||
|   @apply !border-l-wp-control-ok-300 !bg-wp-control-ok-100; | ||||
| } | ||||
|  | ||||
| .vue-notification.error { | ||||
|   @apply !bg-wp-error-100 !dark:bg-wp-error-200 !border-l-wp-error-300; | ||||
|   @apply !border-l-wp-error-200 !bg-wp-error-100; | ||||
| } | ||||
|  | ||||
| *::-webkit-scrollbar { | ||||
|   @apply w-12px h-12px bg-transparent; | ||||
|   @apply h-3 w-3 bg-transparent; | ||||
| } | ||||
|  | ||||
| * { | ||||
| @@ -143,11 +143,11 @@ body, | ||||
| *::-webkit-scrollbar-thumb { | ||||
|   transition: background 0.2s ease-in-out; | ||||
|   border: 3px solid transparent; | ||||
|   @apply bg-cool-gray-200 dark:bg-dark-200 rounded-full bg-clip-content; | ||||
|   @apply rounded-full bg-gray-200 bg-clip-content dark:bg-wp-background-200; | ||||
| } | ||||
|  | ||||
| *::-webkit-scrollbar-thumb:hover { | ||||
|   @apply bg-cool-gray-300 dark:bg-dark-100; | ||||
|   @apply bg-gray-300 dark:bg-wp-background-100; | ||||
| } | ||||
|  | ||||
| *::-webkit-scrollbar-corner { | ||||
| @@ -155,16 +155,16 @@ body, | ||||
| } | ||||
|  | ||||
| .code-box { | ||||
|   @apply bg-wp-code-inline-100 text-wp-code-inline-text-100 break-words rounded-md p-4 text-sm; | ||||
|   @apply break-words rounded-md bg-wp-code-inline-100 p-4 text-sm text-wp-code-inline-text-100; | ||||
|   white-space: pre-wrap; | ||||
| } | ||||
|  | ||||
| .code-box-inline, | ||||
| code:not(pre > code) { | ||||
|   @apply bg-wp-code-inline-100 text-wp-code-inline-text-100 rounded-md px-1.5 py-0.5; | ||||
|   @apply rounded-md bg-wp-code-inline-100 px-1.5 py-0.5 text-wp-code-inline-text-100; | ||||
| } | ||||
|  | ||||
| .code-box-log { | ||||
|   @apply bg-wp-code-300 text-wp-code-text-100 break-words rounded-md p-4 text-sm; | ||||
|   @apply break-words bg-wp-code-300 p-4 text-wp-code-text-100; | ||||
|   white-space: pre-wrap; | ||||
| } | ||||
|   | ||||
							
								
								
									
										19
									
								
								web/src/tailwind.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								web/src/tailwind.css
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| @tailwind base; | ||||
| @tailwind components; | ||||
| @tailwind utilities; | ||||
|  | ||||
| @layer components { | ||||
|   .hover-effect { | ||||
|     @apply transition-colors duration-100 hover:bg-black hover:bg-opacity-10 dark:hover:bg-white dark:hover:bg-opacity-5; | ||||
|   } | ||||
|  | ||||
|   .w-fill { | ||||
|     width: -webkit-fill-available; | ||||
|     width: -moz-available; | ||||
|     width: stretch; | ||||
|   } | ||||
|  | ||||
|   .display-unset { | ||||
|     display: unset; | ||||
|   } | ||||
| } | ||||
| @@ -1,26 +1,26 @@ | ||||
| <template> | ||||
|   <main class="flex h-full w-full flex-col items-center justify-center"> | ||||
|     <Error v-if="errorMessage" class="md:w-3xl w-full"> | ||||
|     <Error v-if="errorMessage" class="w-full md:w-3xl"> | ||||
|       <span class="whitespace-pre">{{ errorMessage }}</span> | ||||
|       <span v-if="errorDescription" class="mt-1 whitespace-pre">{{ errorDescription }}</span> | ||||
|       <a | ||||
|         v-if="errorUri" | ||||
|         :href="errorUri" | ||||
|         target="_blank" | ||||
|         class="text-wp-link-100 hover:text-wp-link-200 mt-1 cursor-pointer" | ||||
|         class="mt-1 cursor-pointer text-wp-link-100 hover:text-wp-link-200" | ||||
|       > | ||||
|         <span>{{ errorUri }}</span> | ||||
|       </a> | ||||
|     </Error> | ||||
|  | ||||
|     <div | ||||
|       class="bg-wp-background-100 border-wp-background-400 dark:bg-wp-background-200 md:w-3xl md:h-sm flex w-full flex-col overflow-hidden border shadow md:m-8 md:flex-row md:rounded-md" | ||||
|       class="flex min-h-sm w-full flex-col overflow-hidden border border-wp-background-400 bg-wp-background-100 shadow dark:bg-wp-background-200 md:m-8 md:w-3xl md:flex-row md:rounded-md" | ||||
|     > | ||||
|       <div class="bg-wp-primary-200 dark:bg-wp-primary-300 flex min-h-48 items-center justify-center md:w-3/5"> | ||||
|         <WoodpeckerLogo preserveAspectRatio="xMinYMin slice" class="w-30 h-30 md:h-48 md:w-48" /> | ||||
|       <div class="flex min-h-48 items-center justify-center bg-wp-primary-200 dark:bg-wp-primary-300 md:w-3/5"> | ||||
|         <WoodpeckerLogo preserveAspectRatio="xMinYMin slice" class="h-32 w-32 md:h-48 md:w-48" /> | ||||
|       </div> | ||||
|       <div class="flex min-h-48 flex-col items-center justify-center gap-4 text-center md:w-2/5"> | ||||
|         <h1 class="text-wp-text-100 text-xl">{{ $t('welcome') }}</h1> | ||||
|         <h1 class="text-xl text-wp-text-100">{{ $t('welcome') }}</h1> | ||||
|         <div class="flex flex-col gap-2"> | ||||
|           <Button | ||||
|             v-for="forge in forges" | ||||
|   | ||||
| @@ -13,9 +13,9 @@ | ||||
|           :to="repo.active ? { name: 'repo', params: { repoId: repo.id } } : undefined" | ||||
|         > | ||||
|           <span class="text-wp-text-100">{{ repo.full_name }}</span> | ||||
|           <span v-if="repo.active" class="text-wp-text-alt-100 ml-auto">{{ $t('repo.enable.enabled') }}</span> | ||||
|           <span v-if="repo.active" class="ml-auto text-wp-text-alt-100">{{ $t('repo.enable.enabled') }}</span> | ||||
|           <div v-else class="ml-auto flex items-center"> | ||||
|             <Badge v-if="repo.id" class="<md:hidden mr-2" :label="$t('repo.enable.disabled')" /> | ||||
|             <Badge v-if="repo.id" class="md:display-unset mr-2 hidden" :label="$t('repo.enable.disabled')" /> | ||||
|             <Button | ||||
|               :text="$t('repo.enable.enable')" | ||||
|               :is-loading="isActivatingRepo && repoToActivate?.forge_remote_id === repo.forge_remote_id" | ||||
| @@ -24,7 +24,7 @@ | ||||
|           </div> | ||||
|         </ListItem> | ||||
|       </template> | ||||
|       <div v-else-if="loading" class="text-wp-text-100 flex justify-center"> | ||||
|       <div v-else-if="loading" class="flex justify-center text-wp-text-100"> | ||||
|         <Icon name="spinner" /> | ||||
|       </div> | ||||
|     </div> | ||||
|   | ||||
| @@ -15,7 +15,7 @@ | ||||
|         </div> | ||||
|  | ||||
|         <div class="flex flex-col gap-4"> | ||||
|           <h2 class="text-wp-text-100 text-lg">{{ $t('all_repositories') }}</h2> | ||||
|           <h2 class="text-lg text-wp-text-100">{{ $t('all_repositories') }}</h2> | ||||
|           <div class="flex flex-col gap-4"> | ||||
|             <RepoItem v-for="repo in reposLastActivity" :key="repo.id" :repo="repo" /> | ||||
|           </div> | ||||
| @@ -25,7 +25,7 @@ | ||||
|         <div v-if="reposLastActivity.length > 0" class="flex flex-col gap-4"> | ||||
|           <RepoItem v-for="repo in reposLastActivity" :key="repo.id" :repo="repo" /> | ||||
|         </div> | ||||
|         <span v-else class="text-wp-text-100 text-center text-lg">{{ $t('no_search_results') }}</span> | ||||
|         <span v-else class="text-center text-lg text-wp-text-100">{{ $t('no_search_results') }}</span> | ||||
|       </div> | ||||
|     </Transition> | ||||
|   </Scaffold> | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| <template> | ||||
|   <Settings :title="$t('info')"> | ||||
|     <div class="flex flex-col items-center gap-4"> | ||||
|       <WoodpeckerLogo class="fill-wp-text-200 h-32 w-32" /> | ||||
|       <WoodpeckerLogo class="h-32 w-32 fill-wp-text-200" /> | ||||
|  | ||||
|       <i18n-t keypath="running_version" tag="p" class="text-center text-xl"> | ||||
|         <span class="font-bold">{{ version?.current }}</span> | ||||
|   | ||||
| @@ -1,10 +1,10 @@ | ||||
| <template> | ||||
|   <Settings :title="$t('admin.settings.orgs.orgs')" :description="$t('admin.settings.orgs.desc')"> | ||||
|     <div class="text-wp-text-100 space-y-4"> | ||||
|     <div class="space-y-4 text-wp-text-100"> | ||||
|       <ListItem | ||||
|         v-for="org in orgs" | ||||
|         :key="org.id" | ||||
|         class="!bg-wp-background-200 !dark:bg-wp-background-100 items-center gap-2" | ||||
|         class="items-center gap-2 !bg-wp-background-200 dark:!bg-wp-background-100" | ||||
|       > | ||||
|         <span>{{ org.name }}</span> | ||||
|         <IconButton | ||||
| @@ -22,7 +22,7 @@ | ||||
|         <IconButton | ||||
|           icon="trash" | ||||
|           :title="$t('admin.settings.orgs.delete_org')" | ||||
|           class="hover:text-wp-error-100 ml-2 h-8 w-8" | ||||
|           class="ml-2 h-8 w-8 hover:text-wp-error-100" | ||||
|           :is-loading="isDeleting" | ||||
|           @click="deleteOrg(org)" | ||||
|         /> | ||||
|   | ||||
| @@ -30,7 +30,7 @@ | ||||
|         <ListItem | ||||
|           v-for="task in tasks" | ||||
|           :key="task.id" | ||||
|           class="!bg-wp-background-200 !dark:bg-wp-background-100 mb-2 items-center" | ||||
|           class="mb-2 items-center !bg-wp-background-200 dark:!bg-wp-background-100" | ||||
|         > | ||||
|           <div | ||||
|             class="flex items-center" | ||||
|   | ||||
| @@ -9,15 +9,19 @@ | ||||
|       /> | ||||
|     </template> | ||||
|  | ||||
|     <div class="text-wp-text-100 space-y-4"> | ||||
|     <div class="space-y-4 text-wp-text-100"> | ||||
|       <ListItem | ||||
|         v-for="repo in repos" | ||||
|         :key="repo.id" | ||||
|         class="!bg-wp-background-200 !dark:bg-wp-background-100 items-center gap-2" | ||||
|         class="items-center gap-2 bg-wp-background-200 dark:!bg-wp-background-100" | ||||
|       > | ||||
|         <span>{{ repo.full_name }}</span> | ||||
|         <div class="ml-auto flex items-center"> | ||||
|           <Badge v-if="!repo.active" class="<md:hidden mr-2" :label="$t('admin.settings.repos.disabled')" /> | ||||
|           <Badge | ||||
|             v-if="!repo.active" | ||||
|             class="md:display-unset mr-2 hidden" | ||||
|             :label="$t('admin.settings.repos.disabled')" | ||||
|           /> | ||||
|           <IconButton | ||||
|             icon="chevron-right" | ||||
|             :title="$t('admin.settings.repos.view')" | ||||
|   | ||||
| @@ -10,30 +10,30 @@ | ||||
|       <Button v-else :text="$t('admin.settings.users.add')" start-icon="plus" @click="showAddUser" /> | ||||
|     </template> | ||||
|  | ||||
|     <div v-if="!selectedUser" class="text-wp-text-100 space-y-4"> | ||||
|     <div v-if="!selectedUser" class="space-y-4 text-wp-text-100"> | ||||
|       <ListItem | ||||
|         v-for="user in users" | ||||
|         :key="user.id" | ||||
|         class="!bg-wp-background-200 !dark:bg-wp-background-100 items-center gap-2" | ||||
|         class="items-center gap-2 !bg-wp-background-200 dark:!bg-wp-background-100" | ||||
|       > | ||||
|         <img v-if="user.avatar_url" class="h-6 rounded-md" :src="user.avatar_url" /> | ||||
|         <span>{{ user.login }}</span> | ||||
|         <Badge | ||||
|           v-if="user.admin" | ||||
|           class="ml-auto hidden md:inline-block" | ||||
|           class="md:display-unset ml-auto hidden" | ||||
|           :label="$t('admin.settings.users.admin.admin')" | ||||
|         /> | ||||
|         <IconButton | ||||
|           icon="edit" | ||||
|           :title="$t('admin.settings.users.edit_user')" | ||||
|           class="<md:ml-auto h-8 w-8" | ||||
|           class="md:display-unset ml-auto h-8 w-8" | ||||
|           :class="{ 'ml-auto': !user.admin, 'ml-2': user.admin }" | ||||
|           @click="editUser(user)" | ||||
|         /> | ||||
|         <IconButton | ||||
|           icon="trash" | ||||
|           :title="$t('admin.settings.users.delete_user')" | ||||
|           class="hover:text-wp-error-100 ml-2 h-8 w-8" | ||||
|           class="ml-2 h-8 w-8 hover:text-wp-error-100" | ||||
|           :is-loading="isDeleting" | ||||
|           @click="deleteUser(user)" | ||||
|         /> | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| <template> | ||||
|   <div class="m-auto flex flex-col gap-4"> | ||||
|     <div class="text-wp-text-100 text-center"> | ||||
|     <div class="text-center text-wp-text-100"> | ||||
|       <WoodpeckerLogo preserveAspectRatio="xMinYMin slice" class="m-auto mb-8 w-32" /> | ||||
|       <template v-if="state === 'confirm'"> | ||||
|         <h1 class="text-4xl font-bold">{{ $t('login_to_cli') }}</h1> | ||||
|   | ||||
| @@ -17,7 +17,7 @@ | ||||
|       <RepoItem v-for="repo in reposLastActivity" :key="repo.id" :repo="repo" /> | ||||
|     </div> | ||||
|     <div v-if="(reposLastActivity || []).length <= 0" class="text-center"> | ||||
|       <span class="text-wp-text-100 m-auto">{{ $t('repo.user_none') }}</span> | ||||
|       <span class="m-auto text-wp-text-100">{{ $t('repo.user_none') }}</span> | ||||
|     </div> | ||||
|   </Scaffold> | ||||
| </template> | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| <template> | ||||
|   <div class="mb-4 flex w-full justify-center"> | ||||
|     <span class="text-wp-text-100 text-xl">{{ $t('repo.pipeline.pipelines_for', { branch }) }}</span> | ||||
|     <span class="text-xl text-wp-text-100">{{ $t('repo.pipeline.pipelines_for', { branch }) }}</span> | ||||
|   </div> | ||||
|   <PipelineList :pipelines="pipelines" :repo="repo" /> | ||||
| </template> | ||||
|   | ||||
| @@ -11,7 +11,7 @@ | ||||
|         <Badge v-if="branch === repo?.default_branch" :label="$t('default')" class="ml-auto" /> | ||||
|       </ListItem> | ||||
|     </template> | ||||
|     <div v-else-if="loading" class="text-wp-text-100 flex justify-center"> | ||||
|     <div v-else-if="loading" class="flex justify-center text-wp-text-100"> | ||||
|       <Icon name="spinner" /> | ||||
|     </div> | ||||
|     <Panel v-else class="flex justify-center"> | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| <template> | ||||
|   <Panel v-if="!loading"> | ||||
|     <form @submit.prevent="triggerManualPipeline"> | ||||
|       <span class="text-wp-text-100 text-xl">{{ $t('repo.manual_pipeline.title') }}</span> | ||||
|       <span class="text-xl text-wp-text-100">{{ $t('repo.manual_pipeline.title') }}</span> | ||||
|       <InputField v-slot="{ id }" :label="$t('repo.manual_pipeline.select_branch')"> | ||||
|         <SelectField :id="id" v-model="payload.branch" :options="branches" required /> | ||||
|       </InputField> | ||||
|       <InputField v-slot="{ id }" :label="$t('repo.manual_pipeline.variables.title')"> | ||||
|         <span class="text-wp-text-alt-100 mb-2 text-sm">{{ $t('repo.manual_pipeline.variables.desc') }}</span> | ||||
|         <span class="mb-2 text-sm text-wp-text-alt-100">{{ $t('repo.manual_pipeline.variables.desc') }}</span> | ||||
|         <KeyValueEditor | ||||
|           :id="id" | ||||
|           v-model="payload.variables" | ||||
| @@ -19,7 +19,7 @@ | ||||
|       <Button type="submit" :text="$t('repo.manual_pipeline.trigger')" :disabled="!isFormValid" /> | ||||
|     </form> | ||||
|   </Panel> | ||||
|   <div v-else class="text-wp-text-100 flex justify-center"> | ||||
|   <div v-else class="flex justify-center text-wp-text-100"> | ||||
|     <Icon name="spinner" /> | ||||
|   </div> | ||||
| </template> | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| <template> | ||||
|   <div class="mb-4 flex w-full justify-center"> | ||||
|     <span class="text-wp-text-100 text-xl">{{ $t('repo.pipeline.pipelines_for_pr', { index: pullRequest }) }}</span> | ||||
|     <span class="text-xl text-wp-text-100">{{ $t('repo.pipeline.pipelines_for_pr', { index: pullRequest }) }}</span> | ||||
|   </div> | ||||
|   <PipelineList :pipelines="pipelines" :repo="repo" /> | ||||
| </template> | ||||
|   | ||||
| @@ -8,15 +8,15 @@ | ||||
|         :to="{ name: 'repo-pull-request', params: { pullRequest: pullRequest.index } }" | ||||
|       > | ||||
|         <!-- eslint-disable-next-line @intlify/vue-i18n/no-raw-text --> | ||||
|         <span class="text-wp-text-alt-100 <md:hidden">#{{ pullRequest.index }}</span> | ||||
|         <span class="md:display-unset hidden text-wp-text-alt-100">#{{ pullRequest.index }}</span> | ||||
|         <!-- eslint-disable-next-line @intlify/vue-i18n/no-raw-text --> | ||||
|         <span class="text-wp-text-alt-100 <md:hidden mx-2">-</span> | ||||
|         <span class="text-wp-text-100 <md:underline overflow-hidden overflow-ellipsis whitespace-nowrap">{{ | ||||
|         <span class="md:display-unset mx-2 hidden text-wp-text-alt-100">-</span> | ||||
|         <span class="overflow-hidden overflow-ellipsis whitespace-nowrap text-wp-text-100 underline md:no-underline">{{ | ||||
|           pullRequest.title | ||||
|         }}</span> | ||||
|       </ListItem> | ||||
|     </template> | ||||
|     <div v-else-if="loading" class="text-wp-text-100 flex justify-center"> | ||||
|     <div v-else-if="loading" class="flex justify-center text-wp-text-100"> | ||||
|       <Icon name="spinner" /> | ||||
|     </div> | ||||
|     <Panel v-else class="flex justify-center"> | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| <template> | ||||
|   <Container full-width class="md:min-h-xs flex flex-grow-0 flex-col md:flex-grow md:px-4"> | ||||
|     <div class="flex min-h-0 w-full flex-grow flex-wrap-reverse gap-4 md:flex-nowrap"> | ||||
|     <div class="flex min-h-0 w-full flex-grow flex-wrap-reverse md:flex-nowrap md:gap-4"> | ||||
|       <PipelineStepList | ||||
|         v-model:selected-step-id="selectedStepId" | ||||
|         :class="{ 'hidden md:flex': pipeline!.status === 'blocked' }" | ||||
| @@ -8,17 +8,17 @@ | ||||
|       /> | ||||
|  | ||||
|       <div class="relative flex flex-grow basis-full items-start justify-center md:basis-auto"> | ||||
|         <Container v-if="pipeline!.errors?.some((e) => !e.is_warning)" fill-width class="p-0"> | ||||
|         <div v-if="pipeline!.errors?.some((e) => !e.is_warning)" class="mb-4 w-full md:mb-auto"> | ||||
|           <Panel> | ||||
|             <div class="flex flex-col items-center gap-4 text-center"> | ||||
|               <Icon name="status-error" class="text-wp-error-100 h-16 w-16" size="1.5rem" /> | ||||
|               <Icon name="status-error" class="h-16 w-16 text-wp-error-100" size="1.5rem" /> | ||||
|               <span class="text-xl">{{ $t('repo.pipeline.we_got_some_errors') }}</span> | ||||
|               <Button color="red" :text="$t('repo.pipeline.show_errors')" :to="{ name: 'repo-pipeline-errors' }" /> | ||||
|             </div> | ||||
|           </Panel> | ||||
|         </Container> | ||||
|         </div> | ||||
|  | ||||
|         <Container v-else-if="pipeline!.status === 'blocked'" fill-width class="p-0"> | ||||
|         <div v-else-if="pipeline!.status === 'blocked'" class="mb-4 w-full md:mb-auto"> | ||||
|           <Panel> | ||||
|             <div class="flex flex-col items-center gap-4"> | ||||
|               <Icon name="status-blocked" size="1.5rem" class="h-16 w-16" /> | ||||
| @@ -39,16 +39,16 @@ | ||||
|               </div> | ||||
|             </div> | ||||
|           </Panel> | ||||
|         </Container> | ||||
|         </div> | ||||
|  | ||||
|         <Container v-else-if="pipeline!.status === 'declined'" fill-width class="p-0"> | ||||
|         <div v-else-if="pipeline!.status === 'declined'" class="mb-4 w-full md:mb-auto"> | ||||
|           <Panel> | ||||
|             <div class="flex flex-col items-center gap-4"> | ||||
|               <Icon name="status-declined" size="1.5rem" class="text-wp-error-100 h-16 w-16" /> | ||||
|               <Icon name="status-declined" size="1.5rem" class="h-16 w-16 text-wp-error-100" /> | ||||
|               <p class="text-xl">{{ $t('repo.pipeline.protected.declined') }}</p> | ||||
|             </div> | ||||
|           </Panel> | ||||
|         </Container> | ||||
|         </div> | ||||
|  | ||||
|         <PipelineLog | ||||
|           v-else-if="selectedStepId !== null" | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|   <template v-if="repoPermissions && repoPermissions.push"> | ||||
|     <Panel> | ||||
|       <InputField :label="$t('repo.pipeline.debug.metadata_exec_title')"> | ||||
|         <p class="text-wp-text-alt-100 mb-2 text-sm">{{ $t('repo.pipeline.debug.metadata_exec_desc') }}</p> | ||||
|         <p class="mb-2 text-sm text-wp-text-alt-100">{{ $t('repo.pipeline.debug.metadata_exec_desc') }}</p> | ||||
|         <pre class="code-box">{{ cliExecWithMetadata }}</pre> | ||||
|       </InputField> | ||||
|       <div class="flex items-center space-x-4"> | ||||
| @@ -11,7 +11,7 @@ | ||||
|     </Panel> | ||||
|   </template> | ||||
|   <div v-else class="flex h-full items-center justify-center"> | ||||
|     <div class="bg-wp-error-100 dark:bg-wp-error-200 rounded-lg p-8 text-center shadow-lg"> | ||||
|     <div class="rounded-lg bg-wp-error-100 p-8 text-center shadow-lg dark:bg-wp-error-200"> | ||||
|       <p class="text-2xl font-bold text-white">{{ $t('repo.pipeline.debug.no_permission') }}</p> | ||||
|     </div> | ||||
|   </div> | ||||
|   | ||||
| @@ -14,19 +14,21 @@ | ||||
|       <Button v-else start-icon="plus" :text="$t('repo.settings.crons.add')" @click="selectedCron = {}" /> | ||||
|     </template> | ||||
|  | ||||
|     <div v-if="!selectedCron" class="text-wp-text-100 space-y-4"> | ||||
|     <div v-if="!selectedCron" class="space-y-4 text-wp-text-100"> | ||||
|       <ListItem | ||||
|         v-for="cron in crons" | ||||
|         :key="cron.id" | ||||
|         class="!bg-wp-background-200 !dark:bg-wp-background-100 items-center" | ||||
|         class="items-center !bg-wp-background-200 dark:!bg-wp-background-100" | ||||
|       > | ||||
|         <span class="grid w-full grid-cols-3"> | ||||
|           <span>{{ cron.name }}</span> | ||||
|           <span v-if="cron.next_exec && cron.next_exec > 0" class="<md:hidden col-span-2"> | ||||
|           <span v-if="cron.next_exec && cron.next_exec > 0" class="md:display-unset col-span-2 hidden"> | ||||
|             <!-- eslint-disable-next-line @intlify/vue-i18n/no-raw-text --> | ||||
|             {{ $t('repo.settings.crons.next_exec') }}: {{ date.toLocaleString(new Date(cron.next_exec * 1000)) }} | ||||
|           </span> | ||||
|           <span v-else class="<md:hidden col-span-2">{{ $t('repo.settings.crons.not_executed_yet') }}</span> | ||||
|           <span v-else class="md:display-unset col-span-2 hidden">{{ | ||||
|             $t('repo.settings.crons.not_executed_yet') | ||||
|           }}</span> | ||||
|         </span> | ||||
|         <IconButton | ||||
|           icon="play-outline" | ||||
| @@ -37,7 +39,7 @@ | ||||
|         <IconButton icon="edit" class="h-8 w-8" :title="$t('repo.settings.crons.edit')" @click="selectedCron = cron" /> | ||||
|         <IconButton | ||||
|           icon="trash" | ||||
|           class="hover:text-wp-error-100 h-8 w-8" | ||||
|           class="h-8 w-8 hover:text-wp-error-100" | ||||
|           :is-loading="isDeleting" | ||||
|           :title="$t('repo.settings.crons.delete')" | ||||
|           @click="deleteCron(cron)" | ||||
|   | ||||
| @@ -22,7 +22,7 @@ | ||||
|         :label="$t('repo.settings.general.netrc_only_trusted.netrc_only_trusted')" | ||||
|         docs-url="docs/usage/project-settings#custom-trusted-clone-plugins" | ||||
|       > | ||||
|         <span class="text-wp-text-alt-100 mb-2 ml-1">{{ $t('repo.settings.general.netrc_only_trusted.desc') }}</span> | ||||
|         <span class="mb-2 ml-1 text-wp-text-alt-100">{{ $t('repo.settings.general.netrc_only_trusted.desc') }}</span> | ||||
|  | ||||
|         <div class="flex flex-col gap-2"> | ||||
|           <div v-for="image in repoSettings.netrc_trusted" :key="image" class="flex gap-2"> | ||||
| @@ -99,7 +99,7 @@ | ||||
|       > | ||||
|         <div class="flex items-center"> | ||||
|           <NumberField :id="id" v-model="repoSettings.timeout" class="w-24" /> | ||||
|           <span class="text-wp-text-alt-100 ml-4">{{ $t('repo.settings.general.timeout.minutes') }}</span> | ||||
|           <span class="ml-4 text-wp-text-alt-100">{{ $t('repo.settings.general.timeout.minutes') }}</span> | ||||
|         </div> | ||||
|       </InputField> | ||||
|  | ||||
| @@ -115,7 +115,7 @@ | ||||
|           /> | ||||
|         </template> | ||||
|         <template #description> | ||||
|           <i18n-t keypath="repo.settings.general.pipeline_path.desc" tag="p" class="text-wp-text-alt-100 text-sm"> | ||||
|           <i18n-t keypath="repo.settings.general.pipeline_path.desc" tag="p" class="text-sm text-wp-text-alt-100"> | ||||
|             <span class="code-box-inline">{{ $t('repo.settings.general.pipeline_path.desc_path_example') }}</span> | ||||
|             <!-- eslint-disable-next-line @intlify/vue-i18n/no-raw-text --> | ||||
|             <span class="code-box-inline">/</span> | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|   <Settings :title="$t('user.settings.cli_and_api.cli_and_api')" :description="$t('user.settings.cli_and_api.desc')"> | ||||
|     <InputField :label="$t('user.settings.cli_and_api.cli_usage')"> | ||||
|       <template #headerActions> | ||||
|         <a :href="cliDownload" target="_blank" class="text-wp-link-100 hover:text-wp-link-200 ml-4">{{ | ||||
|         <a :href="cliDownload" target="_blank" class="ml-4 text-wp-link-100 hover:text-wp-link-200">{{ | ||||
|           $t('user.settings.cli_and_api.download_cli') | ||||
|         }}</a> | ||||
|       </template> | ||||
| @@ -22,7 +22,7 @@ | ||||
|           v-if="enableSwagger" | ||||
|           :href="`${address}/swagger/index.html`" | ||||
|           target="_blank" | ||||
|           class="text-wp-link-100 hover:text-wp-link-200 ml-4" | ||||
|           class="ml-4 text-wp-link-100 hover:text-wp-link-200" | ||||
|         > | ||||
|           {{ $t('user.settings.cli_and_api.swagger_ui') }} | ||||
|         </a> | ||||
|   | ||||
| @@ -1,12 +1,11 @@ | ||||
| // cSpell:ignore Segoe Roboto Neue Noto nocheck
 | ||||
| /* eslint-disable ts/no-unsafe-member-access, ts/no-unsafe-assignment, ts/no-unsafe-argument, ts/no-unsafe-return */ | ||||
| // eslint-disable-next-line ts/ban-ts-comment
 | ||||
| // @ts-nocheck
 | ||||
| 
 | ||||
| import typography from '@tailwindcss/typography'; | ||||
| import type { Config } from 'tailwindcss'; | ||||
| import colors from 'tailwindcss/colors'; | ||||
| import tinycolor from 'tinycolor2'; | ||||
| import colors from 'windicss/colors'; | ||||
| import { defineConfig } from 'windicss/helpers'; | ||||
| import typography from 'windicss/plugin/typography'; | ||||
| 
 | ||||
| const customColors = { | ||||
|   'wp-primary': { | ||||
| @@ -28,8 +27,8 @@ const customColors = { | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| /* eslint-disable ts/no-unsafe-call */ | ||||
| export default defineConfig({ | ||||
| export default { | ||||
|   content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}', './src/**/*.css'], | ||||
|   darkMode: 'class', | ||||
|   theme: { | ||||
|     extend: { | ||||
| @@ -205,27 +204,34 @@ export default defineConfig({ | ||||
|           200: 'var(--wp-link-200)', | ||||
|         }, | ||||
|       }, | ||||
|       spacing: { | ||||
|         sm: '24rem', | ||||
|         md: '28rem', | ||||
|         lg: '32rem', | ||||
|         xl: '36rem', | ||||
|         '2xl': '42rem', | ||||
|         '3xl': '48rem', | ||||
|       }, | ||||
|       fontFamily: { | ||||
|         sans: [ | ||||
|           'system-ui', | ||||
|           '-apple-system', | ||||
|           'Segoe UI', | ||||
|           'Roboto', | ||||
|           'Helvetica Neue', | ||||
|           'Noto Sans', | ||||
|           'Liberation Sans', | ||||
|           'Arial', | ||||
|           'sans-serif', | ||||
|         ], | ||||
|       }, | ||||
|       transitionProperty: { | ||||
|         height: 'max-height', | ||||
|       }, | ||||
|       stroke: (theme) => theme('colors'), | ||||
|       fill: (theme) => theme('colors'), | ||||
|       fontFamily: [ | ||||
|         'system-ui', | ||||
|         '-apple-system', | ||||
|         'Segoe UI', | ||||
|         'Roboto', | ||||
|         'Helvetica Neue', | ||||
|         'Noto Sans', | ||||
|         'Liberation Sans', | ||||
|         'Arial', | ||||
|         'sans-serif', | ||||
|       ], | ||||
| 
 | ||||
|       stroke: (theme: (path: string) => object) => theme('colors'), | ||||
|       fill: (theme: (path: string) => object) => theme('colors'), | ||||
|     }, | ||||
|   }, | ||||
|   shortcuts: { | ||||
|     'hover-effect': | ||||
|       'hover:bg-black hover:bg-opacity-10 dark:hover:bg-white dark:hover:bg-opacity-5 transition-colors duration-100', | ||||
|   }, | ||||
|   plugins: [typography()], | ||||
| }); | ||||
|   plugins: [typography], | ||||
| } satisfies Config; | ||||
| @@ -27,6 +27,14 @@ | ||||
|     "noUnusedParameters": true, | ||||
|     "noFallthroughCasesInSwitch": true | ||||
|   }, | ||||
|   "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue", "src/**/*.json", "windi.config.ts", "vite.config.ts"], | ||||
|   "include": [ | ||||
|     "src/**/*.ts", | ||||
|     "src/**/*.tsx", | ||||
|     "src/**/*.vue", | ||||
|     "src/**/*.json", | ||||
|     "tailwind.config.ts", | ||||
|     "vite.config.ts", | ||||
|     "postcss.config.js" | ||||
|   ], | ||||
|   "exclude": ["node_modules", "**/__tests__/**/*", "**/dist/**/*"] | ||||
| } | ||||
|   | ||||
| @@ -5,7 +5,6 @@ import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite'; | ||||
| import vue from '@vitejs/plugin-vue'; | ||||
| import type { Plugin } from 'vite'; | ||||
| import prismjs from 'vite-plugin-prismjs'; | ||||
| import WindiCSS from 'vite-plugin-windicss'; | ||||
| import svgLoader from 'vite-svg-loader'; | ||||
| import type { ViteUserConfig } from 'vitest/config'; | ||||
| import { defineConfig } from 'vitest/config'; | ||||
| @@ -70,7 +69,6 @@ export default defineConfig({ | ||||
|         }, | ||||
|       }; | ||||
|     })(), | ||||
|     WindiCSS(), | ||||
|     svgLoader(), | ||||
|     externalCSSPlugin(), | ||||
|     woodpeckerInfoPlugin(), | ||||
|   | ||||
		Reference in New Issue
	
	Block a user