Replace duplicated strings (#3710)

This commit is contained in:
qwerty287 2024-05-15 18:52:19 +02:00 committed by GitHub
parent 5527d9bf86
commit b08133bb63
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 68 additions and 163 deletions

View file

@ -72,9 +72,8 @@
"success": "Repository enabled", "success": "Repository enabled",
"list_reloaded": "Repository list reloaded" "list_reloaded": "Repository list reloaded"
}, },
"open_in_forge": "Open Repository in Version Control System", "open_in_forge": "Open repository in forge",
"settings": { "settings": {
"settings": "Settings",
"not_allowed": "You are not allowed to access this repository's settings", "not_allowed": "You are not allowed to access this repository's settings",
"general": { "general": {
"general": "General", "general": "General",
@ -131,31 +130,6 @@
"desc": "Enable to cancel pending and running pipelines of the same event and context before starting the newly triggered one." "desc": "Enable to cancel pending and running pipelines of the same event and context before starting the newly triggered one."
} }
}, },
"secrets": {
"secrets": "Secrets",
"desc": "Secrets can be passed to individual pipeline steps at runtime as environmental variables.",
"none": "There are no secrets yet.",
"add": "Add secret",
"save": "Save secret",
"show": "Show secrets",
"name": "Name",
"value": "Value",
"delete_confirm": "Do you really want to delete this secret?",
"deleted": "Secret deleted",
"created": "Secret created",
"saved": "Secret saved",
"images": {
"images": "Available for following images",
"desc": "List of images where this secret is available, leave empty to allow all images"
},
"events": {
"events": "Available at following events",
"pr_warning": "Please be careful with this option as a bad actor can submit a malicious pull request that exposes your secrets."
},
"plugins_only": "Only available for plugins",
"edit": "Edit secret",
"delete": "Delete secret"
},
"registries": { "registries": {
"registries": "Registries", "registries": "Registries",
"credentials": "Registry credentials", "credentials": "Registry credentials",
@ -298,58 +272,18 @@
}, },
"org": { "org": {
"settings": { "settings": {
"settings": "Settings",
"not_allowed": "You are not allowed to access this organization's settings", "not_allowed": "You are not allowed to access this organization's settings",
"secrets": { "secrets": {
"secrets": "Secrets", "desc": "Organization secrets can be passed to all organization's repository individual pipeline steps at runtime as environmental variables."
"desc": "Organization secrets can be passed to all organization's repository individual pipeline steps at runtime as environmental variables.",
"none": "There are no organization secrets yet.",
"add": "Add secret",
"save": "Save secret",
"show": "Show secrets",
"name": "Name",
"value": "Value",
"deleted": "Organization secret deleted",
"created": "Organization secret created",
"saved": "Organization secret saved",
"images": {
"images": "Available for following images",
"desc": "List of images where this secret is available, leave empty to allow all images"
},
"plugins_only": "Only available for plugins",
"events": {
"events": "Available at following events",
"pr_warning": "Please be careful with this option as a bad actor can submit a malicious pull request that exposes your secrets."
}
} }
} }
}, },
"admin": { "admin": {
"settings": { "settings": {
"settings": "Settings",
"not_allowed": "You are not allowed to access server settings", "not_allowed": "You are not allowed to access server settings",
"secrets": { "secrets": {
"secrets": "Secrets",
"desc": "Global secrets can be passed to all repositories individual pipeline steps at runtime as environmental variables.", "desc": "Global secrets can be passed to all repositories individual pipeline steps at runtime as environmental variables.",
"warning": "These secrets will be available for all server users.", "warning": "These secrets will be available for all server users."
"none": "There are no global secrets yet.",
"add": "Add secret",
"save": "Save secret",
"show": "Show secrets",
"name": "Name",
"value": "Value",
"deleted": "Global secret deleted",
"created": "Global secret created",
"saved": "Global secret saved",
"images": {
"images": "Available for following images",
"desc": "List of images where this secret is available, leave empty to allow all images"
},
"plugins_only": "Only available for plugins",
"events": {
"events": "Available at following events",
"pr_warning": "Please be careful with this option as a bad actor can submit a malicious pull request that exposes your secrets."
}
}, },
"agents": { "agents": {
"agents": "Agents", "agents": "Agents",
@ -472,26 +406,7 @@
} }
}, },
"secrets": { "secrets": {
"secrets": "Secrets", "desc": "User secrets can be passed to all user's repository individual pipeline steps at runtime as environmental variables."
"desc": "User secrets can be passed to all user's repository individual pipeline steps at runtime as environmental variables.",
"none": "There are no user secrets yet.",
"add": "Add secret",
"save": "Save secret",
"show": "Show secrets",
"name": "Name",
"value": "Value",
"deleted": "User secret deleted",
"created": "User secret created",
"saved": "User secret saved",
"images": {
"images": "Available for following images",
"desc": "List of images where this secret is available, leave empty to allow all images"
},
"plugins_only": "Only available for plugins",
"events": {
"events": "Available at following events",
"pr_warning": "Please be careful with this option as a bad actor can submit a malicious pull request that exposes your secrets."
}
}, },
"cli_and_api": { "cli_and_api": {
"cli_and_api": "CLI & API", "cli_and_api": "CLI & API",
@ -508,6 +423,31 @@
"internal_error": "Some internal error occurred", "internal_error": "Some internal error occurred",
"access_denied": "You are not allowed to login" "access_denied": "You are not allowed to login"
}, },
"secrets": {
"secrets": "Secrets",
"desc": "Secrets can be passed to individual pipeline steps at runtime as environmental variables.",
"none": "There are no secrets yet.",
"add": "Add secret",
"save": "Save secret",
"show": "Show secrets",
"name": "Name",
"value": "Value",
"delete_confirm": "Do you really want to delete this secret?",
"deleted": "Secret deleted",
"created": "Secret created",
"saved": "Secret saved",
"images": {
"images": "Available for following images",
"desc": "List of images where this secret is available, leave empty to allow all images"
},
"events": {
"events": "Available at following events",
"pr_warning": "Please be careful with this option as a bad actor can submit a malicious pull request that exposes your secrets."
},
"plugins_only": "Only available for plugins",
"edit": "Edit secret",
"delete": "Delete secret"
},
"default": "default", "default": "default",
"info": "Info", "info": "Info",
"running_version": "You are running Woodpecker {0}", "running_version": "You are running Woodpecker {0}",
@ -520,5 +460,6 @@
"cli_login_success": "Login to CLI successful", "cli_login_success": "Login to CLI successful",
"cli_login_failed": "Login to CLI failed", "cli_login_failed": "Login to CLI failed",
"cli_login_denied": "Login to CLI denied", "cli_login_denied": "Login to CLI denied",
"return_to_cli": "You can now close this tab and return to the CLI." "return_to_cli": "You can now close this tab and return to the CLI.",
"settings": "Settings"
} }

View file

@ -1,24 +1,18 @@
<template> <template>
<Settings <Settings
:title="$t('admin.settings.secrets.secrets')" :title="$t('secrets.secrets')"
:desc="$t('admin.settings.secrets.desc')" :desc="$t('admin.settings.secrets.desc')"
docs-url="docs/usage/secrets" docs-url="docs/usage/secrets"
:warning="$t('admin.settings.secrets.warning')" :warning="$t('admin.settings.secrets.warning')"
> >
<template #titleActions> <template #titleActions>
<Button <Button v-if="selectedSecret" :text="$t('secrets.show')" start-icon="back" @click="selectedSecret = undefined" />
v-if="selectedSecret" <Button v-else :text="$t('secrets.add')" start-icon="plus" @click="showAddSecret" />
:text="$t('admin.settings.secrets.show')"
start-icon="back"
@click="selectedSecret = undefined"
/>
<Button v-else :text="$t('admin.settings.secrets.add')" start-icon="plus" @click="showAddSecret" />
</template> </template>
<SecretList <SecretList
v-if="!selectedSecret" v-if="!selectedSecret"
v-model="secrets" v-model="secrets"
i18n-prefix="admin.settings.secrets."
:is-deleting="isDeleting" :is-deleting="isDeleting"
@edit="editSecret" @edit="editSecret"
@delete="deleteSecret" @delete="deleteSecret"
@ -27,7 +21,6 @@
<SecretEdit <SecretEdit
v-else v-else
v-model="selectedSecret" v-model="selectedSecret"
i18n-prefix="admin.settings.secrets."
:is-saving="isSaving" :is-saving="isSaving"
@save="createSecret" @save="createSecret"
@cancel="selectedSecret = undefined" @cancel="selectedSecret = undefined"
@ -81,7 +74,7 @@ const { doSubmit: createSecret, isLoading: isSaving } = useAsyncAction(async ()
await apiClient.createGlobalSecret(selectedSecret.value); await apiClient.createGlobalSecret(selectedSecret.value);
} }
notifications.notify({ notifications.notify({
title: i18n.t(isEditingSecret.value ? 'admin.settings.secrets.saved' : 'admin.settings.secrets.created'), title: i18n.t(isEditingSecret.value ? 'secrets.saved' : 'secrets.created'),
type: 'success', type: 'success',
}); });
selectedSecret.value = undefined; selectedSecret.value = undefined;
@ -90,7 +83,7 @@ const { doSubmit: createSecret, isLoading: isSaving } = useAsyncAction(async ()
const { doSubmit: deleteSecret, isLoading: isDeleting } = useAsyncAction(async (_secret: Secret) => { const { doSubmit: deleteSecret, isLoading: isDeleting } = useAsyncAction(async (_secret: Secret) => {
await apiClient.deleteGlobalSecret(_secret.name); await apiClient.deleteGlobalSecret(_secret.name);
notifications.notify({ title: i18n.t('admin.settings.secrets.deleted'), type: 'success' }); notifications.notify({ title: i18n.t('secrets.deleted'), type: 'success' });
resetPage(); resetPage();
}); });

View file

@ -20,12 +20,7 @@
</div> </div>
<div class="flex ml-auto -m-1.5 items-center space-x-2"> <div class="flex ml-auto -m-1.5 items-center space-x-2">
<div v-if="user?.admin" class="relative"> <div v-if="user?.admin" class="relative">
<IconButton <IconButton class="navbar-icon" :title="$t('settings')" :to="{ name: 'admin-settings' }" icon="settings" />
class="navbar-icon"
:title="$t('admin.settings.settings')"
:to="{ name: 'admin-settings' }"
icon="settings"
/>
<div <div
v-if="version?.needsUpdate" v-if="version?.needsUpdate"
class="absolute top-2 right-2 bg-int-wp-state-error-100 rounded-full w-3 h-3" class="absolute top-2 right-2 bg-int-wp-state-error-100 rounded-full w-3 h-3"

View file

@ -1,23 +1,13 @@
<template> <template>
<Settings <Settings :title="$t('secrets.secrets')" :desc="$t('org.settings.secrets.desc')" docs-url="docs/usage/secrets">
:title="$t('org.settings.secrets.secrets')"
:desc="$t('org.settings.secrets.desc')"
docs-url="docs/usage/secrets"
>
<template #titleActions> <template #titleActions>
<Button <Button v-if="selectedSecret" :text="$t('secrets.show')" start-icon="back" @click="selectedSecret = undefined" />
v-if="selectedSecret" <Button v-else :text="$t('secrets.add')" start-icon="plus" @click="showAddSecret" />
:text="$t('org.settings.secrets.show')"
start-icon="back"
@click="selectedSecret = undefined"
/>
<Button v-else :text="$t('org.settings.secrets.add')" start-icon="plus" @click="showAddSecret" />
</template> </template>
<SecretList <SecretList
v-if="!selectedSecret" v-if="!selectedSecret"
v-model="secrets" v-model="secrets"
i18n-prefix="org.settings.secrets."
:is-deleting="isDeleting" :is-deleting="isDeleting"
@edit="editSecret" @edit="editSecret"
@delete="deleteSecret" @delete="deleteSecret"
@ -26,7 +16,6 @@
<SecretEdit <SecretEdit
v-else v-else
v-model="selectedSecret" v-model="selectedSecret"
i18n-prefix="org.settings.secrets."
:is-saving="isSaving" :is-saving="isSaving"
@save="createSecret" @save="createSecret"
@cancel="selectedSecret = undefined" @cancel="selectedSecret = undefined"
@ -89,7 +78,7 @@ const { doSubmit: createSecret, isLoading: isSaving } = useAsyncAction(async ()
await apiClient.createOrgSecret(org.value.id, selectedSecret.value); await apiClient.createOrgSecret(org.value.id, selectedSecret.value);
} }
notifications.notify({ notifications.notify({
title: i18n.t(isEditingSecret.value ? 'org.settings.secrets.saved' : 'org.settings.secrets.created'), title: i18n.t(isEditingSecret.value ? 'secrets.saved' : 'secrets.created'),
type: 'success', type: 'success',
}); });
selectedSecret.value = undefined; selectedSecret.value = undefined;
@ -102,7 +91,7 @@ const { doSubmit: deleteSecret, isLoading: isDeleting } = useAsyncAction(async (
} }
await apiClient.deleteOrgSecret(org.value.id, _secret.name); await apiClient.deleteOrgSecret(org.value.id, _secret.name);
notifications.notify({ title: i18n.t('org.settings.secrets.deleted'), type: 'success' }); notifications.notify({ title: i18n.t('secrets.deleted'), type: 'success' });
resetPage(); resetPage();
}); });

View file

@ -1,23 +1,13 @@
<template> <template>
<Settings <Settings :title="$t('secrets.secrets')" :desc="$t('secrets.desc')" docs-url="docs/usage/secrets">
:title="$t('repo.settings.secrets.secrets')"
:desc="$t('repo.settings.secrets.desc')"
docs-url="docs/usage/secrets"
>
<template #titleActions> <template #titleActions>
<Button <Button v-if="selectedSecret" :text="$t('secrets.show')" start-icon="back" @click="selectedSecret = undefined" />
v-if="selectedSecret" <Button v-else :text="$t('secrets.add')" start-icon="plus" @click="showAddSecret" />
:text="$t('repo.settings.secrets.show')"
start-icon="back"
@click="selectedSecret = undefined"
/>
<Button v-else :text="$t('repo.settings.secrets.add')" start-icon="plus" @click="showAddSecret" />
</template> </template>
<SecretList <SecretList
v-if="!selectedSecret" v-if="!selectedSecret"
:model-value="secrets" :model-value="secrets"
i18n-prefix="repo.settings.secrets."
:is-deleting="isDeleting" :is-deleting="isDeleting"
@edit="editSecret" @edit="editSecret"
@delete="deleteSecret" @delete="deleteSecret"
@ -26,7 +16,6 @@
<SecretEdit <SecretEdit
v-else v-else
v-model="selectedSecret" v-model="selectedSecret"
i18n-prefix="repo.settings.secrets."
:is-saving="isSaving" :is-saving="isSaving"
@save="createSecret" @save="createSecret"
@cancel="selectedSecret = undefined" @cancel="selectedSecret = undefined"
@ -129,7 +118,7 @@ const { doSubmit: createSecret, isLoading: isSaving } = useAsyncAction(async ()
await apiClient.createSecret(repo.value.id, selectedSecret.value); await apiClient.createSecret(repo.value.id, selectedSecret.value);
} }
notifications.notify({ notifications.notify({
title: i18n.t(isEditingSecret.value ? 'repo.settings.secrets.saved' : 'repo.settings.secrets.created'), title: i18n.t(isEditingSecret.value ? 'secrets.saved' : 'secrets.created'),
type: 'success', type: 'success',
}); });
selectedSecret.value = undefined; selectedSecret.value = undefined;
@ -142,7 +131,7 @@ const { doSubmit: deleteSecret, isLoading: isDeleting } = useAsyncAction(async (
} }
await apiClient.deleteSecret(repo.value.id, _secret.name); await apiClient.deleteSecret(repo.value.id, _secret.name);
notifications.notify({ title: i18n.t('repo.settings.secrets.deleted'), type: 'success' }); notifications.notify({ title: i18n.t('secrets.deleted'), type: 'success' });
await resetPage(); await resetPage();
}); });

View file

@ -1,28 +1,28 @@
<template> <template>
<div v-if="innerValue" class="space-y-4"> <div v-if="innerValue" class="space-y-4">
<form @submit.prevent="save"> <form @submit.prevent="save">
<InputField v-slot="{ id }" :label="$t(i18nPrefix + 'name')"> <InputField v-slot="{ id }" :label="$t('secrets.name')">
<TextField <TextField
:id="id" :id="id"
v-model="innerValue.name" v-model="innerValue.name"
:placeholder="$t(i18nPrefix + 'name')" :placeholder="$t('secrets.name')"
required required
:disabled="isEditingSecret" :disabled="isEditingSecret"
/> />
</InputField> </InputField>
<InputField v-slot="{ id }" :label="$t(i18nPrefix + 'value')"> <InputField v-slot="{ id }" :label="$t('secrets.value')">
<TextField <TextField
:id="id" :id="id"
v-model="innerValue.value" v-model="innerValue.value"
:placeholder="$t(i18nPrefix + 'value')" :placeholder="$t('secrets.value')"
:lines="5" :lines="5"
:required="!isEditingSecret" :required="!isEditingSecret"
/> />
</InputField> </InputField>
<InputField v-slot="{ id }" :label="$t(i18nPrefix + 'images.images')"> <InputField v-slot="{ id }" :label="$t('secrets.images.images')">
<span class="ml-1 mb-2 text-wp-text-alt-100">{{ $t(i18nPrefix + 'images.desc') }}</span> <span class="ml-1 mb-2 text-wp-text-alt-100">{{ $t('secrets.images.desc') }}</span>
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">
<div v-for="image in innerValue.images" :key="image" class="flex gap-2"> <div v-for="image in innerValue.images" :key="image" class="flex gap-2">
@ -36,7 +36,7 @@
</div> </div>
</InputField> </InputField>
<InputField :label="$t(i18nPrefix + 'events.events')"> <InputField :label="$t('secrets.events.events')">
<CheckboxesField v-model="innerValue.events" :options="secretEventsOptions" /> <CheckboxesField v-model="innerValue.events" :options="secretEventsOptions" />
</InputField> </InputField>
@ -46,7 +46,7 @@
type="submit" type="submit"
color="green" color="green"
:is-loading="isSaving" :is-loading="isSaving"
:text="isEditingSecret ? $t(i18nPrefix + 'save') : $t(i18nPrefix + 'add')" :text="isEditingSecret ? $t('secrets.save') : $t('secrets.add')"
/> />
</div> </div>
</form> </form>
@ -67,7 +67,6 @@ import { Secret, WebhookEvents } from '~/lib/api/types';
const props = defineProps<{ const props = defineProps<{
modelValue: Partial<Secret>; modelValue: Partial<Secret>;
isSaving: boolean; isSaving: boolean;
i18nPrefix: string;
}>(); }>();
const emit = defineEmits<{ const emit = defineEmits<{
@ -106,7 +105,7 @@ const secretEventsOptions: CheckboxOption[] = [
{ {
value: WebhookEvents.PullRequest, value: WebhookEvents.PullRequest,
text: i18n.t('repo.pipeline.event.pr'), text: i18n.t('repo.pipeline.event.pr'),
description: i18n.t('repo.settings.secrets.events.pr_warning'), description: i18n.t('secrets.events.pr_warning'),
}, },
{ value: WebhookEvents.Deploy, text: i18n.t('repo.pipeline.event.deploy') }, { value: WebhookEvents.Deploy, text: i18n.t('repo.pipeline.event.deploy') },
{ value: WebhookEvents.Cron, text: i18n.t('repo.pipeline.event.cron') }, { value: WebhookEvents.Cron, text: i18n.t('repo.pipeline.event.cron') },

View file

@ -18,20 +18,20 @@
<IconButton <IconButton
icon="edit" icon="edit"
class="ml-2 <md:ml-auto w-8 h-8" class="ml-2 <md:ml-auto w-8 h-8"
:title="$t('repo.settings.secrets.edit')" :title="$t('secrets.edit')"
@click="editSecret(secret)" @click="editSecret(secret)"
/> />
<IconButton <IconButton
icon="trash" icon="trash"
class="ml-2 w-8 h-8 hover:text-wp-control-error-100" class="ml-2 w-8 h-8 hover:text-wp-control-error-100"
:is-loading="isDeleting" :is-loading="isDeleting"
:title="$t('repo.settings.secrets.delete')" :title="$t('secrets.delete')"
@click="deleteSecret(secret)" @click="deleteSecret(secret)"
/> />
</template> </template>
</ListItem> </ListItem>
<div v-if="secrets?.length === 0" class="ml-2">{{ $t(i18nPrefix + 'none') }}</div> <div v-if="secrets?.length === 0" class="ml-2">{{ $t('secrets.none') }}</div>
</div> </div>
</template> </template>
@ -47,7 +47,6 @@ import { Secret } from '~/lib/api/types';
const props = defineProps<{ const props = defineProps<{
modelValue: (Secret & { edit?: boolean })[]; modelValue: (Secret & { edit?: boolean })[];
isDeleting: boolean; isDeleting: boolean;
i18nPrefix: string;
}>(); }>();
const emit = defineEmits<{ const emit = defineEmits<{

View file

@ -1,12 +1,12 @@
<template> <template>
<Scaffold enable-tabs> <Scaffold enable-tabs>
<template #title> <template #title>
{{ $t('repo.settings.settings') }} {{ $t('settings') }}
</template> </template>
<Tab id="info" :title="$t('info')"> <Tab id="info" :title="$t('info')">
<AdminInfoTab /> <AdminInfoTab />
</Tab> </Tab>
<Tab id="secrets" :title="$t('admin.settings.secrets.secrets')"> <Tab id="secrets" :title="$t('secrets.secrets')">
<AdminSecretsTab /> <AdminSecretsTab />
</Tab> </Tab>
<Tab id="repos" :title="$t('admin.settings.repos.repos')"> <Tab id="repos" :title="$t('admin.settings.repos.repos')">

View file

@ -9,7 +9,7 @@
v-if="orgPermissions.admin" v-if="orgPermissions.admin"
icon="settings" icon="settings"
:to="{ name: org.is_user ? 'user' : 'org-settings' }" :to="{ name: org.is_user ? 'user' : 'org-settings' }"
:title="$t('org.settings.settings')" :title="$t('settings')"
/> />
</template> </template>

View file

@ -6,11 +6,11 @@
{{ org.name }} {{ org.name }}
</router-link> </router-link>
/ /
{{ $t('org.settings.settings') }} {{ $t('settings') }}
</span> </span>
</template> </template>
<Tab id="secrets" :title="$t('org.settings.secrets.secrets')"> <Tab id="secrets" :title="$t('secrets.secrets')">
<OrgSecretsTab /> <OrgSecretsTab />
</Tab> </Tab>
</Scaffold> </Scaffold>

View file

@ -8,7 +8,7 @@
<IconButton <IconButton
v-if="orgPermissions.admin" v-if="orgPermissions.admin"
:to="{ name: org.is_user ? 'user' : 'repo-settings' }" :to="{ name: org.is_user ? 'user' : 'repo-settings' }"
:title="$t('org.settings.settings')" :title="$t('settings')"
icon="settings" icon="settings"
/> />
</template> </template>

View file

@ -10,14 +10,14 @@
{{ repo.name }} {{ repo.name }}
</router-link> </router-link>
/ /
{{ $t('repo.settings.settings') }} {{ $t('settings') }}
</span> </span>
</template> </template>
<Tab id="general" :title="$t('repo.settings.general.general')"> <Tab id="general" :title="$t('repo.settings.general.general')">
<GeneralTab /> <GeneralTab />
</Tab> </Tab>
<Tab id="secrets" :title="$t('repo.settings.secrets.secrets')"> <Tab id="secrets" :title="$t('secrets.secrets')">
<SecretsTab /> <SecretsTab />
</Tab> </Tab>
<Tab id="registries" :title="$t('repo.settings.registries.registries')"> <Tab id="registries" :title="$t('repo.settings.registries.registries')">

View file

@ -21,7 +21,7 @@
<IconButton <IconButton
v-if="repoPermissions.admin" v-if="repoPermissions.admin"
:to="{ name: 'repo-settings' }" :to="{ name: 'repo-settings' }"
:title="$t('repo.settings.settings')" :title="$t('settings')"
icon="settings" icon="settings"
/> />
</template> </template>