Merge pull request #316 from Axolotle/enh-vuejs

Port to Vue.js
This commit is contained in:
Alexandre Aubin 2021-01-19 22:51:18 +01:00 committed by GitHub
commit 2cfe92d092
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
198 changed files with 23142 additions and 18266 deletions

9
.gitignore vendored
View file

@ -1,3 +1,4 @@
.env
*.swp
*~
@ -7,8 +8,12 @@ debian/files
debian/yunohost-admin*
# npm files
src/node_modules
src/npm-debug.log
node_modules
npm-debug.log
dist
# old
# Symlink to ca.crt file
ca.crt

View file

@ -2,8 +2,8 @@ language: node_js
node_js:
- "10"
before_install:
- cd src
- cd app
script:
- npm ci
- gulp build --dev
- gulp lint --dev
- npm run lint
- npm run build

View file

@ -16,26 +16,27 @@ Please report issues on the [YunoHost bugtracker](https://github.com/YunoHost/is
Feel free to improve the plugin and send a pull request.
`gulp` is used to compile Less files and minify the JavaScript. Assuming [nodejs](http://nodejs.org/) is installed, you can install dependencies and run a build with:
In order to contribute you will need to setup a development environment using [ynh-dev](https://github.com/YunoHost/ynh-dev) (see the README).
Once you have a environment running and are attached to it (with `./ynh-dev start`) you will be able to run:
```sh
cd src
npm install
npm run build
```
$ ./ynh-dev use-git yunohost-admin
```
Alternatively you can run `npm run build-dev`, which improves building speed by bypassing compression tasks.
This command will install all dependencies and start a dev server (based on [webpack-dev-server](https://github.com/webpack/webpack-dev-server)) with Hot-Module-Replacement (live updates on code modification without reloading the page nor rebuilding the whole code). After the build step, click on the "Network:" link and you are good to go.
You can also install [Vue Devtools](https://addons.mozilla.org/fr/firefox/addon/vue-js-devtools/) (module for Firefox but also exists for Chromium/Chrome) if you want component trees, performance views and so on.
On a YunoHost instance, the web admin files are located at `/usr/share/yunohost/admin`.
**Note:** The `.ms` - moustache - files are cached by the browser. You have to
reach them manually, and sometimes you modify them. (e.g. go to
https://example.com/yunohost/admin/views/domain/domain_list.ms)
## Dependencies
* Bootstrap 3.3.6
* Font-Awesome 4.5.0
* Handlebars 1.3.0
* Sammy 0.7.6
* JS-cookie 2.1.0
* [Vue.js](https://vuejs.org/v2/guide/)
* [BootstrapVue](https://bootstrap-vue.org/docs)
* [Vue i18n](https://kazupon.github.io/vue-i18n/started.html)
* [Vue Router](https://router.vuejs.org/guide/)
* [Vuex](https://vuex.vuejs.org/)
* [Vuelidate](https://vuelidate.js.org/#getting-started)
* [date-fns](https://date-fns.org/v2.16.1/docs/Getting-Started)
* [Fork Awesome](https://forkaweso.me/Fork-Awesome/icons/) for icons
* [FiraGO](https://bboxtype.com/typefaces/FiraGO/#!layout=specimen) and [Fira Code](https://github.com/tonsky/FiraCode) for fonts

5
app/babel.config.js Normal file
View file

@ -0,0 +1,5 @@
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}

12867
app/package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

99
app/package.json Normal file
View file

@ -0,0 +1,99 @@
{
"name": "yunohost-admin",
"version": "0.1.0",
"private": true,
"description": "YunoHost Admin web interface",
"author": "Yunohost",
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint --no-fix",
"i18n": "vue-cli-service i18n:report --src './src/**/*.?(js|vue)' --locales './src/i18n/locales/*.json'",
"i18n:en": "vue-cli-service i18n:report --src './src/**/*.?(js|vue)' --locales './src/i18n/locales/en.json'"
},
"dependencies": {
"bootstrap-vue": "^2.20.1",
"core-js": "^3.6.5",
"date-fns": "^2.16.1",
"firacode": "^5.2.0",
"fontsource-firago": "^3.0.2",
"fork-awesome": "^1.1.7",
"vue": "^2.6.12",
"vue-i18n": "^8.22.1",
"vue-router": "^3.4.8",
"vuelidate": "^0.7.6",
"vuex": "^3.4.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.4.0",
"@vue/cli-plugin-eslint": "~4.4.0",
"@vue/cli-plugin-router": "^4.5.8",
"@vue/cli-plugin-vuex": "^4.5.8",
"@vue/cli-service": "~4.4.0",
"babel-eslint": "^10.1.0",
"bootstrap": "^4.5.2",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^6.2.2",
"popper.js": "^1.16.0",
"portal-vue": "^2.1.6",
"sass": "^1.28.0",
"sass-loader": "^8.0.0",
"sass-resources-loader": "^2.1.1",
"standard": "^14.3.4",
"vue-cli-plugin-bootstrap-vue": "~0.6.0",
"vue-cli-plugin-i18n": "~1.0.1",
"vue-template-compiler": "^2.6.12"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/strongly-recommended",
"eslint:recommended",
"standard"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {
"vue/max-attributes-per-line": [
"error",
{
"singleline": 3,
"multiline": {
"max": 3,
"allowFirstLine": true
}
}
],
"template-curly-spacing": "off",
"camelcase": "warn",
"indent": "off",
"no-irregular-whitespace": "off",
"no-unused-vars": "warn",
"quotes": "warn",
"no-multiple-empty-lines": [
"error",
{
"max": 2
}
]
}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
],
"bugs": {
"url": "https://github.com/YunoHost/issues"
},
"homepage": "https://github.com/YunoHost/yunohost-admin",
"license": "AGPL-3.0",
"repository": {
"type": "git",
"url": "https://github.com/YunoHost/yunohost-admin"
}
}

View file

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

19
app/public/index.html Normal file
View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta name="format-detection" content="telephone=no" />
<meta name="robots" content="noindex, nofollow">
<link rel="icon" href="<%= BASE_URL %>favicon.png">
<title>YunoHost Admin</title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

230
app/src/App.vue Normal file
View file

@ -0,0 +1,230 @@
<template>
<div id="app" class="container">
<!-- HEADER -->
<header>
<b-navbar>
<b-navbar-brand
:to="{ name: 'home' }" :disabled="waiting"
exact exact-active-class="active"
>
<img alt="Yunohost logo" src="./assets/logo.png">
</b-navbar-brand>
<b-navbar-nav class="ml-auto">
<li class="nav-item">
<b-button
href="/yunohost/sso"
variant="primary" size="sm" block
>
{{ $t('user_interface_link') }} <icon iname="user" />
</b-button>
</li>
<li class="nav-item" v-show="connected">
<b-button
@click.prevent="logout"
variant="outline-dark" block size="sm"
>
{{ $t('logout') }} <icon iname="sign-out" />
</b-button>
</li>
</b-navbar-nav>
</b-navbar>
</header>
<!-- MAIN -->
<api-wait-overlay>
<breadcrumb />
<main id="main">
<!-- The `key` on router-view make sure that if a link points to a page that
use the same component as the previous one, it will be refreshed -->
<transition v-if="transitions" :name="transitionName">
<router-view class="animated" :key="$route.fullPath" />
</transition>
<router-view v-else class="static" :key="$route.fullPath" />
</main>
</api-wait-overlay>
<!-- CONSOLE/HISTORY -->
<ynh-console />
<!-- FOOTER -->
<footer class="py-3 mt-auto">
<nav>
<b-nav class="justify-content-center">
<b-nav-item href="https://yunohost.org/docs" target="_blank" link-classes="text-secondary">
<icon iname="book" /> {{ $t('footer.documentation') }}
</b-nav-item>
<b-nav-item href="https://yunohost.org/help" target="_blank" link-classes="text-secondary">
<icon iname="life-ring" /> {{ $t('footer.help') }}
</b-nav-item>
<b-nav-item href="https://donate.yunohost.org/" target="_blank" link-classes="text-secondary">
<icon iname="heart" /> {{ $t('footer.donate') }}
</b-nav-item>
<b-nav-text
v-if="yunohost" id="yunohost-version" class="ml-md-auto text-center"
v-html="$t('footer_version', yunohost)"
/>
</b-nav>
</nav>
</footer>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import ApiWaitOverlay from '@/components/ApiWaitOverlay'
import YnhConsole from '@/components/YnhConsole'
export default {
name: 'App',
data () {
return {
transitionName: null
}
},
computed: {
...mapGetters(['connected', 'yunohost', 'transitions', 'waiting'])
},
watch: {
// Set the css class to animate the components transition
'$route' (to, from) {
if (!this.transitions || from.name === null) return
// Use the breadcrumb array length as a direction indicator
const toDepth = to.meta.breadcrumb.length
const fromDepth = from.meta.breadcrumb.length
this.transitionName = toDepth < fromDepth ? 'slide-right' : 'slide-left'
}
},
methods: {
async logout () {
this.$store.dispatch('LOGOUT')
}
},
components: {
ApiWaitOverlay,
YnhConsole
},
// This hook is only triggered at page first load
created () {
// From this hook the value of `connected` always come from the localStorage.
// This state may be `true` but session may have expired, by querying
// yunohost infos, api may respond with `Unauthorized` in which case the `connected`
// state will be automaticly reseted and user will be prompt with the login view.
if (this.connected) {
this.$store.dispatch('GET_YUNOHOST_INFOS')
}
},
mounted () {
// Konamicode ;P
const konamiCode = ['ArrowUp', 'ArrowUp', 'ArrowDown', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'ArrowLeft', 'ArrowRight', 'b', 'a']
let step = 0
document.addEventListener('keydown', ({ key }) => {
if (key === konamiCode[step++]) {
if (step === konamiCode.length) {
this.$store.commit('SET_SPINNER', 'nyancat')
step = 0
}
} else {
step = 0
}
})
// April fools easter egg ;)
const today = new Date()
if (today.getDate() === 1 && today.getMonth() + 1 === 4) {
this.$store.commit('SET_SPINNER', 'magikarp')
}
}
}
</script>
<style lang="scss">
// Global import of Bootstrap and custom styles
@import '@/scss/main.scss';
</style>
<style lang="scss" scoped>
// generic style for <html>, <body> and <#app> is in `scss/main.scss`
header {
border-bottom: $thin-border;
padding-top: 1rem;
margin-bottom: 1rem;
.navbar {
padding: 1rem 0;
img {
width: 70px;
}
.navbar-nav {
flex-direction: column;
li {
margin: .2rem 0;
}
}
}
}
main {
position: relative;
// Routes transition
.animated {
transition: all .15s ease-in-out;
}
.slide-left-enter, .slide-right-leave-active {
position: absolute;
width: 100%;
top: 0;
transform: translate(100vw, 0);
}
.slide-left-leave-active, .slide-right-enter {
position: absolute;
width: 100%;
top: 0;
transform: translate(-100vw, 0);
}
// hack to hide last transition provoqued by the <router-view> element change
// while disabling the transitions in ToolWebAdmin
.static ~ .animated {
display: none;
}
}
#console {
// Allows the console to be tabbed before the footer links while remaining visually
// the last element of the page
order: 3;
}
footer {
border-top: 1px solid #eee;
font-size: $font-size-sm;
margin-top: 2rem;
.nav-item {
& + .nav-item a::before {
content: "•";
width: 1rem;
display: inline-block;
margin-left: -1.15rem;
}
&:first-child {
margin-left: -1rem;
}
}
}
</style>

127
app/src/api/api.js Normal file
View file

@ -0,0 +1,127 @@
/**
* API module.
* @module api
*/
import store from '@/store'
import { handleResponse } from './handlers'
import { objectToParams } from '@/helpers/commons'
/**
* A digested fetch response as an object, a string or an error.
* @typedef {(Object|string|Error)} DigestedResponse
*/
export default {
options: {
credentials: 'include',
mode: 'cors',
headers: {
// FIXME is it important to keep this previous `Accept` header ?
// 'Accept': 'application/json, text/javascript, */*; q=0.01',
// Auto header is :
// "Accept": "*/*",
// Also is this still important ? (needed by back-end)
'X-Requested-With': 'XMLHttpRequest'
}
},
/**
* Opens a WebSocket connection to the server in case it sends messages.
* Currently, the connection is closed by the server right after an API call so
* we have to open it for every calls.
* Messages are dispatch to the store so it can handle them.
*
* @return {Promise<Event>} Promise that resolve on websocket 'open' or 'error' event.
*/
openWebSocket () {
return new Promise(resolve => {
const ws = new WebSocket(`wss://${store.getters.host}/yunohost/api/messages`)
ws.onmessage = ({ data }) => store.dispatch('DISPATCH_MESSAGE', JSON.parse(data))
// ws.onclose = (e) => {}
ws.onopen = resolve
// Resolve also on error so the actual fetch may be called.
ws.onerror = resolve
})
},
/**
* Generic method to fetch the api without automatic response handling.
*
* @param {string} method - a method between 'GET', 'POST', 'PUT' and 'DELETE'.
* @param {string} uri
* @param {string} [data={}] - data to send as body for 'POST', 'PUT' and 'DELETE' methods.
* @return {Promise<Response>} Promise that resolve a fetch `Response`.
*/
async fetch (method, uri, data = {}) {
// Open a websocket connection that will dispatch messages received.
// FIXME add ability to do not open it
await this.openWebSocket()
if (method === 'GET') {
const localeQs = `${uri.includes('?') ? '&' : '?'}locale=${store.getters.locale}`
return fetch('/yunohost/api/' + uri + localeQs, this.options)
}
store.dispatch('WAITING_FOR_RESPONSE', [uri, method])
return fetch('/yunohost/api/' + uri, {
...this.options,
method,
body: objectToParams(data, { addLocale: true })
})
},
/**
* Api get helper function.
*
* @param {string} uri - the uri to call.
* @return {Promise<module:api~DigestedResponse>} Promise that resolve the api response as an object, a string or as an error.
*/
get (uri) {
return this.fetch('GET', uri).then(response => handleResponse(response, 'GET'))
},
/**
* Api get helper function for multiple queries.
*
* @param {string} uri - the uri to call.
* @return {Promise<module:api~DigestedResponse[]>} Promise that resolve the api responses as an array.
*/
getAll (uris) {
return Promise.all(uris.map(uri => this.get(uri)))
},
/**
* Api post helper function.
*
* @param {string} uri - the uri to call.
* @param {string} [data={}] - data to send as body.
* @return {Promise<module:api~DigestedResponse>} Promise that resolve the api responses as an array.
*/
post (uri, data = {}) {
return this.fetch('POST', uri, data).then(response => handleResponse(response, 'POST'))
},
/**
* Api put helper function.
*
* @param {string} uri - the uri to call.
* @param {string} [data={}] - data to send as body.
* @return {Promise<module:api~DigestedResponse>} Promise that resolve the api responses as an array.
*/
put (uri, data = {}) {
return this.fetch('PUT', uri, data).then(response => handleResponse(response, 'PUT'))
},
/**
* Api delete helper function.
*
* @param {string} uri - the uri to call.
* @param {string} [data={}] - data to send as body.
* @return {Promise<('ok'|Error)>} Promise that resolve the api responses as an array.
*/
delete (uri, data = {}) {
return this.fetch('DELETE', uri, data).then(response => handleResponse(response, 'DELETE'))
}
}

86
app/src/api/errors.js Normal file
View file

@ -0,0 +1,86 @@
/**
* API errors definitionss.
* @module api/errors
*/
import i18n from '@/i18n'
class APIError extends Error {
constructor (method, { url, status, statusText }, message) {
super(message || i18n.t('error_server_unexpected'))
this.uri = new URL(url).pathname.replace('/yunohost', '')
this.method = method
this.code = status
this.status = statusText
this.name = 'APIError'
}
print () {
console.error(`${this.name} (${this.code}): ${this.uri}\n${this.message}`)
}
}
// 401 — Unauthorized
class APIUnauthorizedError extends APIError {
constructor (method, response, message) {
super(method, response, i18n.t('unauthorized'))
this.name = 'APIUnauthorizedError'
}
}
// 400 — Bad Request
class APIBadRequestError extends APIError {
constructor (method, response, message) {
super(method, response, message)
this.name = 'APIBadRequestError'
}
}
// 500 — Server Internal Error
class APIInternalError extends APIError {
constructor (method, response, data) {
// not tested (message should be json but in )
const traceback = typeof data === 'object' ? data.traceback : null
super(method, response, 'none')
if (traceback) {
this.traceback = traceback
}
this.name = 'APIInternalError'
}
}
// 502 — Bad gateway (means API is down)
class APINotRespondingError extends APIError {
constructor (method, response) {
super(method, response, i18n.t('api_not_responding'))
this.name = 'APINotRespondingError'
}
}
// 0 — (means "the connexion has been closed" apparently)
class APIConnexionError extends APIError {
constructor (method, response) {
super(method, response, i18n.t('error_connection_interrupted'))
this.name = 'APIConnexionError'
}
}
// Temp factory
const errors = {
[undefined]: APIError,
0: APIConnexionError,
400: APIBadRequestError,
401: APIUnauthorizedError,
500: APIInternalError,
502: APINotRespondingError
}
export {
errors as default,
APIError,
APIUnauthorizedError,
APIBadRequestError,
APIInternalError,
APINotRespondingError,
APIConnexionError
}

66
app/src/api/handlers.js Normal file
View file

@ -0,0 +1,66 @@
/**
* API handlers.
* @module api/handlers
*/
import store from '@/store'
import errors from './errors'
import router from '@/router'
/**
* Try to get response content as json and if it's not as text.
*
* @param {Response} response - A fetch `Response` object.
* @return {(Object|String)} Parsed response's json or response's text.
*/
async function _getResponseContent (response) {
// FIXME the api should always return json as response
const responseText = await response.text()
try {
return JSON.parse(responseText)
} catch {
return responseText
}
}
/**
* Handler for API responses.
*
* @param {Response} response - A fetch `Response` object.
* @return {(Object|String)} Parsed response's json, response's text or an error.
*/
export function handleResponse (response, method) {
if (method !== 'GET') {
store.dispatch('SERVER_RESPONDED', response.ok)
}
if (!response.ok) return handleError(response, method)
// FIXME the api should always return json objects
return _getResponseContent(response)
}
/**
* Handler for API errors.
*
* @param {Response} response - A fetch `Response` object.
* @throws Will throw a custom error with response data.
*/
export async function handleError (response, method) {
const message = await _getResponseContent(response)
const errorCode = response.status in errors ? response.status : undefined
const error = new errors[errorCode](method, response, message.error || message)
if (error.code === 401) {
store.dispatch('DISCONNECT')
} else if (error.code === 400) {
if (typeof message !== 'string' && 'log_ref' in message) {
router.push({ name: 'tool-log', params: { name: message.log_ref } })
}
// Hide the waiting screen
store.dispatch('SERVER_RESPONDED', true)
} else {
store.dispatch('DISPATCH_ERROR', error)
}
throw error
}

2
app/src/api/index.js Normal file
View file

@ -0,0 +1,2 @@
export { default } from './api'
export { handleResponse, handleError } from './handlers'

View file

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

View file

Before

Width:  |  Height:  |  Size: 391 B

After

Width:  |  Height:  |  Size: 391 B

View file

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View file

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

View file

@ -0,0 +1,74 @@
<template>
<b-input-group v-bind="$attrs">
<input-item
:id="id" :placeholder="placeholder"
:state="state" :aria-describedby="id + 'local-part-desc'"
v-model="value.localPart"
v-on="listeners"
/>
<b-input-group-append>
<b-input-group-text>{{ value.separator }}</b-input-group-text>
</b-input-group-append>
<b-input-group-append>
<select-item
v-model="value.domain"
:choices="choices"
:aria-describedby="id + 'domain-desc'"
/>
</b-input-group-append>
<span class="sr-only" :id="id + 'local-part-desc'" v-t="'address.local_part_description.' + type" />
<span class="sr-only" :id="id + 'domain-desc'" v-t="'address.domain_description.' + type" />
</b-input-group>
</template>
<script>
export default {
name: 'AdressInputSelect',
inheritAttrs: false,
props: {
// `value` is actually passed thru the `v-model` directive
value: { type: Object, required: true },
choices: { type: Array, required: true },
placeholder: { type: String, default: null },
id: { type: String, default: null },
state: { type: null, default: null },
type: { type: String, default: 'email' }
},
computed: {
listeners: function () {
return Object.assign({},
// Forwards all parent events listeners
this.$listeners,
// Overwrite input behavior so this component can work with v-model
{
input: (event) => {
this.$parent.$emit('touch')
this.$emit('input', this.value)
},
blur: event => {
this.$parent.$emit('touch')
this.$emit('blur', this.value)
}
}
)
}
}
}
</script>
<style lang="scss" scoped>
.input-group-append ~ .input-group-append {
flex-basis: 40%;
}
select {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
</style>

View file

@ -0,0 +1,137 @@
<template>
<b-overlay
variant="white" rounded="sm" opacity="0.5"
no-center
:show="waiting"
>
<slot name="default" />
<template v-slot:overlay>
<b-card no-body>
<div v-if="!error" class="mt-3 px-3">
<div class="custom-spinner" :class="spinner" />
</div>
<b-card-body v-if="error">
<error-page />
</b-card-body>
<b-card-body v-else class="pb-4">
<b-card-title class="text-center m-0" v-t="'api_waiting'" />
<!-- PROGRESS BAR -->
<b-progress
v-if="progress" class="mt-4"
:max="progress.max" height=".5rem"
>
<b-progress-bar variant="success" :value="progress.values[0]" />
<b-progress-bar variant="warning" :value="progress.values[1]" animated />
<b-progress-bar variant="secondary" :value="progress.values[2]" striped />
</b-progress>
</b-card-body>
<b-card-footer v-if="error" class="justify-content-end">
<b-button variant="primary" v-t="'ok'" @click="$store.dispatch('SERVER_RESPONDED', true)" />
</b-card-footer>
</b-card>
</template>
</b-overlay>
</template>
<script>
import { mapGetters } from 'vuex'
import ErrorPage from '@/views/ErrorPage'
export default {
name: 'ApiWaitOverlay',
computed: {
...mapGetters(['waiting', 'lastAction', 'error', 'spinner']),
progress () {
if (!this.lastAction) return null
const progress = this.lastAction.progress
if (!progress) return null
return {
values: progress, max: progress.reduce((sum, value) => (sum + value), 0)
}
}
},
components: {
ErrorPage
}
}
</script>
<style lang="scss" scoped>
.card {
position: sticky;
top: 5vh;
margin: 0 5%;
@include media-breakpoint-up(md) {
margin: 0 10%;
}
@include media-breakpoint-up(lg) {
margin: 0 20%;
}
}
.card-body {
padding-bottom: 2rem;
max-height: 50vh;
overflow-y: auto;
}
.progress {
margin-top: 2rem;
}
.custom-spinner {
animation: 4s linear infinite;
background-repeat: no-repeat;
&.pacman {
height: 24px;
width: 24px;
background-image: url('../assets/spinners/pacman.gif');
animation-name: back-and-forth-pacman;
@keyframes back-and-forth-pacman {
0%, 100% { transform: scale(1); margin-left: 0; }
49% { transform: scale(1); margin-left: calc(100% - 24px);}
50% { transform: scale(-1); margin-left: calc(100% - 24px);}
99% { transform: scale(-1); margin-left: 0;}
}
}
&.magikarp {
height: 32px;
width: 32px;
background-image: url('../assets/spinners/magikarp.gif');
animation-name: back-and-forth-magikarp;
@keyframes back-and-forth-magikarp {
0%, 100% { transform: scale(1, 1); margin-left: 0; }
49% { transform: scale(1, 1); margin-left: calc(100% - 32px);}
50% { transform: scale(-1, 1); margin-left: calc(100% - 32px);}
99% { transform: scale(-1, 1); margin-left: 0;}
}
}
&.nyancat {
height: 40px;
width: 100px;
background-image: url('../assets/spinners/nyancat.gif');
animation-name: back-and-forth-nyancat;
@keyframes back-and-forth-nyancat {
0%, 100% { transform: scale(1, 1); margin-left: 0; }
49% { transform: scale(1, 1); margin-left: calc(100% - 100px);}
50% { transform: scale(-1, 1); margin-left: calc(100% - 100px);}
99% { transform: scale(-1, 1); margin-left: 0;}
}
}
}
</style>

View file

@ -0,0 +1,151 @@
<template>
<div class="selectize-base">
<b-input-group>
<b-input-group-prepend is-text>
<icon iname="search-plus" />
<span class="ml-1">{{ label }}</span>
</b-input-group-prepend>
<b-form-input
:class="visible ? null : 'collapsed'"
aria-controls="collapse" :aria-expanded="visible ? 'true' : 'false'"
@focus="onInputFocus" @blur="onInputBlur" @keydown="onInputKeydown"
v-model="search" ref="input"
/>
</b-input-group>
<b-collapse ref="collapse" v-model="visible">
<b-list-group tabindex="-1" @mouseover="onChoiceListOver" v-if="visible">
<b-list-group-item
v-for="(item, index) in filteredChoices" :key="item"
tabindex="-1" :active="index === focusedIndex" ref="choiceList"
@mousedown.prevent @mouseup.prevent="onSelect(item)"
>
{{ item | filter(format) }}
</b-list-group-item>
</b-list-group>
</b-collapse>
</div>
</template>
<script>
// FIXME add accessibility to ChoiceList
export default {
name: 'BaseSelectize',
props: {
choices: { type: Array, required: true },
label: { type: String, default: null },
// FIXME find a better way to pass filters
format: { type: Function, default: null }
},
data: () => ({
visible: false,
search: '',
focusedIndex: 0
}),
computed: {
filteredChoices () {
const search = this.search.toLowerCase()
return this.choices.filter(item => {
return item.toLowerCase().includes(search)
}).sort()
}
},
methods: {
onInputFocus ({ relatedTarget }) {
this.visible = true
this.focusedIndex = 0
// timeout needed else scrollIntoView won't work
if (!this.$refs.choiceList) return
setTimeout(() => {
this.$refs.choiceList[0].scrollIntoView({ behavior: 'instant', block: 'nearest', inline: 'nearest' })
}, 50)
},
onInputBlur ({ relatedTarget }) {
if (!this.$refs.collapse.$el.contains(relatedTarget)) {
this.visible = false
}
},
onInputKeydown (e) {
const { key } = e
const choicesLen = this.filteredChoices.length
if (choicesLen < 1) return
if (key === 'ArrowDown') {
e.preventDefault()
if (this.focusedIndex <= choicesLen) {
this.focusedIndex++
}
} else if (key === 'ArrowUp') {
e.preventDefault()
if (this.focusedIndex > 0) {
this.focusedIndex--
}
} else if (key === 'Enter') {
this.onSelect(this.filteredChoices[this.focusedIndex])
this.focusedIndex = 0
} else {
this.focusedIndex = 0
}
const elemToFocus = this.$refs.choiceList[this.focusedIndex]
if (elemToFocus) {
elemToFocus.scrollIntoView({ behavior: 'instant', block: 'nearest', inline: 'nearest' })
}
},
onChoiceListOver ({ target }) {
const index = this.$refs.choiceList.indexOf(target)
if (index > -1) {
this.focusedIndex = index
}
},
onSelect (item) {
this.$emit('selected', { item, index: this.choices.indexOf(item) })
}
},
filters: {
filter: function (text, func) {
if (func) return func(text)
else return text
}
}
}
</script>
<style lang="scss" scoped>
.collapse {
position: relative;
width: 100%;
}
// disable collapse animation
.collapsing {
-webkit-transition: none;
transition: none;
display: none;
}
.list-group {
margin-top: .5rem;
max-height: 10rem;
overflow-y: auto;
position: absolute;
z-index: 10;
width: 100%;
}
.list-group-item {
padding-top: 0;
padding-bottom: 0;
min-height: 2rem;
line-height: 1.75rem;
cursor: pointer;
}
</style>

View file

@ -0,0 +1,237 @@
<template>
<div id="console">
<b-list-group>
<!-- HISTORY BAR -->
<b-list-group-item
class="d-flex align-items-center"
:class="{ 'bg-best text-white': open }"
ref="history-button"
role="button" tabindex="0"
:aria-expanded="open ? 'true' : 'false'" aria-controls="console-collapse"
@mousedown.left.prevent="onHistoryBarClick"
@keyup.enter.space.prevent="open = !open"
>
<h6 class="m-0">
<icon iname="history" /> {{ $t('history.title') }}
</h6>
<div class="ml-auto">
<!-- LAST ACTION -->
<small v-if="lastAction">
<u v-t="'history.last_action'" />
{{ lastAction.uri | readableUri }} ({{ $t('history.methods.' + lastAction.method) }})
</small>
</div>
</b-list-group-item>
<!-- ACTION LIST -->
<b-collapse id="console-collapse" v-model="open">
<b-list-group-item
id="history" ref="history"
class="p-0" :class="{ 'show-last': openedByWaiting }"
>
<!-- ACTION -->
<b-list-group v-for="(action, i) in history" :key="i" flush>
<!-- ACTION DESC -->
<b-list-group-item class="sticky-top d-flex align-items-center">
<div>
<strong>{{ $t('action') }}:</strong>
{{ action.uri | readableUri }}
<small>({{ $t('history.methods.' + action.method) }})</small>
</div>
<time :datetime="action.date | hour" class="ml-auto">{{ action.date | hour }}</time>
</b-list-group-item>
<!-- ACTION MESSAGE -->
<b-list-group-item
v-for="({ type, text }, j) in action.messages" :key="j"
:variant="type" v-html="text"
/>
</b-list-group>
</b-list-group-item>
</b-collapse>
</b-list-group>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
name: 'YnhConsole',
props: {
value: { type: Boolean, default: false },
height: { type: [Number, String], default: 30 }
},
data () {
return {
open: false,
openedByWaiting: false
}
},
watch: {
open (value) {
// In case it is needed.
this.$emit('toggle', value)
if (value) {
// Wait for DOM update and scroll if needed.
this.$nextTick().then(this.scrollToLastAction)
}
},
'lastAction.messages' () {
if (!this.open) return
this.$nextTick(this.scrollToLastAction)
},
waiting (waiting) {
if (waiting && !this.open) {
// Open the history while waiting for the server's response to display WebSocket messages.
this.open = true
this.openedByWaiting = true
const history = this.$refs.history
this.$nextTick().then(() => {
history.style.height = ''
history.classList.add('with-max')
})
} else if (!waiting && this.openedByWaiting) {
// Automaticly close the history if it was not opened before the request
setTimeout(() => {
// Do not close it if the history was enlarged during the action
if (!history.style || history.style.height === '') {
this.open = false
}
this.openedByWaiting = false
}, 500)
}
}
},
computed: mapGetters(['history', 'lastAction', 'waiting']),
methods: {
scrollToLastAction () {
const historyElem = this.$refs.history
const lastActionGroup = historyElem.lastElementChild
if (lastActionGroup) {
const lastItem = lastActionGroup.lastElementChild || lastActionGroup
historyElem.scrollTop = lastItem.offsetTop
}
},
onHistoryBarClick (e) {
const history = this.$refs.history
let mousePos = e.clientY
const onMouseMove = ({ clientY }) => {
if (!this.open) {
history.style.height = '0px'
this.open = true
}
const currentHeight = history.offsetHeight
const move = mousePos - clientY
const nextSize = currentHeight + move
if (nextSize < 10 && nextSize < currentHeight) {
// Close the console and reset its size if the user reduce it to less than 10px.
mousePos = e.clientY
history.style.height = ''
onMouseUp()
} else {
history.style.height = nextSize + 'px'
// Simulate scroll when reducing the box so the content doesn't move
if (nextSize < currentHeight) {
history.scrollBy(0, -move)
}
mousePos = clientY
}
}
// Delay the mouse move listener to distinguish a click from a drag.
const listenToMouseMove = setTimeout(() => {
history.style.height = history.offsetHeight + 'px'
history.classList.remove('with-max')
window.addEventListener('mousemove', onMouseMove)
}, 200)
const onMouseUp = () => {
// Toggle opening if no mouse movement
if (mousePos === e.clientY) {
// add a max-height class if the box's height is not custom
if (!history.style.height) {
history.classList.add('with-max')
}
this.open = !this.open
}
clearTimeout(listenToMouseMove)
window.removeEventListener('mousemove', onMouseMove)
window.removeEventListener('mouseup', onMouseUp)
}
window.addEventListener('mouseup', onMouseUp)
}
},
filters: {
readableUri (uri) {
return uri.split('?')[0].replace('/', ' > ')
},
hour (date) {
return new Date(date).toLocaleTimeString()
}
}
}
</script>
<style lang="scss" scoped>
#console {
position: sticky;
z-index: 15;
bottom: 0;
margin-left: -1.5rem;
width: calc(100% + 3rem);
@include media-breakpoint-down(xs) {
margin-left: -15px;
width: calc(100% + 30px);
& > .list-group {
border-radius: 0;
}
}
}
#console-collapse {
// disable collapse animation
transition: none !important;
}
#history {
overflow-y: auto;
&.with-max {
max-height: 30vh;
}
// Used to display only the last message of the last action while an action is triggered
// and console was not opened.
&.with-max.show-last {
& > :not(:last-child) {
display: none;
}
& > :last-child > :not(:last-child) {
display: none;
}
}
}
.list-group-item {
font-size: $font-size-sm;
padding: $tooltip-padding-y $tooltip-padding-x;
}
</style>

View file

@ -0,0 +1,99 @@
<template lang="html">
<div class="selectize-zone">
<div id="selected-items" v-if="selected.length > 0">
<b-button-group size="sm" v-for="item in filteredSelected" :key="item">
<b-button :variant="itemVariant" :to="itemRoute ? {name: itemRoute, params: {name: item}} : null" class="item-btn">
<icon :iname="itemIcon" /> {{ item | filter(format) }}
</b-button>
<b-button
v-if="!removable || removable(item)"
class="remove-btn" variant="warning"
@click="onRemove(item)"
>
<icon :title="$t('delete')" iname="minus" />
</b-button>
</b-button-group>
</div>
<base-selectize
v-if="choices.length"
:choices="choices"
:format="format"
:label="label"
@selected="$emit('change', { ...$event, action: 'add' })"
/>
</div>
</template>
<script>
import BaseSelectize from '@/components/BaseSelectize'
export default {
name: 'ZoneSelectize',
props: {
itemIcon: { type: String, default: null },
itemRoute: { type: String, default: null },
itemVariant: { type: String, default: 'secondary' },
selected: { type: Array, required: true },
// needed by SelectizeBase
choices: { type: Array, required: true },
label: { type: String, default: null },
format: { type: Function, default: null },
removable: { type: Function, default: null }
},
data: () => ({
visible: false,
search: '',
focusedIndex: 0
}),
computed: {
filteredSelected () {
return [...this.selected].sort()
}
},
methods: {
onRemove (item) {
this.$emit('change', { item, index: this.selected.indexOf(item), action: 'remove' })
}
},
filters: {
filter: function (text, func) {
if (func) return func(text)
else return text
}
},
components: {
BaseSelectize
}
}
</script>
<style lang="scss" scoped>
#selected-items {
margin-bottom: .75rem;
display: flex;
flex-wrap: wrap;
.btn-group {
margin-right: .5rem;
margin-bottom: .5rem;
.item-btn {
.icon {
margin-right: .25rem;
}
}
}
}
.fa-minus {
position: relative;
top: 1px;
}
</style>

View file

@ -0,0 +1,62 @@
<template>
<b-breadcrumb v-if="routesList">
<b-breadcrumb-item to="/">
<span class="sr-only">{{ $t('home') }}</span>
<icon iname="home" />
</b-breadcrumb-item>
<b-breadcrumb-item
v-for="{ name, text } in breadcrumb" :key="name"
:to="{ name }" :active="name === $route.name"
>
{{ text }}
</b-breadcrumb-item>
</b-breadcrumb>
</template>
<script>
export default {
name: 'Breadcrumb',
computed: {
routesList () {
const routesList = this.$route.meta.breadcrumb
return routesList && routesList.length ? routesList : null
},
breadcrumb () {
if (!this.routesList) return
// Get current params to pass it to potential previous routes
const currentParams = this.$route.params
return this.routesList.map(name => {
const { trad, param } = this.getRouteArgs(name)
let text = ''
// if a traduction key string has been given and we also need to pass
// the route param as a variable.
if (trad && param) {
text = this.$i18n.t(trad, { [param]: currentParams[param] })
} else if (trad) {
text = this.$i18n.t(trad)
} else {
text = currentParams[param]
}
return { name, text }
})
}
},
methods: {
getRouteArgs (routeName) {
const route = this.$router.options.routes.find(route => route.name === routeName)
return route ? route.meta.args : {}
}
}
}
</script>
<style lang="scss" scoped>
.breadcrumb {
border: none;
background-color: transparent;
}
</style>

View file

@ -0,0 +1,92 @@
<template>
<b-card v-bind="$attrs" :no-body="collapsable ? true : $attrs['no-body']">
<template #header>
<div class="w-100 d-flex align-items-center flex-wrap custom-header">
<slot name="header">
<component :is="titleTag" class="custom-header-title">
<icon v-if="icon" :iname="icon" class="mr-2" />{{ title }}
</component>
</slot>
<div v-if="hasButtons" class="mt-2 w-100 custom-header-buttons" :class="{ [`ml-${buttonUnbreak}-auto mt-${buttonUnbreak}-0 w-${buttonUnbreak}-auto`]: buttonUnbreak }">
<slot name="header-buttons" />
</div>
</div>
<b-button
v-if="collapsable" @click="visible = !visible"
size="sm" variant="outline-secondary"
class="align-self-center ml-auto" :class="{ 'not-collapsed': visible, 'collapsed': !visible, [`ml-${buttonUnbreak}-2`]: buttonUnbreak }"
>
<icon iname="chevron-right" />
<span class="sr-only">{{ $t('words.collapse') }}</span>
</b-button>
</template>
<b-collapse v-if="collapsable" :visible="visible">
<slot v-if="('no-body' in $attrs)" name="default" />
<b-card-body v-else>
<slot name="default" />
</b-card-body>
</b-collapse>
<slot v-else name="default" slot="default" />
<slot name="footer" slot="footer">
<slot name="buttons" />
</slot>
</b-card>
</template>
<script>
export default {
name: 'Card',
props: {
id: { type: String, default: 'ynh-form' },
title: { type: String, default: null },
titleTag: { type: String, default: 'h2' },
icon: { type: String, default: null },
collapsable: { type: Boolean, default: false },
collapsed: { type: Boolean, default: false },
buttonUnbreak: { type: String, default: 'md' }
},
data () {
return {
visible: !this.collapsed
}
},
computed: {
hasButtons () {
return 'header-buttons' in this.$slots
}
}
}
</script>
<style lang="scss" scoped>
.card-header {
display: flex;
.custom-header {
& > :first-child {
margin-right: 1rem;
}
.btn + .btn {
margin-left: .5rem;
}
}
}
.card-footer {
display: flex;
justify-content: flex-end;
& > *:not(:first-child) {
margin-left: .5rem;
}
}
</style>

View file

@ -0,0 +1,64 @@
<template>
<card v-bind="$attrs" class="card-form">
<template #default>
<slot name="disclaimer" />
<b-form
:id="id" :inline="inline" :class="formClasses"
@submit.prevent="onSubmit" novalidate
>
<slot name="default" />
<slot name="server-error">
<b-alert variant="danger" :show="serverError !== ''" v-html="serverError" />
</slot>
</b-form>
</template>
<slot v-if="!noFooter" name="buttons" slot="buttons">
<b-button
type="submit" variant="success"
:form="id" :disabled="disabled"
>
{{ submitText ? submitText : $t('save') }}
</b-button>
</slot>
</card>
</template>
<script>
export default {
name: 'CardForm',
props: {
id: { type: String, default: 'ynh-form' },
submitText: { type: String, default: null },
validation: { type: Object, default: null },
serverError: { type: String, default: '' },
inline: { type: Boolean, default: false },
formClasses: { type: [Array, String, Object], default: null },
noFooter: { type: Boolean, default: false }
},
computed: {
disabled () {
return this.validation ? this.validation.$invalid : false
}
},
methods: {
onSubmit (e) {
const v = this.validation
if (v) {
v.$touch()
if (v.$pending || v.$invalid) return
}
this.$emit('submit', e)
}
}
}
</script>
<style lang="scss">
</style>

View file

@ -0,0 +1,143 @@
<template>
<!-- v-bind="$attrs" allow to pass default attrs not specified in this component slots -->
<b-form-group
v-bind="attrs"
:id="_id"
:label-for="$attrs['label-for'] || props.id"
:state="state"
@touch="touch"
>
<!-- Make field props and state available as scoped slot data -->
<slot v-bind="{ self: { ...props, state }, touch }">
<!-- if no component was passed as slot, render a component from the props -->
<component
:is="component"
v-bind="props"
v-on="$listeners"
:value="value"
:state="state"
:required="validation ? 'required' in validation : false"
/>
</slot>
<template #invalid-feedback>
<span v-html="errorMessage" />
</template>
<template #description>
<!-- Render description -->
<template v-if="description || example || link">
<div class="d-flex">
<span v-if="example">{{ $t('form_input_example', { example }) }}</span>
<b-link v-if="link" :to="link" class="ml-auto">
{{ link.text }}
</b-link>
</div>
<div
v-if="description" v-html="description"
:class="{ ['alert p-1 px-2 alert-' + descriptionVariant]: descriptionVariant }"
/>
</template>
<!-- Slot available to overwrite the one above -->
<slot name="description" />
</template>
</b-form-group>
</template>
<script>
export default {
name: 'FormField',
inheritAttrs: false,
props: {
// Component props (other <form-group> related attrs are passed thanks to $attrs)
id: { type: String, default: null },
description: { type: String, default: null },
descriptionVariant: { type: String, default: null },
example: { type: String, default: null },
link: { type: Object, default: null },
// Rendered field component props
component: { type: String, default: 'InputItem' },
value: { type: null, default: null },
props: { type: Object, default: () => ({}) },
validation: { type: Object, default: null }
},
computed: {
_id () {
if (this.id) return this.id
const childId = this.props.id || this.$attrs['label-for']
return childId ? childId + '_group' : null
},
attrs () {
const attrs = { ...this.$attrs }
if ('label' in attrs) {
const defaultAttrs = {
'label-cols-md': 4,
'label-cols-lg': 2,
'label-class': 'font-weight-bold'
}
if (!('label-cols' in attrs)) {
for (const attr in defaultAttrs) {
if (!(attr in attrs)) attrs[attr] = defaultAttrs[attr]
}
} else if (!('label-class' in attrs)) {
attrs['label-class'] = defaultAttrs['label-class']
}
}
return attrs
},
state () {
// Need to set state as null if no error, else component turn green
if (this.validation) {
return this.validation.$anyError === true ? false : null
}
return null
},
errorMessage () {
const validation = this.validation
if (validation && validation.$anyError) {
const [type, errData] = this.findError(validation.$params, validation)
return this.$i18n.t('form_errors.' + type, errData)
}
return ''
}
},
methods: {
touch (name) {
if (this.validation) {
// For fields that have multiple elements
if (name) {
this.validation[name].$touch()
} else {
this.validation.$touch()
}
}
},
findError (params, obj, parent = obj) {
for (const key in params) {
if (!obj[key]) {
return [key, obj.$params[key]]
}
if (obj[key].$anyError) {
return this.findError(obj[key].$params, obj[key], parent)
}
}
}
}
}
</script>
<style lang="scss" scoped>
::v-deep .invalid-feedback code {
background-color: $gray-200;
}
</style>

View file

@ -0,0 +1,30 @@
<template>
<span :class="'icon fa fa-' + iname" aria-hidden="true" />
</template>
<script>
export default {
name: 'Icon',
props: {
iname: { type: String, required: true }
}
}
</script>
<style lang="scss" scoped>
.icon {
font-size: inherit;
min-width: 1rem;
text-align: center;
&.lg {
width: 3rem;
font-size: 1.5rem;
min-width: 3rem;
}
&.fs-sm {
font-size: 1rem;
}
}
</style>

View file

@ -0,0 +1,95 @@
<template>
<b-button-toolbar :aria-label="label" id="top-bar">
<div id="top-bar-left" class="top-bar-group" v-if="hasLeftSlot">
<slot name="group-left" />
</div>
<div id="top-bar-right" class="top-bar-group" v-if="hasRightSlot || button">
<slot v-if="hasRightSlot" name="group-right" />
<b-button v-else variant="success" :to="button.to">
<icon v-if="button.icon" :iname="button.icon" /> {{ button.text }}
</b-button>
</div>
</b-button-toolbar>
</template>
<script>
export default {
name: 'TopBar',
props: {
label: { type: String, default: null },
button: {
type: Object,
default: null,
validator (value) {
return ['text', 'to'].every(prop => (prop in value))
}
}
},
data () {
return {
hasLeftSlot: null,
hasRightSlot: null
}
},
created () {
this.$nextTick(() => {
this.hasLeftSlot = 'group-left' in this.$slots
this.hasRightSlot = 'group-right' in this.$slots
})
}
}
</script>
<style lang="scss" scoped>
#top-bar {
margin-bottom: 2rem;
flex-wrap: wrap-reverse;
.top-bar-group {
display: flex;
}
@include media-breakpoint-down(xs) {
.top-bar-group {
flex-direction: column-reverse;
}
::v-deep .btn:not(:first-of-type) {
margin-bottom: .25rem;
}
}
@include media-breakpoint-down(sm) {
flex-direction: column-reverse;
#top-bar-left ~ #top-bar-right {
margin-bottom: 1rem;
}
.top-bar-group {
justify-content: space-between;
flex-wrap: wrap;
}
}
@include media-breakpoint-up(md) {
#top-bar-left {
flex-grow: 2;
max-width: 50%;
}
#top-bar-right {
margin-left: auto;
}
::v-deep .btn {
margin-left: .5rem;
}
}
}
</style>

View file

@ -0,0 +1,83 @@
<template>
<div>
<top-bar v-if="hasTopBar">
<slot name="top-bar-group-left" slot="group-left" />
<slot name="top-bar-group-right" slot="group-right" />
</top-bar>
<slot v-else name="top-bar" />
<slot name="top" v-bind="{ loading: isLoading }" />
<b-skeleton-wrapper :loading="isLoading">
<template #loading>
<slot name="skeleton">
<component :is="skeleton" />
</slot>
</template>
<!-- Empty div to be able to receive multiple components -->
<div>
<slot name="default" v-bind="{ loading: isLoading }" />
</div>
</b-skeleton-wrapper>
<slot name="bot" v-bind="{ loading: isLoading }" />
</div>
</template>
<script>
import api from '@/api'
export default {
name: 'ViewBase',
props: {
queries: { type: Array, default: null },
skeleton: { type: [String, Array], default: null },
// Optional prop to take control of the loading value
loading: { type: Boolean, default: null }
},
data () {
return {
fallback_loading: this.loading === null && this.fetch !== null ? true : null
}
},
computed: {
isLoading () {
if (this.loading !== null) return this.loading
return this.fallback_loading
},
hasTopBar () {
return ['top-bar-group-left', 'top-bar-group-right'].some(slotName => (slotName in this.$slots))
}
},
methods: {
fetchQueries (triggerLoading = false) {
if (triggerLoading) {
this.fallback_loading = true
}
const [apiQueries, storeQueries] = this.queries.reduce((types, query) => {
types[typeof query === 'string' ? 0 : 1].push(query)
return types
}, [[], []])
Promise.all([
api.getAll(apiQueries),
this.$store.dispatch('FETCH_ALL', storeQueries)
]).then(([apiResponses, storeResponses]) => {
this.$emit('queries-response', ...apiResponses, ...storeResponses)
this.fallback_loading = false
})
}
},
created () {
if (this.queries) this.fetchQueries()
}
}
</script>

View file

@ -0,0 +1,57 @@
<template>
<view-base v-bind="$attrs" v-on="$listeners" :skeleton="skeleton">
<slot v-if="hasCustomTopBar" name="top-bar" slot="top-bar" />
<template v-if="!hasCustomTopBar" #top-bar-group-left>
<b-input-group class="w-100">
<b-input-group-prepend is-text>
<icon iname="search" />
</b-input-group-prepend>
<b-form-input
id="top-bar-search"
:value="search" @input="$emit('update:search', $event)"
:placeholder="$t('search.for', { items: $tc('items.' + itemsName, 2) })"
:disabled="!items"
/>
</b-input-group>
</template>
<slot v-if="!hasCustomTopBar" name="top-bar-buttons" slot="top-bar-group-right" />
<slot name="top" slot="top" />
<template #default>
<b-alert v-if="items === null || filteredItems === null" variant="warning">
<slot name="alert-message">
<icon iname="exclamation-triangle" />
{{ $t(items === null ? 'items_verbose_count' : 'search.not_found', { items: $tc('items.' + itemsName, 0) }) }}
</slot>
</b-alert>
<slot v-else name="default" />
</template>
<slot name="bot" slot="bot" />
<slot name="skeleton" slot="skeleton" />
</view-base>
</template>
<script>
export default {
name: 'ViewSearch',
props: {
items: { type: null, required: true },
itemsName: { type: String, required: true },
filteredItems: { type: null, required: true },
search: { type: String, default: null },
skeleton: { type: String, default: 'list-group-skeleton' }
},
computed: {
hasCustomTopBar () {
return 'top-bar' in this.$slots
}
}
}
</script>

View file

@ -0,0 +1,30 @@
<template>
<b-checkbox
v-model="checked"
v-on="$listeners"
:id="id"
:aria-describedby="$parent.id + '__BV_description_'"
switch
>
{{ label || $t(labels[checked]) }}
</b-checkbox>
</template>
<script>
export default {
name: 'CheckboxItem',
props: {
value: { type: Boolean, required: true },
id: { type: String, default: null },
label: { type: String, default: null },
labels: { type: Object, default: () => ({ true: 'yes', false: 'no' }) }
},
data () {
return {
checked: this.value
}
}
}
</script>

View file

@ -0,0 +1,28 @@
<template>
<b-input
:value="value"
:id="id"
v-on="$listeners"
:placeholder="placeholder"
:type="type"
:state="state"
:required="required"
@blur="$parent.$emit('touch', name)"
/>
</template>
<script>
export default {
name: 'InputItem',
props: {
value: { type: [String, Number], default: null },
id: { type: String, default: null },
placeholder: { type: String, default: null },
type: { type: String, default: 'text' },
required: { type: Boolean, default: false },
state: { type: Boolean, default: null },
name: { type: String, default: null }
}
}
</script>

View file

@ -0,0 +1,24 @@
<template>
<b-select
:value="value"
:id="id"
:options="choices"
:required="required"
v-on="$listeners"
@blur.native="$emit('blur', value)"
/>
</template>
<script>
export default {
name: 'SelectItem',
props: {
value: { type: [String, null], default: null },
id: { type: String, default: null },
choices: { type: [Array, Object], required: true },
required: { type: Boolean, default: false },
name: { type: String, default: null }
}
}
</script>

View file

@ -0,0 +1,32 @@
<template>
<b-card>
<template #header>
<b-skeleton width="30%" height="36px" class="m-0" />
</template>
<div v-for="count in itemCount" :key="count">
<template v-if="randint(0, 1)">
<b-skeleton width="100%" height="24px" />
<b-skeleton :width="randint(15, 60) + '%'" height="24px" />
</template>
<b-skeleton v-else :width="randint(45, 100) + '%'" height="24px" />
<b-skeleton :width="randint(20, 30) + '%'" height="38px" class="mt-3" />
<hr>
</div>
</b-card>
</template>
<script>
import { randint } from '@/helpers/commons'
export default {
name: 'CardButtonsSkeleton',
props: {
itemCount: { type: Number, default: 5 }
},
methods: { randint }
}
</script>

View file

@ -0,0 +1,52 @@
<template>
<b-card>
<template #header>
<b-skeleton width="30%" height="36px" class="m-0" />
</template>
<template v-for="count in itemCount">
<b-row :key="count" :class="{ 'd-block': cols === null }">
<b-col v-bind="cols">
<div style="height: 38px" class="d-flex align-items-center">
<b-skeleton class="m-0" :width="randint(45, 100) + '%'" height="24px" />
</div>
</b-col>
<b-col>
<div class="w100 d-flex justify-content-between" v-if="count % 2 === 0">
<b-skeleton width="100%" height="38px" />
<b-skeleton width="38px" height="38px" class="ml-2" />
</div>
<b-skeleton v-else width="100%" height="38px" />
<b-skeleton :width="randint(15, 35) + '%'" height="19px" />
</b-col>
</b-row>
<hr :key="count + '-hr'">
</template>
<template #footer>
<div class="d-flex justify-content-end w-100">
<b-skeleton width="100px" height="38px" />
</div>
</template>
</b-card>
</template>
<script>
import { randint } from '@/helpers/commons'
export default {
name: 'CardFormSkeleton',
props: {
itemCount: { type: Number, default: 5 },
cols: { type: [Object, null], default () { return { md: 4, lg: 2 } } }
},
methods: { randint }
}
</script>

View file

@ -0,0 +1,30 @@
<template>
<b-card>
<template #header>
<b-skeleton width="30%" height="36px" class="m-0" />
</template>
<b-row v-for="i in itemCount" :key="i" no-gutters>
<b-col cols="5" md="3" xl="3">
<b-skeleton :width="randint(45, 95) + '%'" height="19px" />
</b-col>
<b-col>
<b-skeleton :width="randint(10, 60) + '%'" height="19px" />
</b-col>
</b-row>
</b-card>
</template>
<script>
import { randint } from '@/helpers/commons'
export default {
name: 'CardInfoSkeleton',
props: {
itemCount: { type: Number, default: 5 }
},
methods: { randint }
}
</script>

View file

@ -0,0 +1,30 @@
<template>
<b-card no-body>
<template #header>
<b-skeleton width="30%" height="36px" class="m-0" />
</template>
<b-list-group flush>
<b-list-group-item v-for="count in itemCount" :key="count" class="d-flex">
<div style="width: 20%;">
<b-skeleton :width="randint(50, 100) + '%'" height="24px" class="mr-3" />
</div>
<b-skeleton :width="randint(30, 80) + '%'" height="24px" class="m-0" />
</b-list-group-item>
</b-list-group>
</b-card>
</template>
<script>
import { randint } from '@/helpers/commons'
export default {
name: 'CardListSkeleton',
props: {
itemCount: { type: Number, default: 5 }
},
methods: { randint }
}
</script>

View file

@ -0,0 +1,22 @@
<template>
<b-list-group>
<b-list-group-item v-for="count in itemCount" :key="count">
<b-skeleton :width="randint(15, 25) + '%'" height="24px" class="mb-2" />
<b-skeleton :width="randint(25, 50) + '%'" height="24px" class="m-0" />
</b-list-group-item>
</b-list-group>
</template>
<script>
import { randint } from '@/helpers/commons'
export default {
name: 'ListGroupSkeleton',
props: {
itemCount: { type: Number, default: 5 }
},
methods: { randint }
}
</script>

View file

@ -0,0 +1,152 @@
<template>
<card-form
:title="title" icon="globe" :submit-text="submitText"
:validation="$v" :server-error="serverError"
@submit.prevent="onSubmit"
>
<slot name="disclaimer" slot="disclaimer" />
<b-form-radio
v-model="selected" name="domain-type" value="domain"
:class="domainIsVisible ? null : 'collapsed'"
:aria-expanded="domainIsVisible ? 'true' : 'false'"
aria-controls="collapse-domain"
>
{{ $t('domain_add_panel_with_domain') }}
</b-form-radio>
<b-collapse id="collapse-domain" :visible.sync="domainIsVisible">
<small v-html="$t('domain_add_dns_doc')" />
<form-field
v-bind="fields.domain" v-model="form.domain"
:validation="$v.form.domain" class="mt-3"
/>
</b-collapse>
<b-form-radio
v-model="selected" name="domain-type" value="dynDomain"
:disabled="dynDnsForbiden"
:class="dynDomainIsVisible ? null : 'collapsed'"
:aria-expanded="dynDomainIsVisible ? 'true' : 'false'"
aria-controls="collapse-dynDomain"
>
{{ $t('domain_add_panel_without_domain') }}
</b-form-radio>
<b-collapse id="collapse-dynDomain" :visible.sync="dynDomainIsVisible">
<small>{{ $t('domain_add_dyndns_doc') }}</small>
<form-field v-bind="fields.dynDomain" :validation="$v.form.dynDomain" class="mt-3">
<template #default="{ self }">
<adress-input-select v-bind="self" v-model="form.dynDomain" />
</template>
</form-field>
</b-collapse>
<div v-if="dynDnsForbiden" class="alert alert-warning mt-2" v-html="$t('domain_add_dyndns_forbidden')" />
</card-form>
</template>
<script>
import { mapGetters } from 'vuex'
import { validationMixin } from 'vuelidate'
import AdressInputSelect from '@/components/AdressInputSelect'
import { formatFormDataValue } from '@/helpers/yunohostArguments'
import { required, domain, dynDomain } from '@/helpers/validators'
export default {
name: 'DomainForm',
props: {
title: { type: String, required: true },
submitText: { type: String, default: null },
serverError: { type: String, default: '' },
// Do not query the api (used by postinstall)
noStore: { type: Boolean, default: false }
},
data () {
return {
selected: '',
form: {
domain: '',
dynDomain: { localPart: '', separator: '.', domain: 'nohost.me' }
},
fields: {
domain: {
label: this.$i18n.t('domain_name'),
props: {
id: 'domain',
placeholder: this.$i18n.t('placeholder.domain')
}
},
dynDomain: {
label: this.$i18n.t('domain_name'),
props: {
id: 'dyn-domain',
placeholder: this.$i18n.t('myserver'),
type: 'domain',
choices: ['nohost.me', 'noho.st', 'ynh.fr']
}
}
}
}
},
computed: {
...mapGetters(['domains']),
dynDnsForbiden () {
if (!this.domains) return false
const dynDomains = this.fields.dynDomain.props.choices
return this.domains.some(domain => {
return dynDomains.some(dynDomain => domain.includes(dynDomain))
})
},
domainIsVisible () {
return this.selected === 'domain'
},
dynDomainIsVisible () {
return this.selected === 'dynDomain'
}
},
validations () {
return {
selected: { required },
form: {
domain: this.selected === 'domain' ? { required, domain } : {},
dynDomain: { localPart: this.selected === 'dynDomain' ? { required, dynDomain } : {} }
}
}
},
methods: {
onSubmit () {
const domainType = this.selected
this.$emit('submit', {
domain: formatFormDataValue(this.form[domainType]),
domainType
})
}
},
created () {
if (this.dynDnsForbiden) {
this.selected = 'domain'
}
},
mixins: [validationMixin],
components: {
AdressInputSelect
}
}
</script>

View file

@ -0,0 +1,88 @@
<template>
<card-form
:title="title" icon="key-modern" :submit-text="submitText"
:validation="$v" :server-error="serverError"
@submit.prevent="onSubmit"
>
<template #disclaimer>
<p class="alert alert-warning">
{{ $t('good_practices_about_admin_password') }}
</p>
<slot name="disclaimer" />
<hr>
</template>
<slot name="extra" v-bind="{ v: $v, fields, form }">
<form-field
v-for="(value, key) in extra.fields" :key="key"
v-bind="value" v-model="$v.form.$model[key]" :validation="$v.form[key]"
/>
</slot>
<!-- ADMIN PASSWORD -->
<form-field v-bind="fields.password" v-model="form.password" :validation="$v.form.password" />
<!-- ADMIN PASSWORD CONFIRMATION -->
<form-field v-bind="fields.confirmation" v-model="form.confirmation" :validation="$v.form.confirmation" />
</card-form>
</template>
<script>
import { validationMixin } from 'vuelidate'
import { required, minLength, sameAs } from '@/helpers/validators'
export default {
name: 'PasswordForm',
props: {
title: { type: String, required: true },
submitText: { type: String, default: null },
serverError: { type: String, default: '' },
extra: { type: Object, default: () => ({ form: {}, fields: {}, validations: {} }) }
},
data () {
return {
form: {
password: '',
confirmation: '',
...this.extra.form
},
fields: {
password: {
label: this.$i18n.t('password'),
props: { id: 'password', type: 'password', placeholder: '••••••••' }
},
confirmation: {
label: this.$i18n.t('password_confirmation'),
props: { id: 'confirmation', type: 'password', placeholder: '••••••••' }
},
...this.extra.fields
}
}
},
validations () {
return {
form: {
password: { required, passwordLenght: minLength(8) },
confirmation: { required, passwordMatch: sameAs('password') },
...this.extra.validations
}
}
},
methods: {
onSubmit () {
this.$emit('submit', this.form)
}
},
mixins: [validationMixin]
}
</script>

View file

@ -0,0 +1,2 @@
export { default as PasswordForm } from './PasswordForm'
export { default as DomainForm } from './DomainForm'

130
app/src/helpers/commons.js Normal file
View file

@ -0,0 +1,130 @@
import store from '@/store'
/**
* Allow to set a timeout on a `Promise` expected response.
* The returned Promise will be rejected if the original Promise is not resolved or
* rejected before the delay.
*
* @param {Promise} promise - A promise (like a fetch call).
* @param {Number} delay - delay after which the promise is rejected
* @return {Promise}
*/
export function timeout (promise, delay) {
return new Promise((resolve, reject) => {
// FIXME reject(new Error('api_not_responding')) for post-install
setTimeout(() => reject, delay)
promise.then(resolve, reject)
})
}
/**
* Converts an object literal into an `URLSearchParams` that can be turned into a
* query string or used as a body in a `fetch` call.
*
* @param {Object} obj - An object literal to convert.
* @param {Object} options
* @param {Boolean} [options.addLocale=false] - Option to append the locale to the query string.
* @return {URLSearchParams}
*/
export function objectToParams (obj, { addLocale = false } = {}) {
const urlParams = new URLSearchParams()
for (const [key, value] of Object.entries(obj)) {
if (Array.isArray(value)) {
value.forEach(v => urlParams.append(key, v))
} else {
urlParams.append(key, value)
}
}
if (addLocale) {
urlParams.append('locale', store.getters.locale)
}
return urlParams
}
/**
* Check if passed value is an object literal.
*
* @param {*} value - Anything.
* @return {Boolean}
*/
export function isObjectLiteral (value) {
return value !== null && value !== undefined && Object.is(value.constructor, Object)
}
/**
* Check if value is "empty" (`null`, `undefined`, `''`, `[]`, '{}').
* Note: `0` is not considered "empty" in that helper.
*
* @param {*} value - Anything.
* @return {Boolean}
*/
export function isEmptyValue (value) {
if (typeof value === 'number') return false
return !value || value.length === 0 || Object.keys(value).length === 0
}
/**
* Returns an flattened object literal, with all keys at first level and removing nested ones.
*
* @param {Object} obj - An object literal to flatten.
* @param {Object} [flattened={}] - An object literal to add passed obj keys/values.
* @return {Object}
*/
export function flattenObjectLiteral (obj, flattened = {}) {
function flatten (objLit) {
for (const key in objLit) {
const value = objLit[key]
if (isObjectLiteral(value)) {
flatten(value)
} else {
flattened[key] = value
}
}
}
flatten(obj)
return flattened
}
/**
* Returns an new array containing items that are in first array but not in the other.
*
* @param {Array} [arr1=[]]
* @param {Array} [arr2=[]]
* @return {Array}
*/
export function arrayDiff (arr1 = [], arr2 = []) {
return arr1.filter(item => !arr2.includes(item))
}
/**
* Returns a new string with escaped HTML (`&<>"'` replaced by entities).
*
* @param {String} unsafe
* @return {String}
*/
export function escapeHtml (unsafe) {
return unsafe
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#039;')
}
/**
* Returns a random integer between `min` and `max`.
*
* @param {Number} min
* @param {Number} max
* @return {Number}
*/
export function randint (min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min
}

View file

@ -0,0 +1,19 @@
import formatDistanceToNow from 'date-fns/formatDistanceToNow'
import format from 'date-fns/format'
import { dateFnsLocale as locale } from '@/i18n/helpers'
export function distanceToNow (date, addSuffix = true, isTimestamp = false) {
return formatDistanceToNow(
new Date(isTimestamp ? date * 1000 : date),
{ addSuffix, locale }
)
}
export function readableDate (date, isTimestamp = false) {
return format(
new Date(isTimestamp ? date * 1000 : date),
'PPPpp',
{ locale }
)
}

View file

@ -0,0 +1,13 @@
export function humanSize (bytes) {
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']
if (bytes === 0) return 'n/a'
const i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)))
return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[i]
}
export function humanPermissionName (text) {
return text.split('.')[1].replace('_', ' ').replace(/\w\S*/g, part => {
return part.charAt(0).toUpperCase() + part.substr(1).toLowerCase()
})
}

View file

@ -0,0 +1,64 @@
import { helpers } from 'vuelidate/lib/validators'
// Unicode ranges are taken from https://stackoverflow.com/a/37668315
const nonAsciiWordCharacters = '\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B4\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC'
const alphalownum_ = helpers.regex('alphalownum_', /^[a-z0-9_]+$/)
const domain = helpers.regex('domain', new RegExp(`^(?:[\\da-z${nonAsciiWordCharacters}]+(?:-*[\\da-z${nonAsciiWordCharacters}]+)*\\.)+(?:(?:xn--)?[\\da-z${nonAsciiWordCharacters}]{2,})$`))
const dynDomain = helpers.regex('dynDomain', new RegExp(`^(?:xn--)?[\\da-z-${nonAsciiWordCharacters}]+$`))
const emailLocalPart = helpers.regex('emailLocalPart', /^[\w.-]+$/)
const emailForwardLocalPart = helpers.regex('emailForwardLocalPart', /^[\w+.-]+$/)
const email = value => helpers.withParams(
{ type: 'email', value },
value => {
const [localPart, domainPart] = value.split('@')
if (!domainPart) return !helpers.req(value) || false
return !helpers.req(value) || (emailLocalPart(localPart) && domain(domainPart))
}
)(value)
// Same as email but with `+` allowed.
const emailForward = value => helpers.withParams(
{ type: 'emailForward', value },
value => {
const [localPart, domainPart] = value.split('@')
if (!domainPart) return !helpers.req(value) || false
return !helpers.req(value) || (emailForwardLocalPart(localPart) && domain(domainPart))
}
)(value)
const githubLink = helpers.regex('githubLink', /^https:\/\/github.com\/[a-zA-Z0-9-_.]+\/[a-zA-Z0-9-_.]+[/]?$/)
const includes = items => item => helpers.withParams(
{ type: 'includes', value: item },
item => !helpers.req(item) || (items ? items.includes(item) : false)
)(item)
const name = helpers.regex('name', new RegExp(`^(?:[A-Za-z${nonAsciiWordCharacters}]{2,30}[ ,.'-]{0,3})+$`))
const unique = items => item => helpers.withParams(
{ type: 'unique', arg: items, value: item },
item => items ? !helpers.req(item) || !items.includes(item) : true
)(item)
export {
alphalownum_,
domain,
dynDomain,
email,
emailForward,
emailForwardLocalPart,
emailLocalPart,
githubLink,
includes,
name,
unique
}

View file

@ -0,0 +1,3 @@
// helper module to expose custom and vuelidate validators.
export * from './customValidators'
export * from 'vuelidate/lib/validators'

View file

@ -0,0 +1,223 @@
import i18n from '@/i18n'
import store from '@/store'
import * as validators from '@/helpers/validators'
import { isObjectLiteral, isEmptyValue, flattenObjectLiteral } from '@/helpers/commons'
/**
* Tries to find a translation corresponding to the user's locale/fallback locale in a
* Yunohost argument or simply return the string if it's not an object literal.
*
* @param {(Object|String)} field - A field value containing a translation object or string
* @return {String}
*/
export function formatI18nField (field) {
if (typeof field === 'string') return field
const { locale, fallbackLocale } = store.state
return field[locale] || field[fallbackLocale] || field.en
}
/**
* Returns a string size declaration to a M value.
*
* @param {String} sizeStr - A size declared like '500M' or '56k'
* @return {Number}
*/
export function sizeToM (sizeStr) {
const unit = sizeStr.slice(-1)
const value = sizeStr.slice(0, -1)
if (unit === 'M') return parseInt(value)
if (unit === 'b') return Math.ceil(value / (1024 * 1024))
if (unit === 'k') return Math.ceil(value / 1024)
if (unit === 'G') return Math.ceil(value * 1024)
if (unit === 'T') return Math.ceil(value * 1024 * 1024)
}
/**
* Returns a formatted address element to be used by AdressInputSelect component.
*
* @param {String} address - A string representing an adress (subdomain or email)
* @return {Object} - `{ localPart, separator, domain }`.
*/
export function adressToFormValue (address) {
const separator = address.includes('@') ? '@' : '.'
const [localPart, domain] = address.split(separator)
return { localPart, separator, domain }
}
/**
* Format app install, actions and config panel argument into a data structure that
* will be automaticly transformed into a component on screen.
*
* @param {Object} arg - a yunohost arg options written by a packager.
* @return {Object} an formated argument containing formItem props, validation and base value.
*/
export function formatYunoHostArgument (arg) {
let value = null
const validation = {}
const field = {
component: undefined,
label: formatI18nField(arg.ask),
props: {}
}
if (arg.type === 'boolean') {
field.id = arg.name
} else {
field.props.id = arg.name
}
// Some apps has an argument type `string` as type but expect a select since it has `choices`
if (arg.choices !== undefined) {
field.component = 'SelectItem'
field.props.choices = arg.choices
// Input
} else if ([undefined, 'string', 'number', 'password', 'email'].includes(arg.type)) {
field.component = 'InputItem'
if (![undefined, 'string'].includes(arg.type)) {
field.props.type = arg.type
if (arg.type === 'password') {
field.description = i18n.t('good_practices_about_admin_password')
field.placeholder = '••••••••'
validation.passwordLenght = validators.minLength(8)
}
}
// Checkbox
} else if (arg.type === 'boolean') {
field.component = 'CheckboxItem'
value = arg.default || false
// Special (store related)
} else if (['user', 'domain'].includes(arg.type)) {
field.component = 'SelectItem'
field.link = { name: arg.type + '-list', text: i18n.t(`manage_${arg.type}s`) }
field.props.choices = store.getters[arg.type + 'sAsChoices']
value = arg.type === 'domain' ? store.getters.mainDomain : field.props.choices[0].value
// Unknown from the specs, try to display it as an input[text]
// FIXME throw an error instead ?
} else {
field.component = 'InputItem'
}
// Required (no need for checkbox its value can't be null)
if (field.component !== 'CheckboxItem' && arg.optional !== true) {
validation.required = validators.required
}
// Default value
if (arg.default) {
value = arg.default
}
// Help message
if (arg.help) {
field.description = formatI18nField(arg.help)
}
// Example
if (arg.example) {
field.example = arg.example
if (field.component === 'InputItem') {
field.props.placeholder = field.example
}
}
return {
value,
field,
// Return null instead of empty object if there's no validation
validation: Object.keys(validation).length === 0 ? null : validation
}
}
/**
* Format app install, actions and config panel manifest args into a form that can be used
* as v-model values, fields that can be passed to a FormField component and validations.
*
* @param {Array} args - a yunohost arg array written by a packager.
* @param {String} name - (temp) an app name to build a label field in case of manifest install args
* @return {Object} an object containing all parsed values to be used in vue views.
*/
export function formatYunoHostArguments (args, name = null) {
let disclaimer = null
const form = {}
const fields = {}
const validations = {}
// FIXME yunohost should add the label field by default
if (name) {
args.unshift({
ask: i18n.t('label_for_manifestname', { name }),
default: name,
name: 'label'
})
}
for (const arg of args) {
if (arg.type === 'display_text') {
disclaimer = formatI18nField(arg.ask)
} else {
const { value, field, validation } = formatYunoHostArgument(arg)
fields[arg.name] = field
form[arg.name] = value
if (validation) validations[arg.name] = validation
}
}
return { form, fields, validations, disclaimer }
}
/**
* Format helper for a form value.
* Convert Boolean to (1|0) and concatenate adresses.
*
* @param {*} value
* @return {*}
*/
export function formatFormDataValue (value) {
if (typeof value === 'boolean') {
return value ? 1 : 0
} else if (isObjectLiteral(value) && 'separator' in value) {
return Object.values(value).join('')
}
return value
}
/**
* Format a form produced by a vue view to be sent to the server.
*
* @param {Object} formData - An object literal containing form values.
* @param {Object} [extraParams] - Optionnal params
* @param {Array} [extraParams.extract] - An array of keys that should be extracted from the form.
* @param {Boolean} [extraParams.flatten=false] - Flattens or not the passed formData.
* @param {Boolean} [extraParams.removeEmpty=true] - Removes "empty" values from the object.
* @return {Object} the parsed data to be sent to the server, with extracted values if specified.
*/
export function formatFormData (
formData,
{ extract = null, flatten = false, removeEmpty = true } = {}
) {
const output = {
data: {},
extracted: {}
}
for (const key in formData) {
const type = extract && extract.includes(key) ? 'extracted' : 'data'
const value = Array.isArray(formData[key])
? formData[key].map(item => formatFormDataValue(item))
: formatFormDataValue(formData[key])
if (removeEmpty && isEmptyValue(value)) {
continue
} else if (flatten && isObjectLiteral(value)) {
flattenObjectLiteral(value, output[type])
} else {
output[type][key] = value
}
}
const { data, extracted } = output
return extract ? { data, ...extracted } : data
}

92
app/src/i18n/helpers.js Normal file
View file

@ -0,0 +1,92 @@
import i18n from '@/i18n'
import store from '@/store'
import supportedLocales from './supportedLocales'
let dateFnsLocale
const loadedLanguages = []
/**
* Returns the first two supported locales that can be found in the `localStorage` or
* in the user browser settings.
*
* @return {string[]}
*/
function getDefaultLocales () {
const locale = store.getters.locale
const fallbackLocale = store.getters.fallbackLocale
if (locale && fallbackLocale) return [locale, fallbackLocale]
const navigatorLocales = navigator.languages || [navigator.language]
const defaultLocales = []
const supported = Object.keys(supportedLocales)
for (const locale of navigatorLocales) {
if (supported.includes(locale) && !defaultLocales.includes(locale)) {
defaultLocales.push(locale)
} else {
const lang = locale.split('-')[0]
if (supported.includes(lang) && !defaultLocales.includes(lang)) {
defaultLocales.push(lang)
}
}
if (defaultLocales.length === 2) break
}
return defaultLocales
}
function updateDocumentLocale (locale) {
document.documentElement.lang = locale
// FIXME can't currently change document direction easily since bootstrap still doesn't handle rtl.
// document.dir = locale === 'ar' ? 'rtl' : 'ltr'
}
/**
* Loads a translation file and adds its content to the i18n plugin `messages`.
*
* @return {Promise<string>} Promise that resolve the given locale string
*/
function loadLocaleMessages (locale) {
if (loadedLanguages.includes(locale)) {
return Promise.resolve(locale)
}
return import(
/* webpackChunkName: "lc/lang-[request]" */ `@/i18n/locales/${locale}`
).then(messages => {
i18n.setLocaleMessage(locale, messages.default)
loadedLanguages.push(locale)
return locale
})
}
/**
* Loads a date-fns locale object
*/
async function loadDateFnsLocale (locale) {
const dateFnsLocaleName = supportedLocales[locale].dateFnsLocale || locale
return import(
/* webpackChunkName: "lc/datefns-[request]" */
`date-fns/locale/${dateFnsLocaleName}/index.js`
).then(locale => {
dateFnsLocale = locale.default
})
}
/**
* Initialize all locales
*/
function initDefaultLocales () {
// Get defined locales from `localStorage` or `navigator`
const [locale, fallbackLocale] = getDefaultLocales()
store.dispatch('UPDATE_LOCALE', locale)
store.dispatch('UPDATE_FALLBACKLOCALE', fallbackLocale || 'en')
loadLocaleMessages('en')
}
export {
initDefaultLocales,
updateDocumentLocale,
loadLocaleMessages,
loadDateFnsLocale,
dateFnsLocale
}

16
app/src/i18n/index.js Normal file
View file

@ -0,0 +1,16 @@
/**
* i18n plugin module.
* @module i18n
*/
import Vue from 'vue'
import VueI18n from 'vue-i18n'
import { initDefaultLocales } from './helpers'
// Plugin Initialization
Vue.use(VueI18n)
export default new VueI18n({})
// Load default locales translations files and setup store data
initDefaultLocales()

View file

@ -1,147 +1,79 @@
{
"action": "الإجراء",
"add": "إضافة",
"remove": "حذف",
"administration_password": "كلمة السر الإدارية",
"allowed_users": "المستخدمون المصرح لهم",
"api_not_responding": "واجهة برمجة تطبيقات API الخاصة بـ YunoHost لا تستجيب. ربما 'yunohost-api' معطّلة أو تم إعادة تشغيلها؟",
"app_access": "النفاذ",
"app_access_addall_btn": "السماح بالنفاذ للجميع",
"app_access_addall_desc": "سيُسمح لكافة المستخدمين الموجودين النفاذ إلى %s.",
"app_access_clearall_btn": "إلغاء جميع التصريحات بالدخول",
"app_access_clearall_desc": "كافة المستخدمين سيكون لهم التصريح للنفاذ إلى %s.",
"app_access_removeall_btn": "إزالة كافة تصريحات النفاذ",
"app_access_removeall_desc": "لن يكون بإمكان أي مستخدم النفاذ إلى %s .",
"app_access_title": "النفاذ إلى %s",
"app_change_label": "تعديل التسمية",
"app_change_url": "تغيير عنوان الرابط",
"app_debug_no_logs": "سجلات هذا البرنامج غير متوفرة",
"app_debug_tab": "إظهار معلومات التنقيح",
"app_info_access_desc": "الفِرَق / المستخدمون المصرّح لهم للنفاذ إلى هذا التطبيق:",
"app_info_changelabel_desc": "تعديل تسمية البرنامج على البوابة.",
"app_info_debug_desc": "عرض معلومات التنقيح الخاصة بهذا البرنامج.",
"app_info_default_desc": "تحويل مسار جذر النطاق نحو هذا البرنامج (%s).",
"app_info_default_desc": "تحويل مسار جذر النطاق نحو هذا البرنامج ({domain}).",
"app_info_changeurl_desc": "يقوم بتغيير عنوان رابط النفاذ إلى هذا البرنامج (النطاق و/أو المسار).",
"app_info_change_url_disabled_tooltip": "لم تُهيأ هذه الخاصية لإعدادها في هذا البرنامج بعدُ",
"app_info_uninstall_desc": "حذف هذا البرنامج.",
"app_install_cancel": "تم إلغاء عملية التنصيب.",
"app_install_custom_no_manifest": "No manifest.json file",
"app_list": "قائمة التطبيقات",
"app_make_default": "تعيينه كافتراضي",
"app_repository": "مصدر البرنامج : ",
"app_state": "حالة البرنامج : ",
"app_state_inprogress": "لا يعمل بعد",
"app_state_notworking": "لا يعمل بعدُ",
"app_state_validated": "موافَق عليها",
"app_state_working": "يشتغل",
"application": "برنامج",
"applications": "التطبيقات",
"archive_empty": "النسخة الإحتياطية فارغة",
"available": "متوفر",
"available_apps": "التطبيقات المتوفرة",
"backup": "النسخ الإحتياطي",
"backup_action": "النسخ الإحتياطي",
"backup_archive_copy": "نسخ هذا الأرشيف إلى مساحة تخزين أخرى",
"backup_archive_delete": "حذف هذا الأرشيف",
"backup_archive_download": "تنزيل هذا الأرشيف",
"backup_content": "محتوى النسخة الإحتياطية",
"backup_create": "إنشاء نسخة إحتياطية",
"backup_encryption_warning": "لا تنسى كلمة السر هذه، ستحتاجها حينما تود استعادة النسخة الإحتياطية مِن جديد",
"backup_experimental_warning": "Be aware that the backup feature is still experimental, and may not be fully reliable.",
"backup_new": "نسخة إحتياطية جديدة",
"backup_optional_encryption": "تعمية إختيارية",
"backup_optional_password": "كلمة سر إختيارية",
"backup_type": "Type",
"backups_no": "لا توجد نسخة إحتياطية",
"begin": "إبدأ",
"bit_rate": "Bit rate",
"both": "كِلاهُما",
"cancel": "إلغاء",
"check": "تحقق",
"check_mx": "تسجيل MX",
"check_stmp": "النفاذ عبر منفذ 25",
"close": "إغلاق",
"confirm_access_add": "متأكد من أنك تود إضافة تصريح بالنفاذ إلى %s لكافة المستخدمين ؟",
"confirm_access_clear": "أمتأكد مِن أنك تريد إلغاء النفاذ الكامل إلى %s ؟",
"confirm_access_remove_all": "أمتأكد مِن أنك تريد إلغاء النفاذ الكامل إلى %s ؟",
"confirm_access_remove_user": "أمتأكد مِن أنك تريد إلغاء النفاذ الكامل إلى %s لـ %s ؟",
"confirm_app_change_url": "متأكد مِن أنك تود تغيير عنوان رابط النفاذ إلى البرنامج ؟",
"confirm_app_default": "أمتأكد مِن أنك تود تعيين هذا التطبيق كبرنامج إفتراضي ؟",
"confirm_change_maindomain": "متأكد من أنك تريد تغيير النطاق الرئيسي ؟",
"confirm_delete": "هل تود حقًا حذف %s ؟",
"confirm_firewall_open": "متأكد مِن أنك تود فتح منفذ %s ؟ (بروتوكول : %s، إتصال : %s)",
"confirm_firewall_close": "متأكد مِن أنك تود إغلاق منفذ %s ؟ (بروتوكول : %s، إتصال : %s)",
"confirm_delete": "هل تود حقًا حذف {name} ؟",
"confirm_firewall_open": "متأكد مِن أنك تود فتح منفذ {port} ؟ (بروتوكول : {protocol}، إتصال : {connection})",
"confirm_firewall_close": "متأكد مِن أنك تود إغلاق منفذ {port} ؟ (بروتوكول : {protocol}، إتصال : {connection})",
"confirm_install_custom_app": "إنّ خيار تنصيب تطبيقات خارجية قد يؤثر على أمان نظامكم. ربما وجب عليكم ألا تقوموا بالتنصيب إلا إن كنتم حقا مدركون بما أنتم فاعلين. هل أنتم مستعدون للمخاطرة؟",
"confirm_install_domain_root": "لن يكون بإمكانك تنصيب أي برنامج آخر على %s. هل تريد المواصلة ؟",
"confirm_postinstall": "إنك بصدد إطلاق خطوة ما بعد التنصيب على النطاق %s. سوف تستغرق العملية بضع دقائق، لذلك *يُرجى عدم إيقاف العملية*.",
"confirm_restore": "متأكد مِن أنك تريد استعادة %s ؟",
"confirm_service_start": "متأكد مِن أنك تريد تشغيل %s ؟",
"confirm_service_stop": "متأكد من أنك تود إيقاف %s ؟",
"confirm_service_enable": "متأكد مِن أنك تريد تفعيل %s ؟",
"confirm_service_disable": "متأكد مِن أنك تريد تعطيل %s ؟",
"confirm_uninstall": "متأكد مِن أنك تريد إلغاء تنصيب %s ؟",
"confirm_install_domain_root": "لن يكون بإمكانك تنصيب أي برنامج آخر على {domain}. هل تريد المواصلة ؟",
"confirm_postinstall": "إنك بصدد إطلاق خطوة ما بعد التنصيب على النطاق {domain}. سوف تستغرق العملية بضع دقائق، لذلك *يُرجى عدم إيقاف العملية*.",
"confirm_restore": "متأكد مِن أنك تريد استعادة {name} ؟",
"confirm_service_start": "متأكد مِن أنك تريد تشغيل {name} ؟",
"confirm_service_stop": "متأكد من أنك تود إيقاف {name} ؟",
"confirm_uninstall": "متأكد مِن أنك تريد إلغاء تنصيب {name} ؟",
"confirm_update_apps": "متأكد مِن أنك تريد تحديث كافة التطبيقات؟",
"confirm_update_packages": "متأكد مِن أنك تريد تحديث كافة الحُزم ؟",
"confirm_update_specific_app": "متأكد مِن أنك تود تحديث %s ؟",
"confirm_update_specific_app": "متأكد مِن أنك تود تحديث {app} ؟",
"confirm_upnp_enable": "متأكد مِن أنك تريد تفعيل الـ UPnP ؟",
"confirm_upnp_disable": "متأكد مِن أنك تريد تعطيل الـ UPnP ؟",
"confirm_reboot_action_reboot": "متأكد من أنك تريد إعادة تشغيل الخادم ؟",
"confirm_reboot_action_shutdown": "متأكد من أنك تريد إيقاف تشغيل الخادم ؟",
"connection": "الدخول",
"copy": "نسخ",
"count_min": "%s min",
"cpu_load": "نسبة تحميل وحدة المعالَجَة المركزية",
"created_at": "تم إنشاؤه على",
"cumulative_usage": "الإستخدام التراكُميّ",
"custom_app_install": "تنصيب برنامج خاص",
"custom_app_url_only_github": "حاليا فقط مِن جيت هب",
"default": "Default",
"delete": "حذف",
"description": "الوصف",
"domain_dns_conf_is_just_a_recommendation": "تُظهر هذه الصفحة الإعدادات *المستحسَنة*. فهي *لا* تقوم بتهيئة نظام أسماء النطاقات مكانكم. فالمسؤولية هي على عاتقكم لتهيئة منطقة نظام أسماء النطاقات عند المصدر أي عند مزودكم وذلك باتباع الخطوات التي ينصحكم بها.",
"diagnosis": "التشخيص",
"diagnosis_hide_private": "عرض معلومات و تفاصيل التشخيص دون الكشف عن البيانات الشخصية",
"diagnosis_view_private": "عرض معلومات و تفاصيل التشخيص مع إدراج البيانات الشخصية",
"diagnosis_with_private": "التشخيص بإدراج البيانات الحساسة",
"disable": "تعطيل",
"disabled": "معطل",
"disk": "وحدة التخزين",
"dns": "خدمة أسماء النطاقات",
"domain": "النطاق",
"domain_add": "إضافة نطاق",
"domain_add_dns_doc": "… و قد قُمتُ <a href='//yunohost.org/dns'>بإعداد خدمة أسماء النطاقات بصورة صحيحة</a>.",
"domain_add_dyndns_doc": "... و إني أريد الحصول على خدمة أسماء النطاقات الديناميكي.",
"domain_add_panel_with_domain": "عندي إسم نطاق …",
"domain_add_panel_without_domain": "لا أمتلك إسم نطاق …",
"domain_default": "إسم النطاق الإفتراضي",
"domain_default_desc": "إسم النطاق الإفتراضي هو النطاق الذي مِن خلاله يقوم المستخدِمون بتسجيل دخولهم.",
"domain_default_longdesc": "هذا هو إسم نطاقك الإفتراضي.",
"domain_delete_longdesc": "حذف هذا النطاق",
"domain_dns_config": "إعدادات خدمة أسماء النطاقات",
"domain_dns_longdesc": "الإطلاع على إعدادات خدمة أسماء النطاقات",
"domain_list": "قائمة النطاقات",
"domain_name": "إسم النطاق",
"domain_select": "إختيار نطاق",
"domain_visit": "زيارته",
"domain_visit_url": "زيارة %s",
"domain_visit_url": "زيارة {url}",
"domains": "أسماء النطاقات",
"download": "التنزيل",
"enable": "تشغيل",
"enabled": "مُفَعَّل",
"error_modify_something": "يجب عليك تغيير شيء ما",
"error_occured": "طرأ هناك خطأ، يرجى إعادة المحاولة",
"error_retrieve_feed": "تعذر جلب خيط الأخبار: %s. مِن المحتمل أنك قد تستخدم إضافة تمنع متصفحك مِن تنفيذ هذا الطلب (أو أنّ موقع الويب لا يعمل).",
"error_select_domain": "يجب اختيار نطاق",
"error_server": "خطأ في الخادم",
"error_server_unexpected": "طرأ هناك خطأ غير متوقع في الخادم (%s)",
"everyone_has_access": "النفاذ إليه مسموح للجميع.",
"filesystem": "نظام الملفات",
"error_server_unexpected": "طرأ هناك خطأ غير متوقع في الخادم",
"firewall": "الجدار الناري",
"footer_version": "مدعوم بـ <a href='https://yunohost.org'>YunoHost</a> %s (%s).",
"form_input_example": "مثال : %s",
"free": "حرة",
"fs_type": "نوع نظام الملفات",
"gateway": "بوابة العبور : ",
"footer_version": "مدعوم بـ <a href='https://yunohost.org'>YunoHost</a> {version} ({repo}).",
"form_input_example": "مثال : {example}",
"home": "الرئيسية",
"hook_adminjs_group_configuration": "إعدادات النظام",
"hook_conf_cron": "المهام التلقائية",
@ -157,30 +89,18 @@
"hook_data_home_desc": "بيانات المستخدم في /home/USER",
"hook_data_mail": "البريد",
"hook_data_mail_desc": "الرسائل الإلكترونية الخامة المحفوظة على السيرفر",
"hostname": "إسم المضيف",
"id": "ID",
"inactive": "معطّل",
"infos": "معلومات",
"install": "تنصيب",
"install_name": "تثبيت %s",
"install_name": "تثبيت {id}",
"install_time": "تاريخ التنصيب",
"installation_complete": "إكتملت عملية التنصيب",
"installed": "مُنصّب",
"installed_apps": "التطبيقات المنصّبة",
"installing": "جارٍ التنصيب",
"interface": "الواجهة",
"internal_exception": "",
"io": "I/O",
"ipv4": "IPv4",
"ipv6": "IPv6",
"label": "التسمية",
"label_for_manifestname": "تسمية لـ %s",
"loading": "عملية التحميل جارية …",
"label_for_manifestname": "تسمية لـ {name}",
"local_archives": "الأرشيف المحلي",
"local_ip": "عنوان الإيبي المحلي",
"log": "السِجِل",
"logged_in": "مُتّصل",
"logged_out": "تم تسجيل خروجك",
"login": "تسجيل الدخول",
"logout": "الخروج",
"mailbox_quota_description": "على سبيل المثال, 700M هو حجم CD، و 4700M هو حجم DVD.",
@ -188,99 +108,47 @@
"manage_apps": "إدارة التطبيقات",
"manage_domains": "إدراة أسماء النطاقات",
"manage_users": "إدارة المستخدمين",
"memory": "الذاكرة",
"menu": "Menu",
"mode": "Mode",
"monitoring": "المراقبة",
"monitoring_check_glances": "تحقق مِن حالة خدمة <a href='#/services/glances'>glances</a>.",
"monitoring_disabled": "المراقبة معطلة.",
"mount_point": "نقطة التنصيب Mount",
"multi_instance": "متعدد مثيلات الخوادم",
"myserver": "خادمي",
"myserver_org": "myserver.org",
"network": "الشبكة",
"next": "التالي",
"no": "لا",
"no_allowed_users": "لم يُقدَّم أي تصريح لأي مستخدم بعد.",
"no_installed_apps": "لم يتم تنصيب أي برنامج.",
"no_log": "No log.",
"no_user_to_add": "لا يوجد أي مستخدم لإضافته.",
"non_compatible_api": "واجهة برمجة التطبيقات API غير متوافقة",
"ok": "موافق",
"open": "فتح",
"operations": "الإجراءات",
"os": "نظام التشغيل",
"password": "كلمة السر",
"password_confirmation": "تأكيد كلمة السر",
"password_description": "يتوجب أن يكون طول كلمة السر %s أحرف على الأقل.",
"password_empty": "إنَّ حقل كلمة السر فارغ",
"password_new": "كلمة السر الجديدة",
"passwords_dont_match": "كلمات السر غير متطابقة",
"passwords_too_short": "كلمة السر قصيرة جدًا",
"path": "المسار",
"path_url": "المسار",
"port": "المنفذ",
"ports": "المنافذ",
"postinstall": "ما بعد التنصيب",
"postinstall_domain": "سوف يصبح هذا إسم النطاق الرئيسي المرتبط بخادوم واي يونوهوست YunoHost و الذي مِن خلاله يُمكن للمستخدمين النفاذ إلى بوابة المصادقة قصد تسجيل دخولهم. إسم النطاق هذا سيكون ظاهرا لكافة المستخدمين، لذا يتوجّب اختياره بعناية.",
"postinstall_intro_1": "هنيئًا ! تمت عملية تنصيب YunoHost بنجاح.",
"postinstall_intro_2": "لم يتبقى إلّا إكمال خطوتين لازمتين لتفعيل خدمات السيرفر.",
"postinstall_intro_3": "يمكنكم الحصول على مزيد مِن التفاصيل بزيارة <a href='//yunohost.org/postinstall' target='_blank'>صفحة التعليمات المخصصة لذلك</a>",
"postinstall_password": "سوف يتم استخدام كلمة السر هذه في إدارة كافة خدمات السيرفر. يُرجى التأني و الحِكمة عند اختيارها.",
"previous": "السابق",
"process": "Process",
"protocol": "Protocol",
"public_ip": "عنوان الإيبي العمومي : ",
"ram": "الذاكرة",
"read": "قراءة",
"read_more": "تعلم المزيد",
"reception": "تلقِّي",
"refresh_app_list": "تحديث القائمة",
"remove_access": "إلغاء تصريح النفاذ",
"restore": "إستعادة",
"running": "يشتغل",
"save": "حفظ",
"select_user": "إختر مستخدما",
"service_log": "%s log",
"service_start_on_boot": "تُطلَق عند بداية التشغيل",
"service_status": "الحالة : ",
"services": "الخدمات",
"services_list": "قائمة الخدمات",
"set_default": "تعيينه كافتراضي",
"size": "الحجم",
"start": "تشغيل",
"status": "الحالة",
"stop": "إيقاف التشغيل",
"storage_create": "إضافة مساحة تخزين عن بُعد",
"storages_new": "مساحة جديدة للتخزين عن بُعد",
"storages_no": "لا توجد أية مساحة تخزين.",
"swap": "Swap",
"system": "النظام",
"system_apps": "التطبيقات",
"system_apps_nothing": "كافة التطبيقات حديثة!",
"system_delayed_upgrade": "ترقية أو تحديث مؤجل",
"system_delayed_upgrade_warning": "سوف يُحدَّث <b>%s</b> تلقائيا خلال الساعة القادمة.",
"system_packages": "الحزم",
"system_packages_nothing": "كافة حزم النظام حديثة!",
"system_update": "تحديث النظام",
"system_upgrade": "تحديث النظام",
"system_upgrade_btn": "ترقية",
"system_upgrade_all_applications_btn": "تحديث كافة التطبيقات",
"system_upgrade_all_packages_btn": "تحديث كافة الحُزم",
"tcp": "TCP",
"time_since_update": "آخِر تحديث : ",
"tools": "الأدوات",
"tools_adminpw": "تعديل كلمة السر الإدارية",
"tools_adminpw_confirm_placeholder": "تأكيد كلمة السر الجديدة",
"tools_adminpw_current": "كلمة السر الحالية",
"tools_adminpw_current_placeholder": "قم بإدخال كلمتك السرية الحالية",
"tools_adminpw_new_placeholder": "إدخال كلمة السر الجديدة",
"tools_download_ca": "تنزيل هيئة شهادات الأمان SSL",
"tools_download_ca_desc": "أنقر هنا للشروع في تنزيل هيئتك لشهادات الأمان SSL",
"tools_security_feed": "إشعارات الأمان",
"tools_security_feed_no_items": "ليس هناك أية إشعارات بخصوص الأمان",
"tools_security_feed_subscribe_rss": "قم بالإكتتاب إلى إشعارات الأمان عبر RSS",
"tools_security_feed_view_items": "إظهار كافة الإشعارات الأمنية",
"tools_reboot": "إعادة تشغيل الخادم",
"tools_reboot_btn": "إعادة التشغيل",
"tools_reboot_done": "إعادة التشغيل جارية …",
@ -290,22 +158,13 @@
"tools_shutdown_done": "عملية إيقاف التشغيل جارية ...",
"tools_shuttingdown": "إنّ خادومك متوقف و طالما هو على هذا الحال فلن تتمكن مِن استعمال الواجهة الإدارية.",
"tools_shutdown_reboot": "إيقاف التشغيل/إعادة التشغيل",
"total": "المجموع",
"transmission": "الإرسال",
"udp": "UDP",
"unauthorized": "غير مسموح",
"uninstall": "إلغاء التنصيب",
"unknown_action": "إجراء مجهول %s",
"unknown_argument": "مُعامِل مجهول : %s",
"upload": "الرفع",
"upload_archive": "رفع نسخة إحتياطية",
"upnp": "UPnP",
"upnp_disabled": "UPnP معطّل.",
"upnp_enabled": "UPnP يشتغل.",
"uptime": "مدة التشغيل",
"url": "عنوان الرابط",
"usage": "الإستعمال",
"used": "مستعمَلة",
"user_email": "البريد الإلكتروني",
"user_emailaliases": "Mail aliases",
"user_emailforward": "تحويل البريد",
@ -314,17 +173,11 @@
"user_mailbox_quota": "مساحة علبة البريد",
"user_mailbox_use": "المساحة المستعمَلة في علبة البريد",
"user_new_forward": "newforward@myforeigndomain.org",
"user_new_mail": "newmail@mydomain.org",
"user_username": "إسم المستخدم",
"user_username_edit": "تعديل حساب %s",
"user_username_edit": "تعديل حساب {name}",
"users": "المستخدمون",
"users_list": "قائمة المستخدمين",
"users_new": "مستخدم جديد",
"users_no": "لا يوجد أي مستخدم.",
"versions": "الإصدارات",
"view_user_profile": "عرض الملف الشخصي لـ %s",
"warning_first_user": "ربما يتطلًب منك <a href='#/users/create' class='alert-link'>إنشاء مستخدِم</a> أولًا.",
"write": "الكتابة",
"wrong_password": "كلمة السر خاطئة",
"yes": "نعم",
"certificate_alert_not_valid": "حرِج : إنّ شهادة الأمان الحالية لم تعُد صالحة! لن يُصبح بالإمكان النفاذ عبر بروتوكول الـ HTTPS !",
@ -335,7 +188,6 @@
"certificate_alert_great": "رائع ! إنك تستخدم شهادة صالحة لـ Let's Encrypt !",
"certificate_alert_unknown": "حالة الشهادة غير معروفة",
"certificate_manage": "إدارة شهادات أمان SSL",
"certificate_old_letsencrypt_app_conflict": "إنّ تطبيق 'letsencrypt' مُثبّت حاليا و نشأ عن ذلك خلاف مع هذه الميزة. يُرجى منكم إلغاء تنصيبه أولا لتتمكنوا مِن استخدام الواجهة الجديدة لإدارة الشهادات.",
"ssl_certificate": "شهادة أمان SSL",
"confirm_cert_install_LE": "متأكد مِن أنك تريد تثبيت شهادة Let's Encrypt على هذا النطاق ؟",
"confirm_cert_regen_selfsigned": "أتريد إعادة توليد الشهادة الموقعة شخصيا لاسم النطاق هذا؟",
@ -350,25 +202,10 @@
"install_letsencrypt_cert": "تنصيب شهادة Let's Encrypt",
"manually_renew_letsencrypt_message": "سيطرأ تجديد الشهادة تلقائيا خلال الأيام الـ 15 مِن اقتراب نهاية صلاحيتها. يُمكنكم تجديدها يدويا إن شئتم. (غير مُستحسَن).",
"manually_renew_letsencrypt": "تجديد الشهادة يدويًا الآن",
"meltdown": "",
"regenerate_selfsigned_cert_message": "إن كنت ترغب في ذلك، بإمكانك إعادة توليد تلك الشهادة الموقعة شخصيًا.",
"regenerate_selfsigned_cert": "إعادة توليد الشهادة الموقعة ذاتيًا",
"revert_to_selfsigned_cert_message": "إن كنت ترغب في ذلك، بإمكانك إعادة تنصيب شهادة موقعة شخصيًا. (غير مُستحسن)",
"revert_to_selfsigned_cert": "العودة إلى الشهادة الموقعة ذاتيًا",
"appslists": "قوائم التطبيقات",
"appslists_no_lists": "لا توجد قوائم للبرمجيات",
"appslists_custom": "قائمة خاصة للتطبيقات",
"appslists_manage": "إدارة قوائم التطبيقات",
"appslists_confirm_remove": "متأكد من أنك تود حذف قائمة التطبيقات هذه؟",
"appslists_info_refresh_desc": "تحديث حالة برمجيات هذه القائمة.",
"appslists_info_remove_desc": "تطبيقات هذه القائمة لن تكون متوفرة بعد اليوم.",
"appslists_last_update": "آخر تحديث",
"appslists_unknown_list": "قائمة التطبيقات مجهولة : %s",
"appslists_community_list": "قائمة برمجيات المجتمع",
"name": "الإسم",
"install_community_appslists_info": "تتيح لك قائمة التطبيقات المجتمعية إمكانية تثبيت التطبيقات المُصانة.<br /> اطلع على القائمة كاملة على <a href='https://yunohost.org/apps_in_progress'>yunohost.org/apps_in_progress</a>.",
"install_community_appslists_warning": "يُرجى منكم الأخذ بعين الاعتبار أنّ حُزم التطبيقات هذه <strong>ليست</strong> رسمية و هي غير مدعومة مِن طرف فريق واي يونوهوست. <br />تثبيت هذه التطبيقات تحت مسؤوليتك الخاصة قد يؤدي إلى تعطّل نظامك.",
"install_custom_app_appslists_info": "بإمكانكم استخدام قوائم تطبيقات بديلة لتنصيب تطبيقات أخرى يدعمها مجتمع واي يونوهوست YunoHost.",
"migrations": "الارتحال",
"migrations_pending": "الترحيلات المعلقة",
"migrations_done": "الترحيلات السابقة",
@ -377,16 +214,7 @@
"run": "شَغِّل",
"skip": "تخطي",
"confirm_migrations_skip": "إنّ تخطي التهجير غير مستحسَن. متأكد مِن أنك تريد ذلك ؟",
"service_description": "الوصف :",
"started_at": "تم تشغيله على :",
"active": "مُفعَّل",
"all_apps": "كافة التطبيقات",
"app_license": "رخصة التطبيق",
"app_level": "درجة التطبيق",
"app_state_official": "رسمي",
"current_maintainer_title": "المشرف الحالي على هذه الحزمة",
"level": "الدرجة",
"only_official_apps": "إلاّ التطبيقات الرسمية",
"only_working_apps": "إلاّ التطبيقات التي تعمل",
"logs": "السِجلات",
"logs_history": "سِجِل الأوامر التي تم تنفيذها على النظام",
@ -399,30 +227,24 @@
"logs_context": "السياق",
"logs_share_with_yunopaste": "شاركه عبر YunoPaste",
"logs_more": "اظهر المزيد مِن الأسطر",
"search_for_apps": "البحث عن تطبيقات…",
"select_all": "تحديد الكل",
"version": "الإصدار",
"app_no_actions": "لا يحتوي هذا التطبيق على أية إجراءات",
"logs_operation": "الإجراءات التي طرأت على النظام عبر YunoHost",
"logs_no_logs_registered": "لم يُسجَّل هناك أي حدث في سِجِل هذه الفئة",
"logs_end_with_error": "انتهى هذا السِجِل بالخطأ التالي:",
"unmaintained": "غير مُصان",
"app_state_high-quality": "جودة عالية",
"app_state_highquality": "جودة عالية",
"license": "الرخصة",
"orphaned": "غير مصان",
"advanced": "متقدّم",
"from_to": "مِن %s إلى %s",
"maintained": "مُصان",
"from_to": "مِن {0} إلى {1}",
"only_highquality_apps": "إلا التطبيقات ذات الجودة العالية",
"only_decent_quality_apps": "إلا التطبيقات ذات الجودة الحسنة",
"request_adoption": "في انتظار التبنّي",
"request_help": "بحاجة إلى مساعدة",
"confirm_update_system": "أمتأكد مِن أنك تريد تحديث كافة حزم النظام؟",
"experimental_warning": "تحذير: هذه الميزة تجريبية ولا تعتبر مستقرة ، يجب ألا تستخدمها إلا إذا كنت تعرف ما تفعله.",
"hook_conf_ynh_currenthost": "النطاق الرئيسي الحالي",
"logs_package": "سِجلّ إدارة حزم ديبيان",
"error_connection_interrupted": "أغلق الخادم الاتصال بدلاً من الاستجابة. هل تم إعادة تشغيل Nginx أو تم إيقاف تشغيل واجهة برمجة تطبيقات YunoHost؟ (رمز/رسالة الخطأ: %s)",
"warnings": "%s تحذيرات",
"error_connection_interrupted": "أغلق الخادم الاتصال بدلاً من الاستجابة. هل تم إعادة تشغيل Nginx أو تم إيقاف تشغيل واجهة برمجة تطبيقات YunoHost؟ (رمز/رسالة الخطأ: )",
"warnings": "{count} تحذيرات",
"unignore": "إلغاء التجاهل",
"since": "منذ",
"restart": "إعادة التشغيل",
@ -431,13 +253,12 @@
"others": "أخرى",
"nobody": "لا أحد",
"last_ran": "آخر تشغيل:",
"issues": "%s مشاكل",
"ignored": "تم تجاهل %s",
"issues": "{count} مشاكل",
"ignored": "تم تجاهل {count}",
"ignore": "تجاهل",
"permissions": "التصريحات",
"groups_and_permissions_manage": "إدارة الفِرَق والتصريحات",
"groups_and_permissions": "الفِرَق والتصريحات",
"groups": "الفِرَق",
"group_new": "فريق جديد",
"group_add_permission": "إضافة إذن",
"group_add_member": "إضافة مستخدم",
@ -447,10 +268,10 @@
"everything_good": "كل شيء على ما يرام!",
"run_first_diagnosis": "شغّل الفحص الأوّلي",
"details": "التفاصيل",
"confirm_service_restart": "أمتأكد مِن أنك تريد إعادة تشغيل %s؟",
"confirm_service_restart": "أمتأكد مِن أنك تريد إعادة تشغيل {name}؟",
"configuration": "الإعداد",
"catalog": "الفهرس",
"app_state_low_quality": "جودة ضعيفة",
"app_state_lowquality": "جودة ضعيفة",
"all": "كلها",
"group_explain_visitors": "هذا فريق خاص بالزوار المجهولين",
"group_visitors": "الزوار"

View file

@ -0,0 +1,9 @@
{
"action": "কৃয়া",
"add": "যুক্ত করুন",
"administration_password": "পরিচালনাকারীর পাসওয়ার্ড",
"all_apps": "সকল অ্যাপ্লিকেশান",
"api_not_responding": "এপিআই সাড়া দিচ্ছে না",
"password": "পাসওয়ার্ড",
"ok": "ঠিক আছে"
}

View file

@ -1,148 +1,80 @@
{
"action": "Acció",
"active": "Actiu",
"add": "Afegir",
"remove": "Suprimir",
"administration_password": "Contrasenya d'administració",
"allowed_users": "Usuaris permesos",
"api_not_responding": "L'API de YunoHost no respon. Pot ser que «yunohost-api» estigui caigut o s'hagi reiniciat?",
"app_access": "Accés",
"app_access_addall_btn": "Habilitar l'accés a tots els utilitzadors",
"app_access_addall_desc": "Tots els usuaris existents tindran accés a %s.",
"app_access_clearall_btn": "Desactivar tots els accessos",
"app_access_clearall_desc": "Cada usuari tindrà accés a %s.",
"app_access_removeall_btn": "Eliminar tots els accessos",
"app_access_removeall_desc": "Cap usuari tindrà accés a %s.",
"app_access_title": "Accés a %s",
"app_change_label": "Canviar l'etiqueta",
"app_change_url": "Canvia l'URL",
"app_debug_no_logs": "Els registres de l'aplicació no estan disponibles",
"app_debug_tab": "Mostra la informació de depuració",
"app_info_access_desc": "Grups / usuaris autoritzats actualment a accedir a aquesta aplicació:",
"app_info_changelabel_desc": "Canvia l'etiqueta de l'aplicació al portal.",
"app_info_debug_desc": "Mostrar la informació de depuració per aquesta aplicació.",
"app_info_default_desc": "Redirigeix l'arrel del domini a aquesta aplicació (%s).",
"app_info_default_desc": "Redirigeix l'arrel del domini a aquesta aplicació ({domain}).",
"app_info_changeurl_desc": "Canvia l'adreça d'accés (URL) d'aquesta aplicació (domini i/o camí).",
"app_info_change_url_disabled_tooltip": "Encara no s'ha implementat aquesta funcionalitat per a aquesta aplicació",
"app_info_uninstall_desc": "Eliminar aquesta aplicació.",
"app_install_cancel": "Instal·lació cancel·lada.",
"app_install_custom_no_manifest": "No s'ha trobat el fitxer manifest.json",
"app_list": "Llista d'aplicacions",
"app_make_default": "Establir com a predeterminat",
"app_repository": "Origen de l'aplicació: ",
"app_state": "Estat de l'aplicació: ",
"app_state_inprogress": "encara no funciona",
"app_state_notworking": "no funciona",
"app_state_validated": "Validat",
"app_state_working": "funcionant",
"application": "Aplicació",
"applications": "Aplicacions",
"archive_empty": "Arxiu buit",
"available": "Disponible",
"available_apps": "Aplicacions disponibles",
"backup": "Còpia de seguretat",
"backup_action": "Fer còpia de seguretat",
"backup_archive_copy": "Copiar aquest arxiu en un altre lloc d'emmagatzematge",
"backup_archive_delete": "Eliminar aquest arxiu",
"backup_archive_download": "Descarregar aquest arxiu",
"backup_content": "Contingut de la còpia de seguretat",
"backup_create": "Crear una còpia de seguretat",
"backup_encryption_warning": "No oblidi aquesta contrasenya, la necessitarà si vol restaurar l'arxiu",
"backup_new": "Nova còpia de seguretat",
"backup_optional_encryption": "Xifratge opcional",
"backup_optional_password": "Contrasenya opcional",
"backup_type": "Tipus",
"backups_no": "No hi ha còpies de seguretat",
"begin": "Començar",
"bit_rate": "Taxa de bits",
"both": "Ambdós",
"cancel": "Cancel·lar",
"check": "Comprovar",
"check_mx": "Registre MX",
"check_stmp": "Accés al port 25",
"close": "Tancar",
"confirm_access_add": "Està segur de voler afegir accés a %s per a tots els usuaris?",
"confirm_access_clear": "Està segur de voler esborrar tots els accessos a %s?",
"confirm_access_remove_all": "Està segur de voler eliminar tots els accessos a %s?",
"confirm_access_remove_user": "Està segur de voler eliminar l'accés a %s per %s?",
"confirm_app_change_url": "Està segur de voler canviar l'adreça d'accés (URL) d'aquesta aplicació?",
"confirm_app_default": "Està segur de voler fer aquesta aplicació predeterminada?",
"confirm_change_maindomain": "Està segur de voler canviar el domini principal?",
"confirm_delete": "Està segur de voler eliminar %s?",
"confirm_firewall_open": "Està segur de voler obrir el port %s? (protocol: %s, connexió: %s)",
"confirm_firewall_close": "Està segur de voler tancar el port %s? (protocol: %s, connexió: %s)",
"confirm_delete": "Està segur de voler eliminar {name}?",
"confirm_firewall_open": "Està segur de voler obrir el port {port}? (protocol: {protocol}, connexió: {connection})",
"confirm_firewall_close": "Està segur de voler tancar el port {port}? (protocol: {protocol}, connexió: {connection})",
"confirm_install_custom_app": "ATENCIÓ! La instal·lació d'aplicacions de terceres parts pot comprometre la integritat i seguretat del seu sistema. No hauríeu d'instal·lar-ne a no ser que sapigueu el que feu. Esteu segurs de voler córrer aquest risc?",
"confirm_install_domain_root": "No podrà instal·lar cap altra aplicació %s. Vol continuar?",
"confirm_install_domain_root": "No podrà instal·lar cap altra aplicació {domain}. Vol continuar?",
"confirm_migrations_skip": "Saltar-se les migracions no està recomanat. Està segur de voler continuar?",
"confirm_postinstall": "Està a punt de començar el procés de post-instal·lació en el domini %s. Pot tardar uns minuts, *no interrompi la operació*.",
"confirm_restore": "Està segur de voler restaurar %s?",
"confirm_service_start": "Està segur de voler iniciar %s?",
"confirm_service_stop": "Està segur de voler parar %s?",
"confirm_service_enable": "Està segur de voler activar %s?",
"confirm_service_disable": "Està segur de voler desactivar %s?",
"confirm_uninstall": "Està segur de voler desinstal·lar %s?",
"confirm_postinstall": "Està a punt de començar el procés de post-instal·lació en el domini {domain}. Pot tardar uns minuts, *no interrompi la operació*.",
"confirm_restore": "Està segur de voler restaurar {name}?",
"confirm_service_start": "Està segur de voler iniciar {name}?",
"confirm_service_stop": "Està segur de voler parar {name}?",
"confirm_uninstall": "Està segur de voler desinstal·lar {name}?",
"confirm_update_apps": "Està segur de voler actualitzar totes les aplicacions?",
"confirm_update_packages": "Està segur de voler actualitzar tots els paquets?",
"confirm_update_specific_app": "Està segur de voler actualitzar %s?",
"confirm_update_specific_app": "Està segur de voler actualitzar {app}?",
"confirm_upnp_enable": "Està segur de voler activar UPnP?",
"confirm_upnp_disable": "Està segur de voler desactivar UPnP?",
"confirm_reboot_action_reboot": "Està segur de voler reiniciar el servidor?",
"confirm_reboot_action_shutdown": "Està segur de voler apagar el servidor?",
"connection": "Connexió",
"copy": "Copiar",
"count_min": "%s min",
"cpu_load": "Càrrega de la CPU",
"created_at": "Creat a",
"cumulative_usage": "Utilització acumulada",
"custom_app_install": "Instal·lar una aplicació personalitzada",
"custom_app_url_only_github": "Únicament des de GitHub",
"default": "Predeterminat",
"delete": "Suprimir",
"description": "Descripció",
"domain_dns_conf_is_just_a_recommendation": "Aquesta pàgina mostra la configuració *recomanada*. Aquesta pàgina *no* configura el DNS. És la seva responsabilitat configurar la zona DNS al seu registrar DNS en acord amb aquesta recomanació.",
"diagnosis": "Diagnòstic",
"diagnosis_hide_private": "Mostrar les dades de diagnòstic sense dades privades",
"diagnosis_view_private": "Mostrar les dades de diagnòstic incloses les dades privades",
"diagnosis_with_private": "Diagnòstic amb dades privades",
"disable": "Desactivar",
"disabled": "Desactivat",
"disk": "Disc",
"dns": "DNS",
"domain": "Domini",
"domain_add": "Afegir domini",
"domain_add_dns_doc": "... i he <a href='//yunohost.org/dns'> configurat el meu DNS correctament</a>.",
"domain_add_dyndns_doc": "... i vull uns servei de DNS dinàmic.",
"domain_add_panel_with_domain": "Ja tinc un nom de domini…",
"domain_add_panel_without_domain": "No tinc un nom de domini…",
"domain_default": "Domini predeterminat",
"domain_default_desc": "Els usuaris iniciaran sessió al domini predeterminat.",
"domain_default_longdesc": "Aquest és el seu domini predeterminat.",
"domain_delete_longdesc": "Eliminar aquest domini",
"domain_dns_config": "Configuració de DNS",
"domain_dns_longdesc": "Veure la configuració DNS",
"domain_list": "Llista de dominis",
"domain_name": "Nom del domini",
"domain_select": "Seleccioni un domini",
"domain_visit": "Visitar",
"domain_visit_url": "Visitar %s",
"domain_visit_url": "Visitar {url}",
"domains": "Dominis",
"download": "Descarregar",
"enable": "Activar",
"enabled": "Activat",
"error_modify_something": "Heu de modificar quelcom",
"error_occured": "Hi ha hagut un error, torneu a intentar",
"error_retrieve_feed": "No s'ha pogut recuperar el fil: %s. Pot ser que tingueu un complement que no permet al vostre navegador fer aquesta sol·licitud (o la pàgina està caiguda).",
"error_select_domain": "Heu d'indicar un domini",
"error_server": "Error del servidor",
"error_server_unexpected": "Error inesperat en el servidor (%s)",
"everyone_has_access": "Tots els usuaris tenen accés.",
"filesystem": "Sistema de fitxers",
"error_server_unexpected": "Error inesperat en el servidor",
"firewall": "Tallafoc",
"footer_version": "Propulsat per <a href='https://yunohost.org'> YunoHost</a> %s (%s).",
"form_input_example": "Exemple: %s",
"free": "Lliure",
"fs_type": "Tipus de sistema de fitxers",
"gateway": "Passarel·la: ",
"footer_version": "Propulsat per <a href='https://yunohost.org'> YunoHost</a> {version} ({repo}).",
"form_input_example": "Exemple: {example}",
"home": "Inici",
"hook_adminjs_group_configuration": "Configuració del sistema",
"hook_conf_cron": "Tasques automàtiques",
@ -158,30 +90,18 @@
"hook_data_home_desc": "Les dades d'usuari són a /home/USUARI",
"hook_data_mail": "Correu",
"hook_data_mail_desc": "Correus guardats en el servidor",
"hostname": "Nom de l'amfitrió",
"id": "ID",
"inactive": "Inactiu",
"infos": "Informació",
"install": "Instal·lar",
"install_name": "Instal·lar %s",
"install_name": "Instal·lar {id}",
"install_time": "Temps d'instal·lació",
"installation_complete": "Instal·lació completada",
"installed": "Instal·lar",
"installed_apps": "Aplicacions instal·lades",
"installing": "Instal·lant",
"interface": "Interfície",
"internal_exception": "<strong> YunoHost a trobat un error intern :/</strong><br><em>Ens sap molt greu.<br> Hauria de buscar ajuda a <a href=\"https://forum.yunohost.org/\">el formum</a> o <a href=\"https://chat.yunohost.org/\"> el xat</a> per arreglar el problema, o per notificar el bug a <a href=\"https://github.com/YunoHost/issues\">the bugtracker</a>.</em><br> La informació següent pot ser útil per la persona que l'ajudi: <h3> Acció</h3><pre>%s%s</pre><h3> Traça </h3><pre>%s</pre>",
"io": "I/O",
"ipv4": "IPv4",
"ipv6": "IPv6",
"label": "Etiqueta",
"label_for_manifestname": "Etiqueta per %s",
"loading": "Carregant…",
"label_for_manifestname": "Etiqueta per {name}",
"local_archives": "Arxius locals",
"local_ip": "IP local",
"log": "Registre",
"logged_in": "Sessió iniciada",
"logged_out": "Sessió tancada",
"login": "Iniciar sessió",
"logout": "Tancar sessió",
"mailbox_quota_description": "Per exemple, 700M és un CD i 4700M és un DVD.",
@ -189,107 +109,53 @@
"manage_apps": "Gestionar les aplicacions",
"manage_domains": "Gestionar els dominis",
"manage_users": "Gestionar els usuaris",
"memory": "Memòria",
"menu": "Menú",
"migrations": "Migracions",
"migrations_pending": "Migracions en espera",
"migrations_done": "Migracions anteriors",
"migrations_no_pending": "No hi ha migracions en espera",
"migrations_no_done": "No hi ha migracions anteriors",
"mode": "Mode",
"monitoring": "Monitoratge",
"monitoring_check_glances": "Verifiqueu l'estat del servei <a href='#/services/glances'>glances</a>.",
"monitoring_disabled": "El monitoratge no està activat.",
"mount_point": "Punt de muntatge",
"multi_instance": "Instàncies múltiples",
"myserver": "elmeuservidor",
"myserver_org": "elmeuservidor.org",
"network": "Xarxa",
"next": "Següent",
"no": "No",
"no_allowed_users": "Cap usuari autoritzat.",
"no_installed_apps": "No hi ha aplicacions instal·lades.",
"no_log": "No hi ha registre.",
"no_user_to_add": "Cap usuari a afegir.",
"non_compatible_api": "L'API no és compatible",
"ok": "OK",
"open": "Obrir",
"operations": "Operacions",
"os": "Sistema operatiu",
"password": "Contrasenya",
"password_confirmation": "Confirmar contrasenya",
"password_description": "La contrasenya ha de tenir com a mínim %s caràcters.",
"password_empty": "El camp de la contrasenya està buit",
"password_new": "Nova contrasenya",
"passwords_dont_match": "Les contrasenyes no coincideixen",
"passwords_too_short": "La contrasenya és massa curta",
"path": "Camí",
"path_url": "Camí",
"port": "Port",
"ports": "Ports",
"postinstall": "Post-instal·lació",
"postinstall_domain": "Aquest és el primer nom de domini vinculat al vostre servidor YunoHost, però també el que utilitzaran els usuaris del servidor per accedir al portal d'autenticació. Així doncs serà visible per tothom, escolliu-lo amb cura.",
"postinstall_intro_1": "Felicitats! YunoHost s'ha instal·lat correctament.",
"postinstall_intro_2": "Falten dos passos més per activar els serveis del seu servidor.",
"postinstall_intro_3": "Pot obtenir més informació visitant <a href='//yunohost.org/postinstall' target='_blank'>la pàgina de documentació</a>",
"postinstall_password": "Aquesta contrasenya serà utilitzada per administrar tot en el servidor. Prengui el temps d'escollir una bona contrasenya.",
"previous": "Precedent",
"process": "Procés",
"protocol": "Protocol",
"public_ip": "IP pública: ",
"ram": "RAM",
"read": "Llegir",
"read_more": "Saber-ne més",
"reception": "Recepció",
"refresh_app_list": "Actualitzar la llista",
"remove_access": "Retirar accés",
"restore": "Restaurar",
"running": "En execució",
"save": "Guardar",
"select_user": "Seleccioneu un usuari",
"service_description": "Descripció:",
"service_log": "Registre %s",
"service_start_on_boot": "Iniciar a l'engegada",
"service_status": "Estat: ",
"services": "Serveis",
"services_list": "Llista de serveis",
"set_default": "Establir com a predeterminat",
"size": "Talla",
"skip": "Passar",
"start": "Engegar",
"started_at": "Engegat a:",
"status": "Estat",
"stop": "Aturar",
"storage_create": "Afegir emmagatzematge remot",
"storages_new": "Nou emmagatzematge remot",
"storages_no": "Sense emmagatzematge.",
"swap": "Memòria d'intercanvi",
"system": "Sistema",
"system_apps": "Aplicacions",
"system_apps_nothing": "Totes les aplicacions estan actualitzades!",
"system_delayed_upgrade": "S'ha posposat l'actualització",
"system_delayed_upgrade_warning": "<b>%s</b> serà actualitzat automàticament durant la pròxima hora.",
"system_packages": "Paquets del sistema",
"system_packages_nothing": "Tots els paquets del sistema estan actualitzats!",
"system_update": "Actualització del sistema",
"system_upgrade": "Actualització del sistema",
"system_upgrade_btn": "Actualització",
"system_upgrade_all_applications_btn": "Actualitza totes les aplicacions",
"system_upgrade_all_packages_btn": "Actualitza tots els paquets",
"tcp": "TCP",
"time_since_update": "Temps des de l'última actualització: ",
"tools": "Eines",
"tools_adminpw": "Canviar la contrasenya d'administració",
"tools_adminpw_confirm_placeholder": "Confirmar la nova contrasenya",
"tools_adminpw_current": "Contrasenya actual",
"tools_adminpw_current_placeholder": "Introdueixi la contrasenya actual",
"tools_adminpw_new_placeholder": "Introdueixi la nova contrasenya",
"tools_download_ca": "Descarregar l'autoritat certificadora SSL (CA)",
"tools_download_ca_desc": "Faci clic aquí per descarregar la seva autoritat certificadora SSL (CA)",
"tools_security_feed": "Notificacions de seguretat",
"tools_security_feed_no_items": "No hi ha notificacions de seguretat",
"tools_security_feed_subscribe_rss": "Subscriure's al canal RSS de notificacions de seguretat",
"tools_security_feed_view_items": "Veure totes les notificacions de seguretat",
"tools_reboot": "Reiniciar el servidor",
"tools_reboot_btn": "Reiniciar",
"tools_reboot_done": "Reiniciant....",
@ -299,39 +165,24 @@
"tools_shutdown_done": "S'està apagant...",
"tools_shuttingdown": "El servidor s'està apagant. Mentre estigui apagat no podrà utilitzar la web d'administració.",
"tools_shutdown_reboot": "Apagar/Reiniciar",
"total": "Total",
"transmission": "Transmissió",
"udp": "UDP",
"unauthorized": "No autoritzat",
"uninstall": "Desinstal·lar",
"unknown_action": "Acció desconeguda %s",
"unknown_argument": "Argument desconegut: %s",
"upload": "Pujar",
"upload_archive": "Pujar fitxer",
"upnp": "UPnP",
"upnp_disabled": "UPnP està desactivat.",
"upnp_enabled": "UPnP està activat.",
"uptime": "Temps en funcionament",
"url": "URL",
"usage": "Utilització",
"used": "Utilitzat",
"user_email": "Correu electrònic",
"user_emailaliases": "Àlies de correu",
"user_fullname": "Nom complet",
"user_interface_link": "Interfície d'usuari",
"user_mailbox_quota": "Quota de correu",
"user_mailbox_use": "Espai utilitzat",
"user_new_mail": "noucorreu@elmeudomini.org",
"user_username": "Nom d'usuari",
"user_username_edit": "Editar el compte de %s",
"user_username_edit": "Editar el compte de {name}",
"users": "Usuaris",
"users_list": "Llista d'usuaris",
"users_new": "Nou usuari",
"users_no": "No hi ha usuaris.",
"versions": "Versions",
"view_user_profile": "Veure el perfil de %s",
"warning_first_user": "Hauríeu de crear un <a href='#/users/create' class='alert-link'>usuari</a> primer.",
"write": "Escriure",
"wrong_password": "Contrasenya incorrecta",
"yes": "Sí",
"certificate_alert_not_valid": "CRÍTIC: El certificat actual no és vàlid! HTTPS no funcionarà!",
@ -342,7 +193,6 @@
"certificate_alert_great": "Perfecte! Esteu utilitzant un certificat Let's Encrypt vàlid!",
"certificate_alert_unknown": "Estat desconegut",
"certificate_manage": "Administrar el certificat SSL",
"certificate_old_letsencrypt_app_conflict": "L'aplicació 'letsencrypt' està instal·lada i entra en conflicte amb aquesta funció. Si us plau desinstal·leu-la primer per utilitzar la nova interfície d'administració de certificats.",
"ssl_certificate": "Certificat SSL",
"confirm_cert_install_LE": "Està segur de voler instal·lar un certificat Let's Encrypt per aquest domini?",
"confirm_cert_regen_selfsigned": "Esteu segur que voleu regenerar un certificat auto-signat per aquest domini?",
@ -358,41 +208,20 @@
"install_letsencrypt_cert": "Instal·la un certificat Let's Encrypt",
"manually_renew_letsencrypt_message": "El certificat es renovarà automàticament durant els últims 15 dies de validesa. El podeu renovar manualment si ho desitgeu. (No recomanat).",
"manually_renew_letsencrypt": "Renovar manualment ara",
"meltdown": "Sou vulnerable a la falla de seguretat crítica <a target=\"_blank\" href=\"https://meltdownattack.com/\">meltdown</a>. Per resoldre el problema heu d'<a href=\"#/update\">actualitzar el sistema</a> i després <a href=\"#/tools/reboot\"> reiniciar-lo</a> per carregar el nou nucli linux.",
"regenerate_selfsigned_cert_message": "Si voleu, podeu regenerar el certificat auto-signat.",
"regenerate_selfsigned_cert": "Regenerar el certificat auto-signat",
"revert_to_selfsigned_cert_message": "Si realment ho desitja, pot tornar a instal·lar el certificat auto-signat. (No recomanat)",
"revert_to_selfsigned_cert": "Tornar a un certificat auto-signat",
"appslists": "Llistes d'aplicacions",
"appslists_no_lists": "No hi ha llistes d'aplicacions",
"appslists_custom": "Llista d'aplicacions personalitzada",
"appslists_manage": "Gestionar llistes d'aplicacions",
"appslists_confirm_remove": "Esteu segur de voler suprimir aquesta llista d'aplicacions?",
"appslists_info_refresh_desc": "Refrescar l'estatus de les aplicacions d'aquesta llista.",
"appslists_info_remove_desc": "Les aplicacions d'aquesta llista ja no estaran disponibles.",
"appslists_last_update": "Última actualització",
"appslists_unknown_list": "Llista d'aplicacions desconeguda: %s",
"appslists_community_list": "Llista d'aplicacions de la comunitat",
"name": "Nom",
"install_community_appslists_info": "La llista d'aplicacions de la comunitat permet instal·lar aplicacions mantingudes per la comunitat.<br /> Trobareu la llista completa a <a href='https://yunohost.org/apps_in_progress'>yunohost.org/apps_in_progress</a>.",
"install_community_appslists_warning": "Tingueu en compte que aquestes aplicacions <strong>no</strong> són oficials i no són mantingudes per l'equip YunoHost. <br />Instal·leu aquestes aplicacions sota la vostra responsabilitat, pot posar en risc el teu sistema.",
"install_custom_app_appslists_info": "Podeu utilitzar llistes d'aplicacions alternatives per instal·lar altres aplicacions mantingudes per la comunitat YunoHost.",
"user_emailforward": "Reenviament de E-mail",
"user_new_forward": "noureenviar@dominiextern.org",
"all_apps": "Totes les aplicacions",
"app_license": "Llicència de l'aplicació",
"app_level": "Nivell de l'aplicació",
"app_no_actions": "Aquesta aplicació no té cap acció",
"app_state_official": "Oficial",
"confirm_install_app_warning": "Atenció: aquesta aplicació funciona però encara no està ben integrada a YunoHost. Algunes característiques com la identificació única i la còpia de seguretat i restauració de l'aplicació poden no estar presents.",
"confirm_install_app_danger": "ATENCIÓ! Aquesta aplicació encara és experimental (si no és que no funciona directament) i és probable que trenqui el sistema! No hauríeu d'instal·lar-la a no ser que sapigueu el que feu. Esteu segurs de voler córrer aquest risc?",
"current_maintainer_title": "Mantenidor d'aquest paquet actualment",
"error_connection_interrupted": "El servidor a tancat la connexió en lloc de respondre. S'han reiniciat o aturat nginx o yunohost-api per alguna raó? (Codi d'error/missatge: %s)",
"confirm_install_app_lowquality": "Atenció: aquesta aplicació funciona però encara no està ben integrada a YunoHost. Algunes característiques com la identificació única i la còpia de seguretat i restauració de l'aplicació poden no estar presents.",
"confirm_install_app_inprogress": "ATENCIÓ! Aquesta aplicació encara és experimental (si no és que no funciona directament) i és probable que trenqui el sistema! No hauríeu d'instal·lar-la a no ser que sapigueu el que feu. Esteu segurs de voler córrer aquest risc?",
"error_connection_interrupted": "El servidor a tancat la connexió en lloc de respondre. S'han reiniciat o aturat nginx o yunohost-api per alguna raó?",
"experimental_warning": "Atenció: aquesta característica és experimental i no es considera estable, no l'hauríeu d'utilitzar a excepció de saber el que feu.",
"good_practices_about_admin_password": "Esteu a punt de definir una nova contrasenya d'administrador. La contrasenya ha de tenir un mínim de 8 caràcters ; tot i que és de bona pràctica utilitzar una contrasenya més llarga (és a dir una frase de contrasenya) i/o utilitzar diferents tipus de caràcters (majúscules, minúscules, dígits i caràcters especials).",
"good_practices_about_user_password": "Esteu a punt de definir una nova contrasenya d'usuari. La contrasenya ha de tenir un mínim de 8 caràcters ; tot i que és de bona pràctica utilitzar una contrasenya més llarga (és a dir una frase de contrasenya) i/o utilitzar diferents tipus de caràcters (majúscules, minúscules, dígits i caràcters especials).",
"level": "nivell",
"only_official_apps": "Només aplicacions oficials",
"only_working_apps": "Només aplicacions que funcionen",
"logs": "Registres",
"logs_operation": "Operacions fetes al sistema amb YunoHost",
@ -403,7 +232,6 @@
"logs_service": "Registres dels serveis",
"logs_app": "Registres de les aplicacions",
"logs_no_logs_registered": "No hi ha cap registre per aquesta categoria",
"logs_end_with_error": "Aquest registre ha acabat amb l'error:",
"logs_error": "Error",
"logs_ended_at": "Fi",
"logs_started_at": "Principi",
@ -411,33 +239,25 @@
"logs_context": "Context",
"logs_share_with_yunopaste": "Comparteix amb YunoPaste",
"logs_more": "Mostra més línies",
"search_for_apps": "Cerca aplicacions...",
"select_all": "Selecciona-ho tot",
"select_none": "No en seleccionis cap",
"unmaintained": "No mantingut",
"purge_user_data_checkbox": "Purga les dades de %s? (Això suprimirà el contingut de la carpeta home i mail.)",
"purge_user_data_checkbox": "Purga les dades de {name}? (Això suprimirà el contingut de la carpeta home i mail.)",
"purge_user_data_warning": "Purgar les dades de l'usuari no és reversible. Assegureu-vos de saber el que esteu fent!",
"version": "Versió",
"confirm_update_system": "Esteu segurs de voler actualitzar tots els paquets del sistema?",
"hook_conf_ynh_currenthost": "Domini principal actual",
"app_state_inprogress_explanation": "El desenvolupador d'aquesta aplicació ha dit que encara no està preparada per fer-ne un ús en producció. SIGUEU PRUDENTS!",
"app_state_notworking_explanation": "El desenvolupador d'aquesta aplicació l'ha marcat com que «no funciona». TRENCARÀ EL SISTEMA!",
"app_state_high-quality": "alta qualitat",
"app_state_high-quality_explanation": "Aquesta aplicació està ben integrada amb YunoHost. Ha estat (i és!) revisada per l'equip d'aplicacions de YunoHost. És segura i serà mantinguda a llarg termini.",
"app_state_highquality": "alta qualitat",
"app_state_highquality_explanation": "Aquesta aplicació està ben integrada amb YunoHost. Ha estat (i és!) revisada per l'equip d'aplicacions de YunoHost. És segura i serà mantinguda a llarg termini.",
"app_state_working_explanation": "El desenvolupador d'aquesta aplicació l'ha marcat com «funcionant». Això vol dir que hauria de ser funcional (c.f. nivells d'aplicació) però no té perquè haver estat comprovada, pot encara tenir problemes o no estar completament integrada amb YunoHost.",
"license": "Llicència",
"maintained": "mantinguda",
"maintained_details": "Aquesta aplicació ha estat mantinguda en els darrers mesos.",
"only_highquality_apps": "Només aplicacions d'alta qualitat",
"only_decent_quality_apps": "Només aplicacións de qualitat decent",
"orphaned": "No mantinguda",
"orphaned_details": "Aquesta aplicació no ha estat mantinguda des de fa temps. Pot ser que funcioni, però no rebrà actualitzacions fins que algú es faci voluntari per ocupar-se'n. No dubteu en contribuir reviure-la!",
"request_adoption": "en espera d'adopció",
"request_adoption_details": "El desnevolupador actual voldria deixar de mantenir aquesta aplicació. Podeu proposar-vos com a nou desenvolupador!",
"request_help": "ajuda necessària",
"request_help_details": "El desenvolupador actual necessita ajuda per mantenir aquesta aplicació. Podeu contribuir-hi!",
"advanced": "Avançat",
"from_to": "de %s fins a %s",
"from_to": "de {0} fins a {1}",
"group": "Grup",
"group_name": "Nom del grup",
"group_all_users": "Tots els usuaris",
@ -458,35 +278,34 @@
"diagnosis_experimental_disclaimer": "Tingueu en compte que l'opció de diagnòstic encara és experimental i s'està millorant, i pot no ser del tot fiable.",
"everything_good": "Tot està bé!",
"ignore": "Ignorar",
"ignored": "%s ignorat",
"errors": "%s errors",
"ignored": "{count} ignorat",
"last_ran": "Executat per última vegada:",
"warnings": "%s avisos",
"warnings": "{count} avisos",
"words": {
"default": "Predeterminat"
},
"unignore": "No ignorar",
"configuration": "Configuració",
"since": "des de",
"others": "Altres",
"catalog": "Catàleg",
"app_state_low_quality_explanation": "Aquesta aplicació pot funcionar, però encara té problemes, o bé encara no està completament integrada a YunoHost, o bé no respecta les bones pràctiques.",
"app_state_low_quality": "baixa qualitat",
"app_state_lowquality_explanation": "Aquesta aplicació pot funcionar, però encara té problemes, o bé encara no està completament integrada a YunoHost, o bé no respecta les bones pràctiques.",
"app_state_lowquality": "baixa qualitat",
"all": "Tot",
"run_first_diagnosis": "Executa el diagnòstic inicial",
"diagnosis_first_run": "La funció de diagnòstic intentarà identificar problemes habituals de diferents aspectes del servidor per tal d'assegurar que tot funcioni de la millor manera possible. No tingueu por si veieu uns quants errors just després de configurar el servidor: està precisament fet per ajudar a identificar els problemes i oferir una guia de com arreglar-los. El diagnòstic també s'executarà dues vegades al dia i s'enviarà un correu a l'administrador si es troben errors.",
"confirm_service_restart": "Esteu segur de voler reiniciar %s?",
"confirm_service_restart": "Esteu segur de voler reiniciar {name}?",
"group_explain_visitors_needed_for_external_client": "Vigileu ja que s'ha de permetre els visitants en algunes aplicacions si voleu utilitzar-les amb clients externs. És el cas, per exemple, de Nextcloud si voleu utilitzar el client de sincronització en el telèfon mòbil o en l'ordinador.",
"groups": "Grups",
"restart": "Reiniciar",
"unmaintained_details": "Fa temps que no es manté aquesta aplicació i la persona que la mantenia ja no ho fa o no té temps per fer-ho. Us convidem a mirar el repositori de l'aplicació per oferir la vostra ajuda",
"issues": "%s problemes",
"issues": "{count} problemes",
"operation_failed_explanation": "Aquesta operació ha fallat! Ens sap molt greu :( Podeu intentar <a href='https://yunohost.org/help'>demanar ajuda</a>. Si us plau doneu *el registre complet* de l'operació a la gent que intenta ajudar-vos. Podeu fer-ho fent clic al botó verd \"Compartir amb Yunopaste\". Quan compartiu els registres, YunoHost intentarà anonimitzar automàticament dades privades com els noms de domini i les IPs.",
"diagnosis_explanation": "La funció de diagnòstic intentarà identificar els errors més comuns en diferents aspectes del servidor per verificar que tot funciona correctament. El diagnòstic s'executa automàticament dues vegades al dia i s'envia un correu electrònic a l'administrador si es troben errors. Tingueu en compte que no tots els tests seran rellevants si no s'utilitzen algunes funcions específiques (com per exemple XMPP) o pot ser que falli si teniu un sistema amb una configuració complexa. En aquests casos, i si sabeu el que feu, podeu ignorar els problemes o avisos corresponents.",
"pending_migrations": "Hi ha algunes migracions pendents esperant per ser executades. Aneu a <a href='#/tools/migrations'>Eines > Migracions</a> per fer-les.",
"log_suboperations": "Sub-operacions",
"logs_suboperations": "Sub-operacions",
"tip_about_user_email": "Els usuaris es creen amb una adreça de correu electrònic associada (i compte de XMPP) amb el format usari@domini.tld. L'administrador i l'usuari poden afegir a posteriori adreces de correu addicionals i reenviament de correus.",
"permission_show_tile_enabled": "Mostrar la «tile» en el portal de l'usuari",
"permission_main": "Permís principal",
"permission_corresponding_url": "URL corresponent",
"app_manage_label_and_tiles": "Gestionar etiquetes i «tiles»",
"app_info_managelabel_desc": "Administrar les etiquetes de permisos en el portal.",
"apply": "Aplicar"
"app_manage_label_and_tiles": "Gestionar etiquetes i «tiles»"
}

View file

@ -2,110 +2,50 @@
"action": "Aktion",
"add": "Hinzufügen",
"administration_password": "Verwaltungspasswort",
"allowed_users": "Zugelassene Benutzer",
"api_not_responding": "Die YunoHost-API antwortet nicht. Vielleicht ist 'yunohost-api' ausgefallen oder wurde neu gestartet?",
"app_access": "Zugriffsrechte",
"app_access_addall_btn": "Zugriff für alle zulassen",
"app_access_addall_desc": "Alle existierenden Benutzer werden Zugriff auf %s haben.",
"app_access_clearall_btn": "Alle Zugriffsrechte löschen",
"app_access_clearall_desc": "Jeder Benutzer wird Zugriff auf %s haben.",
"app_access_removeall_btn": "Alle Zugriffsrechte entfernen",
"app_access_removeall_desc": "Kein Benutzer wird Zugriff auf %s haben.",
"app_access_title": "%s Zugriffsrechte",
"app_debug_no_logs": "Anwendungslogs stehen nicht zur Verfügung",
"app_debug_tab": "Debugging Informationen anzeigen",
"app_info_access_desc": "Gruppen / Benutzer*innen, die auf diese App zugreifen dürfen:",
"app_info_debug_desc": "Debugging Informationen für diese Applikation anzeigen.",
"app_info_default_desc": "Hauptdomain auf diese App (%s) weiterleiten.",
"app_info_default_desc": "Hauptdomain auf diese App ({domain}) weiterleiten.",
"app_info_uninstall_desc": "Diese App löschen.",
"app_install_cancel": "Installation abgebrochen.",
"app_install_custom_no_manifest": "Keine manifest.json Datei",
"app_list": "Appliste",
"app_make_default": "Als Standard setzen",
"application": "Applikation",
"applications": "Applikationen",
"archive_empty": "Leeres Archiv",
"available": "Verfügbar",
"available_apps": "Verfügbare Apps",
"backup": "Datensicherung",
"backup_action": "Datensicherung",
"backup_archive_copy": "Dieses Archiv auf einen anderen Speicher kopieren",
"backup_archive_delete": "Archiv löschen",
"backup_archive_download": "Dieses Archiv herunterladen",
"backup_content": "Inhalt der Datensicherung",
"backup_create": "Sicherung erstellen",
"backup_encryption_warning": "Dieses Passwort nicht vergessen, es wird benötigt, um das Archiv wiederherzustellen",
"backup_new": "Neue Sicherung",
"backup_optional_encryption": "Optionale Verschlüsselung",
"backup_optional_password": "Optionales Passwort",
"backup_type": "Typ",
"backup_warning_desc": "Du solltest deine Daten vorläufig selbst sichern.",
"backup_warning_title": "Das Systemsicherung ist noch nicht implementiert.",
"backups_no": "Keine Datensicherung",
"begin": "Anfangen",
"bit_rate": "Bitrate",
"both": "Beide",
"cancel": "Abbrechen",
"check": "Prüfen",
"check_mx": "MX Eintrag",
"check_stmp": "Zugriff auf Port 25",
"close": "Schließen",
"confirm_access_add": "Zugriffsrechte auf %s allen Benutzer gewähren?",
"confirm_access_clear": "Wirklich alle Zugriffsrechte zu %s löschen?",
"confirm_access_remove_all": "Wirklich alle Berechtigung für %s entfernen?",
"confirm_access_remove_user": "Möchtest du wirklich die Zugriffsrechte auf %s für %s löschen?",
"confirm_app_default": "Möchtest du diese App als Standard einstellen?",
"confirm_change_maindomain": "Möchtest du wirklich die Hauptdomain ändern?",
"confirm_delete": "Möchtest du wirklich %s löschen?",
"confirm_firewall": "Willst du wirklich diesen Port %s? (Port: %s, Protokoll: %s, Verbindung: %s)",
"confirm_delete": "Möchtest du wirklich {name} löschen?",
"confirm_install_custom_app": "WARNUNG! Die Installation von Drittanbieter Apps könnte die Sicherheit und Integrität deines Systems gefährden. Du solltest sie nicht installieren außer du weißt was du tust. Willst du das Risiko eingehen?",
"confirm_install_domain_root": "Du wirst keine weiteren Apps auf %s installieren können. Dennoch fortfahren?",
"confirm_postinstall": "Du bist dabei, den Konfigurationsprozess für die Domain %s starten. Dies wird ein paar Minuten dauern, *die Ausführung nicht unterbrechen*.",
"confirm_restore": "Möchtest du wirklich %s wiederherstellen?",
"confirm_service_action": "Befehl %s für Dienst %s ausführen?",
"confirm_uninstall": "Möchtest du wirklich %s deinstallieren?",
"confirm_update_type": "Möchtest du wirklich alle %s aktualisieren?",
"confirm_upnp_action": "Möchtest du wirklich UPnP %s?",
"confirm_install_domain_root": "Du wirst keine weiteren Apps auf {domain} installieren können. Dennoch fortfahren?",
"confirm_postinstall": "Du bist dabei, den Konfigurationsprozess für die Domain {domain} starten. Dies wird ein paar Minuten dauern, *die Ausführung nicht unterbrechen*.",
"confirm_restore": "Möchtest du wirklich {name} wiederherstellen?",
"confirm_uninstall": "Möchtest du wirklich {name} deinstallieren?",
"connection": "Verbindung",
"copy": "Kopieren",
"count_min": "%s min",
"cpu_load": "CPU Auslastung",
"created_at": "Erstellt am",
"cumulative_usage": "Gesamtverbrauch",
"custom_app_install": "Benutzerdefinierte App installieren",
"custom_app_url_only_github": "Derzeit nur von GitHub aus möglich",
"default": "Vorgabe",
"delete": "Löschen",
"description": "Beschreibung",
"disable": "Deaktivieren",
"disabled": "Deaktiviert",
"disk": "Festplatte",
"domain": "Domain",
"domain_add": "Domain hinzufügen",
"domain_add_dns_doc": "... und ich habe <a href='//yunohost.org/dns'>meine DNS Einstellung richtig hinterlegt</a>.",
"domain_add_dyndns_doc": "... und ich möchte einen Dienst für dynamisches DNS nutzen.",
"domain_add_panel_with_domain": "Ich habe schon eine Domain…",
"domain_add_panel_without_domain": "Ich habe keine Domain…",
"domain_default": "Standarddomain",
"domain_default_desc": "Die Standarddomain ist die Domain, an der sich die Benutzer anmelden.",
"domain_list": "Domainliste",
"domain_name": "Domainname",
"domain_select": "Domain auswählen",
"domains": "Domänen",
"download": "Herunterladen",
"enable": "Aktivieren",
"enabled": "Aktiviert",
"error_modify_something": "Du solltest etwas verändern",
"error_occured": "Es gab einen Fehler, bitte erneut versuchen",
"error_retrieve_feed": "Konnte den Feed nicht abrufen: %s. Du hast eventuell ein Plugin, das deinen Browser davon abhält die Abfrage auszuführen (oder die Website ist offline).",
"error_select_domain": "Bitte Domain eingeben",
"error_server": "Serverfehler",
"everyone_has_access": "Jeder hat Zugriff.",
"filesystem": "Dateisystem",
"firewall": "Firewall",
"free": "Frei",
"fs_type": "Dateisystem",
"gateway": "Netzwerk Gateway: ",
"home": "Home",
"hook_adminjs_group_configuration": "Systemkonfigurationen",
"hook_conf_cron": "Automatisierte Aufgaben",
@ -121,141 +61,69 @@
"hook_data_home_desc": "Die Daten des Benutzers werden gespeichert unter /home/USER",
"hook_data_mail": "E-Mail",
"hook_data_mail_desc": "Roth-E-Mails auf dem Server gespeichert",
"hostname": "Hostname",
"id": "ID",
"inactive": "Inaktiv",
"infos": "Informationen",
"install": "Installieren",
"install_name": "%s installieren",
"install_name": "{id} installieren",
"install_time": "Installiert am",
"installation_complete": "Installation vollständig",
"installed": "Installiert",
"installed_apps": "installierte Apps",
"installing": "Installation läuft",
"interface": "Schnittstelle",
"io": "I/O",
"ipv4": "IPv4",
"ipv6": "IPv6",
"label": "Label",
"label_for_manifestname": "Label für %s",
"loading": "Wird geladen …",
"label_for_manifestname": "Label für {name}",
"local_archives": "Lokale Archive",
"local_ip": "Lokale IP",
"log": "Log",
"logged_in": "Angemeldet",
"logged_out": "Abgemeldet",
"login": "Anmelden",
"logout": "Abmelden",
"mailbox_quota_description": "Zum Beispiel, eine CD verfügt über 700M, eine über 4700M.",
"manage_apps": "Apps verwalten",
"manage_domains": "Domains verwalten",
"manage_users": "Benutzer*innen verwalten",
"memory": "Arbeitsspeicher",
"menu": "Menü",
"mode": "Modus",
"monitoring": "Überwachung",
"monitoring_check_glances": "Überprüfe <a href='#/services/glances'>Glances</a> Dienststatus.",
"monitoring_disabled": "Monitoring ist deaktiviert.",
"mount_point": "Einhängepunkt",
"multi_instance": "Mehrere Instanzen",
"myserver": "meinserver",
"myserver_org": "meinserver.org",
"network": "Netzwerk",
"next": "Weiter",
"no": "Nein",
"no_allowed_users": "Keine berechtigten Benutzer.",
"no_installed_apps": "Keine installierten Apps.",
"no_log": "Kein Log.",
"no_user_to_add": "Es gibt keine weiteren Benutzer, die hinzugefügt werden könnten.",
"non_compatible_api": "API nicht kompatibel",
"open": "Öffnen",
"operations": "Handlungen",
"os": "Betriebssystem",
"password": "Passwort",
"password_confirmation": "Passwortbestätigung",
"password_description": "Das Passwort muss mindestens %s Zeichen enthalten.",
"password_empty": "Das Passwortfeld ist leer",
"password_new": "Neues Passwort",
"passwords_dont_match": "Passwörter stimmen nicht überein",
"passwords_too_short": "Passwort zu kurz",
"path": "Pfad",
"port": "Port",
"ports": "Ports",
"postinstall": "Einrichtung",
"postinstall_domain": "Dies ist die primäre Domain für deinen YunoHost Server und auch die Domain, an der sich die Benutzer*innen anmelden werden. Sie wird für alle Benutzer*innen sichtbar sein, daher wähle die primäre Domain sorgfältig aus.",
"postinstall_intro_1": "Gratuliere! YunoHost wurde erfolgreich installiert.",
"postinstall_intro_2": "Zwei weitere Einstellungen sind notwendig, um den Dienst auf deinem Server zu aktivieren.",
"postinstall_intro_3": "Du kannst mehr Informationen in der <a href='//yunohost.org/postinstall' target='_blank'>Dokumentation</a> finden",
"postinstall_password": "Dieses Passwort wird zur Verwaltung deines Servers benötigt. Wähle es mit Bedacht.",
"previous": "Zurück",
"process": "Prozess",
"protocol": "Protokoll",
"public_ip": "Öffentliche IP: ",
"ram": "Arbeitsspeicher",
"read": "Lesen",
"read_more": "Weiterlesen",
"reception": "Empfang",
"refresh_app_list": "Liste aktualisieren",
"remove_access": "Zugriffsrechte löschen",
"restore": "Wiederherstellen",
"running": "Im Betrieb",
"save": "Speichern",
"select_user": "Benutzer auswählen",
"service_log": "%s Log",
"service_start_on_boot": "Beim Hochfahren starten",
"service_status": "Status: ",
"services": "Dienste",
"services_list": "Dienstübersicht",
"set_default": "Als Standard festlegen",
"size": "Größe",
"sleeping": "Stand-by-Modus",
"start": "Start",
"status": "Status",
"stop": "Anhalten",
"storage_create": "Entfernten Speicher hinzufügen",
"storages_new": "Neuer entfernter Speicher",
"storages_no": "Keine Speicher.",
"swap": "Auslagerungsspeicher",
"system": "System",
"system_apps": "Apps",
"system_apps_nothing": "Alle Applikationen sind auf dem neuesten Stand!",
"system_delayed_upgrade": "Zurückgestellte Aktualisierung",
"system_delayed_upgrade_warning": "<b>%s</b> wird automatisch innerhalb der nächsten Stunde aktualisiert.",
"system_packages": "Systempakete",
"system_packages_nothing": "Alle Systempakete sind auf dem neuesten Stand!",
"system_update": "System aktualisieren",
"system_upgrade": "Systemaktualisierung",
"system_upgrade_btn": "Aktualisieren",
"tcp": "TCP",
"time_since_update": "Zeit seit letzter Aktualisierung: ",
"tools": "Werkzeuge",
"tools_adminpw": "Administratorenpasswort ändern",
"tools_adminpw_confirm_placeholder": "Neues Passwort bestätigen",
"tools_adminpw_current": "Derzeitiges Passwort",
"tools_adminpw_current_placeholder": "Derzeitiges Passwort eingeben",
"tools_adminpw_new_placeholder": "Neues Passwort eingeben",
"tools_download_ca": "SSL Zertifizierungsstelle (CA) herunterladen",
"tools_download_ca_desc": "Hier klicken, um deine SSL Zertifizierungstelle (CA) herunterzuladen",
"tools_security_feed": "Sicherheitsbenachrichtigungen",
"tools_security_feed_no_items": "Keine Sicherheitsbenachrichtigungen",
"tools_security_feed_subscribe_rss": "Sicherheitsbenachrichtigungen mittels RSS abonnieren",
"tools_security_feed_view_items": "Alle Sicherheitsbenachrichtigungen anzeigen",
"total": "Gesamt",
"transmission": "Übertragung",
"udp": "UDP",
"unauthorized": "Unauthorisiert",
"uninstall": "Deinstallieren",
"unknown_action": "Unbekannte Aktion: %s",
"unknown_argument": "Unbekanntes Argument: %s",
"upload": "Hochladen",
"upload_archive": "Archiv hochladen",
"upnp": "UPnP",
"upnp_disabled": "UPnP ist deaktiviert.",
"upnp_enabled": "UPnP ist aktiviert.",
"uptime": "Laufzeit",
"url": "URL",
"usage": "Auslastung",
"used": "Benutzt",
"user_email": "E-Mail",
"user_emailaliases": "E-Mail Aliase",
"user_emailforward": "E-Mail Weiterleitung",
@ -263,40 +131,27 @@
"user_interface_link": "Benutzer*innenoberfläche",
"user_mailbox_quota": "Mailbox Kontingent",
"user_new_forward": "weiterleitung@externedomain.org",
"user_new_mail": "newmail@mydomain.org",
"user_username": "Benutzer*innenname",
"user_username_edit": "Account von %s bearbeiten",
"user_username_edit": "Account von {name} bearbeiten",
"users": "Benutzer*in",
"users_list": "Benutzerliste",
"users_new": "Neue_r Benutzer*in",
"users_no": "Keine Benutzer*in.",
"versions": "Versionen",
"view_user_profile": "Das Profil von %s ansehen",
"warning_first_user": "Bitte zuerst einen <a href='#/users/create' class='alert-link'>Benutzer*in anlegen</a>.",
"write": "Schreiben",
"wrong_password": "Falsches Passwort",
"yes": "Ja",
"app_state_validated": "Bestätigt",
"app_state_inprogress": "funktioniert noch nicht",
"app_state": "Applikationsstatus: ",
"app_repository": "Applikationsherkunft ",
"app_state_notworking": "nicht funktionierend",
"app_state_working": "funktioniert",
"backup_experimental_warning": "Bitte beachte, dass das Backup-Feature noch experimentell ist und daher noch instabil sein könnte.",
"diagnosis": "Diagnose",
"diagnosis_hide_private": "Zeige der Diagnose ohne persönliche Daten an",
"diagnosis_view_private": "Zeige der Diagnose mit persönlichen Daten an",
"diagnosis_with_private": "Diagnose mit persönlichen Daten",
"dns": "DNS",
"domain_default_longdesc": "Das ist Ihre Standard-Domain.",
"domain_delete_longdesc": "Domain löschen",
"domain_dns_config": "DNS Konfiguration",
"domain_dns_longdesc": "DNS Konfiguration anzeigen",
"domain_visit": "Besuchen",
"domain_visit_url": "Besuche %s",
"error_server_unexpected": "Unerwarteter Serverfehler (%s)",
"footer_version": "Angetrieben von <a href='https://yunohost.org'>YunoHost</a> %s (%s).",
"form_input_example": "Beispiel: %s",
"domain_visit_url": "Besuche {url}",
"error_server_unexpected": "Unerwarteter Serverfehler",
"footer_version": "Angetrieben von <a href='https://yunohost.org'>YunoHost</a> {version} ({repo}).",
"form_input_example": "Beispiel: {example}",
"mailbox_quota_placeholder": "Leer lassen oder 0 zum Deaktivieren eintragen.",
"user_mailbox_use": "von der Mailbox verwendeter Speicherplatz",
"certificate_alert_not_valid": "KRITISCH : Das aktuelle Zertifikat ist nicht gültig ! HTTPS wird nicht funktionieren !",
@ -307,7 +162,6 @@
"certificate_alert_great": "Großartig ! Du verwendest ein gültiges Let's Encrypt Zertifikat !",
"certificate_alert_unknown": "Status unbekannt",
"certificate_manage": "SSL-Zertifikat verwalten",
"certificate_old_letsencrypt_app_conflict": "Die 'letsencrypt' Anwendung ist momentan installiert und verursacht einen Konflikt mit diesem Feature. Bitte deinstalliere die Anwendung zuerst, um die neue Zertifikatsverwaltungskonsole nutzen zu können.",
"ssl_certificate": "SSL-Zertifikat",
"confirm_cert_install_LE": "Willst du das Let's Encrypt Zertifikat für diese Domain installieren ?",
"confirm_cert_regen_selfsigned": "Bist du sicher, dass du das selbstsignierte Zertifikat für diese Domain erneuern willst ?",
@ -326,18 +180,14 @@
"revert_to_selfsigned_cert_message": "Wenn du willst, kannst du erneut ein selbstsigniertes Zertifikat installieren. (Nicht empfohlen)",
"revert_to_selfsigned_cert": "In ein selbstsigniertes Zertifikat umwandeln",
"confirm_cert_revert_to_selfsigned": "Bist du sicher, dass du dieser Domain erneut ein selbstsigniertes Zertifikat zuweisen willst ?",
"confirm_service_start": "Möchtest du wirklich %s starten?",
"confirm_service_stop": "Möchtest du wirklich %s anhalten?",
"confirm_service_enable": "Möchtest du wirklich %s aktivieren?",
"confirm_service_disable": "Möchtest du wirklich %s deaktivieren?",
"confirm_service_start": "Möchtest du wirklich {name} starten?",
"confirm_service_stop": "Möchtest du wirklich {name} anhalten?",
"confirm_update_apps": "Möchtest du wirklich alle Anwendungen aktualisieren?",
"confirm_update_packages": "Möchtest du wirklich alle Pakete aktualisieren?",
"confirm_upnp_enable": "Möchtest du wirklich UPnP aktivieren?",
"confirm_upnp_disable": "Möchtest du wirklich UPnP deaktivieren?",
"confirm_firewall_open": "Möchtest du wirklich Port %s1 öffnen? (Protokoll: %s2, Verbindung: %s3)",
"confirm_firewall_close": "Möchtest du wirklich Port %s1 schließen? (Protokoll: %s2, Verbindung: %s3)",
"remove": "Entfernen",
"confirm_update_specific_app": "Möchtest du wirklich %s aktualisieren?",
"confirm_firewall_open": "Möchtest du wirklich Port {port}1 öffnen? (Protokoll: {protocol}2, Verbindung: {connection}3)",
"confirm_firewall_close": "Möchtest du wirklich Port {port}1 schließen? (Protokoll: {protocol}2, Verbindung: {connection}3)",
"confirm_update_specific_app": "Möchtest du wirklich {app} aktualisieren?",
"confirm_reboot_action_reboot": "Möchtest du wirklich den Server neustarten?",
"confirm_reboot_action_shutdown": "Möchtest du wirklich den Server herunterfahren?",
"domain_dns_conf_is_just_a_recommendation": "Diese Seite zeigt dir die *empfohlene* Konfiguration. Sie konfiguriert *nicht* den DNS für dich. Es liegt in deiner Verantwortung, deine Zone bei deinem Registrar entsprechend dieser Empfehlung zu konfigurieren.",
@ -353,87 +203,54 @@
"tools_shutdown_done": "Fahre herunter...",
"tools_shuttingdown": "Dein Server wird heruntergefahren. Solange dein Server ausgeschaltet ist, kannst du die Verwaltungsoberfläche nicht benutzen.",
"tools_shutdown_reboot": "Herunterfahren/Neustarten",
"appslists": "Applikationslisten",
"appslists_no_lists": "Keine Applikationslisten",
"appslists_custom": "Eigene Applikationslisten",
"appslists_manage": "Verwalte Applikationslisten",
"appslists_confirm_remove": "Möchtest du wirklich diese Applikationsliste entfernen?",
"appslists_info_refresh_desc": "Aktualisiere die Paketinformationen für diese Liste.",
"appslists_info_remove_desc": "Applikationen aus dieser Liste werden nicht mehr verfügbar sein.",
"appslists_last_update": "Letzte Aktualisierung",
"appslists_unknown_list": "Die Liste %s ist unbekannt",
"appslists_community_list": "Applikationsliste der Community",
"name": "Name",
"install_community_appslists_warning": "Nimm zur Kenntnis, dass diese Applikationen <strong>nicht</strong> offiziell sind und nicht von YunoHost gepflegt werden.<br /> Diese Applikationen sind auf eigenes Risiko zu installieren und können dein System demolieren.",
"app_change_label": "Label ändern",
"app_state_working_explanation": "Der/die Verwalter*in dieser App deklariert sie als 'funktionierend'. Das heißt sie sollte funktionieren (vgl. App Level) aber ist nicht zwangsläufig begutachtet, sie kann Probleme enthalten oder ist nicht vollkommen integriert in YunoHost.",
"app_state_high-quality": "hohe Qualität",
"app_state_highquality": "hohe Qualität",
"app_state_notworking_explanation": "Der/die Verwalter*in dieser App deklariert sie als 'nicht funktionierend'. SIE WIRD IHR SYSTEM ZERSTÖREN!",
"app_state_inprogress_explanation": "Der/die Verwalter*in dieser App deklariert sie als nicht bereit für den produktiven Einsatz. SEIEN SIE VORSICHTIG!",
"app_no_actions": "Diese Anwendung hat keine Aktionen",
"app_level": "App Level",
"app_info_changelabel_desc": "Änder App Bezeichnung im Portal.",
"app_change_url": "URL ändern",
"all_apps": "Alle Apps",
"advanced": "Weiterführend",
"active": "Aktiv",
"app_info_changeurl_desc": "Ändern Sie die Zugriffs URL dieser Anwendung (Domain und/oder Pfad).",
"app_state_high-quality_explanation": "Diese App ist gut in YunoHost integriert. Sie wurde (und wird!) vom YunoHost-App-Team begutachtet. Es kann erwartet werden, dass sie sicher ist und langfristig gewartet wird.",
"app_state_highquality_explanation": "Diese App ist gut in YunoHost integriert. Sie wurde (und wird!) vom YunoHost-App-Team begutachtet. Es kann erwartet werden, dass sie sicher ist und langfristig gewartet wird.",
"app_info_change_url_disabled_tooltip": "Dieses Feature wurde noch nicht in der App implementiert",
"confirm_app_change_url": "Sind Sie sicher, dass sie die App-Zugangs-URL ändern möchten?",
"current_maintainer_title": "Aktueller Betreuer dieses Pakets",
"confirm_update_system": "Bist du sicher, dass du alle Systempakete aktualisieren möchtest?",
"confirm_migrations_skip": "Das Überspringen von Migrationen wird nicht empfohlen. Bist du sicher, dass du das tun willst?",
"confirm_install_app_danger": "ACHTUNG! Diese Applikation ist noch experimentell (wenn nicht sogar nicht funktionsfähig) und es ist wahrscheinlich, dass sie Dein System zerstört! Du solltest sie besser NICHT installieren, es sei denn, du weißt, was du tust. Bist du bereit, dieses Risiko einzugehen?",
"confirm_install_app_warning": "Achtung: Diese Anwendung kann funktionieren, ist aber nicht gut in YunoHost integriert. Einige Funktionen wie Single Sign-On und Backup/Restore sind möglicherweise nicht verfügbar.",
"confirm_install_app_inprogress": "ACHTUNG! Diese Applikation ist noch experimentell (wenn nicht sogar nicht funktionsfähig) und es ist wahrscheinlich, dass sie Dein System zerstört! Du solltest sie besser NICHT installieren, es sei denn, du weißt, was du tust. Bist du bereit, dieses Risiko einzugehen?",
"confirm_install_app_lowquality": "Achtung: Diese Anwendung kann funktionieren, ist aber nicht gut in YunoHost integriert. Einige Funktionen wie Single Sign-On und Backup/Restore sind möglicherweise nicht verfügbar.",
"good_practices_about_admin_password": "Du bist nun dabei, ein neues Admin-Passwort zu definieren. Das Passwort sollte mindestens 8 Zeichen lang sein - es ist jedoch empfehlenswert, ein längeres Passwort (z.B. eine Passphrase) und/oder verschiedene Arten von Zeichen (Groß- und Kleinschreibung, Ziffern und Sonderzeichen) zu verwenden.",
"from_to": "von %s nach %s",
"from_to": "von {0} nach {1}",
"experimental_warning": "Achtung: Diese Funktion ist experimentell und gilt nicht als stabil, du solltest sie nicht verwenden, außer du weißt, was du tust.",
"error_connection_interrupted": "Der Server hat die Verbindung geschlossen, anstatt sie zu beantworten. Wurde nginx oder die yunohost-api aus irgendeinem Grund neu gestartet oder gestoppt? (Fehlercode/Meldung: %s)",
"error_connection_interrupted": "Der Server hat die Verbindung geschlossen, anstatt sie zu beantworten. Wurde nginx oder die yunohost-api aus irgendeinem Grund neu gestartet oder gestoppt?",
"hook_conf_ynh_currenthost": "Aktuelle Haupt-Domain",
"good_practices_about_user_password": "Du bist nun dabei, ein neues Benutzerpasswort zu definieren. Das Passwort sollte mindestens 8 Zeichen lang sein - es ist jedoch empfehlenswert, ein längeres Passwort (z.B. eine Passphrase) und/oder verschiedene Arten von Zeichen (Groß- und Kleinschreibung, Ziffern und Sonderzeichen) zu verwenden.",
"maintained": "betreut",
"license": "Lizenz",
"level": "Level",
"internal_exception": "<strong>Yunohost ist auf einen internen Fehler gestoßen:/</strong><br><em>Das tut uns wirklich leid.<br>Du solltest <a href=\"https://forum.yunohost.org/\">im Forum</a> nach Hilfe fragen oder <a href=\"https://chat.yunohost.org/\">im Chat</a>, um die Situation zu beheben, oder berichte den Fehler auf <a href=\"https://github.com/YunoHost/issues\">dem Bugtracker</a>.</em><br>Die folgenden Informationen können für die Person, die dir hilft, nützlich sein:<h3>Action</h3><pre>%s%s</pre><h3>Traceback</h3><pre>%s</pre>",
"maintained_details": "Diese App wurde von ihrem/ihrer Betreuer*in in den letzten Monaten betreut.",
"only_highquality_apps": "Nur hochqualitative Apps",
"only_decent_quality_apps": "Nur qualitativ hochwertige Apps",
"orphaned": "Nicht betreut",
"orphaned_details": "Diese App wird nicht mehr gepflegt. Sie kann noch funktionieren, wird aber kein Upgrade mehr erhalten bis jemand Freiwilliges die weitere Pflege übernimmt. Zögere nicht zu kommen und sie wiederzubeleben!",
"request_adoption": "ausstehende Annahme",
"request_adoption_details": "Der/die aktuelle Betreuer*in möchte die Pflege dieser App einstellen. Zögere nicht, dich selbst als neue_n Betreuer*in vorzuschlagen!",
"request_help": "Hilfe benötigt",
"request_help_details": "Der/die aktuelle Betreuer*in möchte Hilfe bei der Pflege dieser App. Zögere nicht, daran mitzuwirken!",
"logs_system": "Kernel-Logs und andere Ereignisse auf niederer Ebene",
"select_none": "Wähle keine",
"skip": "Überspringe",
"logs_share_with_yunopaste": "Teile mit YunoPaste",
"migrations_pending": "Ausstehende Migrationen",
"logs_operation": "Operationen, die auf dem System mit YunoHost durchgeführt wurden",
"search_for_apps": "Suche nach Apps...",
"logs_history": "Historie der Befehlsausführung auf dem System",
"purge_user_data_warning": "Die Löschung der Benutzer*indaten ist nicht umkehrbar. Sei Dir sicher, was du tust!",
"logs_error": "Fehler",
"started_at": "Gestartet um:",
"logs_package": "Historie des Debian-Paket-Managements",
"logs_started_at": "Beginn",
"only_working_apps": "Nur funktionierende Apps",
"logs_no_logs_registered": "Kein Log registriert für diese Kategorie",
"meltdown": "Du bist anfällig für die kritische Sicherheitslücke <a target=\"_blank\" href=\"https://meltdownattack.com/\">Meltdown</a>. Um das zu beheben, musst du <a href=\"#/update\">dein System aktualisieren</a> und es dann <a href=\"#/tools/reboot\">neu starten</a>, um den neuen Linux-Kernel zu laden.",
"purge_user_data_checkbox": "Die Daten von %s löschen? (Dadurch wird der Inhalt des Nutzer- und des E-Mail-Verzeichnisses gelöscht.)",
"purge_user_data_checkbox": "Die Daten von {name} löschen? (Dadurch wird der Inhalt des Nutzer- und des E-Mail-Verzeichnisses gelöscht.)",
"unmaintained": "Unbetreut",
"logs_path": "Pfad",
"logs_service": "Service-Logs",
"logs_end_with_error": "Dieses Log endet mit dem Fehler:",
"migrations_no_done": "Keine vorherigen Migrationen",
"logs_access": "Liste der Zugriffe und Sperrungen",
"migrations_no_pending": "Keine ausstehenden Migrationen",
"logs_context": "Kontext",
"migrations": "Migrationen",
"service_description": "Beschreibung:",
"logs": "Logs",
"path_url": "Pfad",
"run": "Starten",
"version": "Version",
"logs_app": "Apps-Logs",
@ -443,15 +260,17 @@
"migrations_done": "Vorherige Migrationen",
"groups_and_permissions_manage": "Verwalten von Gruppen und Berechtigungen",
"unignore": "Unignorieren",
"warnings": "%s Warnungen",
"warnings": "{count} Warnungen",
"words": {
"default": "Vorgabe"
},
"group": "Gruppe",
"details": "Details",
"errors": "%s Fehler",
"everything_good": "Alles gut!",
"ignore": "Ignorieren",
"configuration": "Konfiguration",
"group_explain_all_users": "Dies ist eine spezielle Gruppe, die alle Benutzer*innenkonten auf dem Server enthält",
"ignored": "%s wird ignoriert",
"ignored": "{count} wird ignoriert",
"last_ran": "Das letzte Mal lief es:",
"group_name": "Gruppenname",
"group_all_users": "Alle Benutzer*innen",
@ -468,22 +287,21 @@
"group_new": "Neue Gruppe",
"group_explain_visitors": "Dies ist eine spezielle Gruppe, die anonyme Besucher*innen repräsentiert",
"rerun_diagnosis": "Diagnose wiederholen",
"app_state_low_quality_explanation": "Diese App kann bereits funktionieren, enthält aber eventuell noch Fehler und/oder ist noch nicht vollständig integriert in YunoHost und/oder befolgt nicht die empfohlene Praxis.",
"app_state_lowquality_explanation": "Diese App kann bereits funktionieren, enthält aber eventuell noch Fehler und/oder ist noch nicht vollständig integriert in YunoHost und/oder befolgt nicht die empfohlene Praxis.",
"others": "Anderes",
"catalog": "Katalog",
"app_state_low_quality": "geringe Qualität",
"app_state_lowquality": "geringe Qualität",
"all": "Alle",
"confirm_service_restart": "Bist du sicher, dass du %s neustarten möchtest?",
"confirm_service_restart": "Bist du sicher, dass du {name} neustarten möchtest?",
"run_first_diagnosis": "Initiale Diagnose läuft",
"diagnosis_first_run": "Die Diagnosefunktion versucht, häufige Probleme in den verschiedenen Bereichen Ihres Servers zu identifizieren, um sicherzustellen, dass alles reibungslos läuft. Bitte geraten Sie nicht in Panik, wenn Sie direkt nach dem Einrichten Ihres Servers einen Haufen Fehler sehen: es soll Ihnen genau dabei helfen, Probleme zu identifizieren und Sie zur Behebung dieser Probleme anleiten. Die Diagnose läuft auch automatisch zweimal täglich, und wenn Probleme gefunden werden, wird eine E-Mail an den Administrator geschickt.",
"unmaintained_details": "Diese Anwendung wurde seit einiger Zeit nicht gewartet und der frühere Wart hat die Anwendung aufgegeben oder hat keine Zeit mehr für die Wartung. Du bist herzlich eingeladen dir die Quellen und Unterlagen anzusehen und Hilfe zu leisten",
"group_explain_visitors_needed_for_external_client": "Sei vorsichtig und beachte, dass du manche Anwendungen für externe Besucher*innen freigeben musst, falls du beabsichtigst, diese mit externen Clients aufzurufen. Zum Beispiel trifft das auf Nextcloud zu, wenn du eine Synchronisation auf dem Smartphone oder Desktop PC haben möchtest.",
"groups": "Gruppen",
"issues": "%s Probleme",
"issues": "{count} Probleme",
"restart": "Neustart",
"operation_failed_explanation": "Die Operation ist fehlgeschlagen! Das tut uns leid :( Sie können Sich <a href='https://yunohost.org/help'>hier Hilfe holen</a>. Bitte stellen Sie *die ganzen Logs* der Operation bereit, damit Ihnen besser geholfen werden kann. Dies tun Sie, indem Sie auf den grünen 'mit Yunopaste teilen' Knopf drücken. Wenn Sie die Logs teilen, wird Yunohost automatisch versuchen Ihre privaten Daten wie Domainnamen und IP's zu anonymisieren.",
"diagnosis_explanation": "Die Diagnose Funktion wird versuchen, gängige Probleme in verschiedenen Teilen deines Servers zu finden, damit alles reibungslos läuft. Die Diagnose wird auch automatisch zweimal täglich ausgeführt, falls Fehler gefunden werden, bekommt der Administrator ein E-Mail. Beachte, dass einige tests nicht relevant sind, wenn du einzelne Features (zum Beispiel XMPP) nicht benutzt oder du ein komplexes Setup hast. In diesem Fall und wenn du weisst was du tust ist es in Ordnung die dazugehoerigen Warnungen und Hinweise zu ignorieren.",
"pending_migrations": "Es gibt einige ausstehende Migrationen, die darauf warten, ausgeführt zu werden. Bitte gehen Sie auf <a href='#/tools/migrations'>Werkzeuge > Migrationen</a> um diese auszuführen.",
"tip_about_user_email": "Benutzer*innen werden mit einer verknüpften eMail-Adresse (und XMPP Account) erstellt im Format username@domain.tld. Zusätzliche eMail-Aliasse and eMail-Weiterleitungen können später durch den/die Admin und User*in hinzugefügt werden.",
"log_suboperations": "Unter-Operationen"
"logs_suboperations": "Unter-Operationen"
}

View file

@ -0,0 +1,38 @@
{
"add": "Προσθήκη",
"administration_password": "Κωδικός Διαχείρισης",
"confirm_delete": "Είστε σίγουροι ότι θέλετε να διαγράψετε το {name} ;",
"delete": "Διαγραφή",
"description": "Περιγραφή",
"disable": "Απενεργοποίηση",
"domain_name": "Όνομα τομέα",
"domains": "Τομείς",
"enable": "Ενεργοποίηση",
"error_modify_something": "Θα πρέπει να τροποποιήσετε κάτι",
"id": "ID",
"infos": "Πληροφορίες",
"installation_complete": "Η εγκατάσταση ολοκληρώθηκε",
"ipv4": "IPv4",
"ipv6": "IPv6",
"login": "Σύνδεση",
"logout": "Αποσύνδεση",
"myserver": "myserver",
"operations": "Δραστηριότητες",
"password": "Κωδικός πρόσβασης",
"password_confirmation": "Επιβεβαίωση κωδικού πρόσβασης",
"save": "Αποθήκευση",
"set_default": "Ορισμός προεπιλογής",
"start": "Εκκίνηση",
"status": "Κατάσταση",
"stop": "Διακοπή",
"tcp": "TCP",
"udp": "UDP",
"unauthorized": "Unauthorized",
"upnp": "UPnP",
"url": "Διεύθυνση URL",
"words": {
"default": "Προεπιλογή"
},
"wrong_password": "Λανθασμένος κωδικός πρόσβασης",
"ok": "Εντάξει"
}

View file

@ -1,74 +1,99 @@
{
"action": "Action",
"active": "Active",
"add": "Add",
"advanced": "Advanced",
"address": {
"domain_description": {
"domain": "Choose a domain.",
"email": "Choose a domain for your email."
},
"local_part_description": {
"domain": "Choose a subdomain.",
"email": "Choose a local part for your email."
}
},
"administration_password": "Administration password",
"all": "All",
"api_error": {
"help": "You should look for help on <a href=\"https://forum.yunohost.org/\">the forum</a> or <a href=\"https://chat.yunohost.org/\">the chat</a> to fix the situation, or report the bug on <a href=\"https://github.com/YunoHost/issues\">the bugtracker</a>.",
"info": "The following information might be useful for the person helping you:",
"sorry": "Really sorry about that."
},
"api_errors_titles": {
"APIError": "Yunohost encountered an unexpected error",
"APIBadRequestError": "Yunohost encountered an error",
"APIInternalError": "Yunohost encountered an internal error",
"APINotRespondingError": "Yunohost API is not responding",
"APIConnexionError": "Yunohost encountered an connexion error"
},
"all_apps": "All apps",
"apply": "Apply",
"api_not_responding": "The YunoHost API is not responding. Maybe 'yunohost-api' is down or got restarted?",
"app_change_url": "Change URL",
"api_waiting": "Waiting for the server's response...",
"app_actions": "Actions",
"app_actions_label": "Perform actions",
"app_choose_category": "Choose a category",
"app_config_panel": "Config panel",
"app_config_panel_label": "Configure this app",
"app_config_panel_no_panel": "This application doesn't have any configuration available",
"app_info_access_desc": "Groups / users currently allowed to access this app:",
"app_info_managelabel_desc": "Manage permissions labels in the portal.",
"app_info_default_desc": "Redirect domain root to this application (%s).",
"app_info_default_desc": "Redirect domain root to this application ({domain}).",
"app_info_changeurl_desc": "Change the access URL of this application (domain and/or path).",
"app_info_change_url_disabled_tooltip": "This feature hasn't been implemented in this app yet",
"app_info_uninstall_desc": "Remove this application.",
"app_install_cancel": "Installation cancelled.",
"app_install_custom_no_manifest": "No manifest.json file",
"app_manage_label_and_tiles": "Manage label and tiles",
"app_make_default": "Make default",
"app_no_actions": "This application doesn't have any actions",
"app_show_categories": "Show categories",
"app_state_inprogress": "not yet working",
"app_state_inprogress_explanation": "This maintainer of this app declared that this application is not ready yet for production use. BE CAREFUL!",
"app_state_notworking": "not working",
"app_state_notworking_explanation": "This maintainer of this app declared it as 'not working'. IT WILL BREAK YOUR SYSTEM!",
"app_state_low_quality": "low quality",
"app_state_low_quality_explanation": "This app may be functional, but may still contain issues, or is not fully integrated with YunoHost, or it does not respect the good practices.",
"app_state_high-quality": "high quality",
"app_state_high-quality_explanation": "This app is well-integrated with YunoHost. It has been (and is!) peer-reviewed by the YunoHost app team. It can be expected to be safe and maintained on the long-term.",
"app_state_lowquality": "low quality",
"app_state_lowquality_explanation": "This app may be functional, but may still contain issues, or is not fully integrated with YunoHost, or it does not respect the good practices.",
"app_state_highquality": "high quality",
"app_state_highquality_explanation": "This app is well-integrated with YunoHost. It has been (and is!) peer-reviewed by the YunoHost app team. It can be expected to be safe and maintained on the long-term.",
"app_state_working": "working",
"app_state_working_explanation": "The maintainer of this app declared it as 'working'. It means that it should be functional (c.f. application level) but is not necessarily peer-reviewed, it may still contain issues or is not fully integrated with YunoHost.",
"applications": "Applications",
"archive_empty": "Empty archive",
"backup": "Backup",
"backup_action": "Backup",
"backup_archive_delete": "Delete this archive",
"backup_content": "Backup content",
"backup_create": "Create a backup",
"backup_encryption_warning": "Don't forget this password, you'll need it if you want restore the archive",
"backup_new": "New backup",
"backup_optional_encryption": "Optional encryption",
"backup_optional_password": "Optional password",
"backups_no": "No backup",
"begin": "Begin",
"both": "Both",
"cancel": "Cancel",
"catalog": "Catalog",
"check": "Check",
"close": "Close",
"code": "Code",
"common": {
"firstname": "First name",
"lastname": "Last name"
},
"configuration": "Configuration",
"confirm_app_change_url": "Are you sure you want to change the app access URL?",
"confirm_app_default": "Are you sure you want to make this app default?",
"confirm_change_maindomain": "Are you sure you want to change the main domain?",
"confirm_delete": "Are you sure you want to delete %s?",
"confirm_firewall_open": "Are you sure you want to open port %s? (protocol: %s, connection: %s)",
"confirm_firewall_close": "Are you sure you want to close port %s? (protocol: %s, connection: %s)",
"confirm_delete": "Are you sure you want to delete {name}?",
"confirm_firewall_open": "Are you sure you want to open port {port} (protocol: {protocol}, connection: {connection})",
"confirm_firewall_close": "Are you sure you want to close port {port} (protocol: {protocol}, connection: {connection})",
"confirm_install_custom_app": "WARNING! Installing 3rd party applications may compromise the integrity and security of your system. You should probably NOT install it unless you know what you are doing. Are you willing to take that risk?",
"confirm_install_domain_root": "You will not be able to install any other app on %s. Continue?",
"confirm_install_app_warning": "Warning: this application may work but is not well-integrated in YunoHost. Some features such as single sign-on and backup/restore might not be available.",
"confirm_install_app_danger": "WARNING! This application is still experimental (if not explicitly not working) and it is likely to break your system! You should probably NOT install it unless you know what you are doing. Are you willing to take that risk?",
"confirm_install_domain_root": "Are you sure you want to install this application on '/'? You will not be able to install any other app on {domain}",
"confirm_app_install": "Are you sure you want to install this application?",
"confirm_install_app_lowquality": "Warning: this application may work but is not well-integrated in YunoHost. Some features such as single sign-on and backup/restore might not be available.",
"confirm_install_app_inprogress": "WARNING! This application is still experimental (if not explicitly not working) and it is likely to break your system! You should probably NOT install it unless you know what you are doing. Are you willing to take that risk?",
"confirm_migrations_skip": "Skipping migrations is not recommended. Are you sure you want to do that?",
"confirm_postinstall": "You are about to launch the post-installation process on the domain %s. It may take a few minutes, *do not interrupt the operation*.",
"confirm_restore": "Are you sure you want to restore %s?",
"confirm_service_restart": "Are you sure you want to restart %s?",
"confirm_service_start": "Are you sure you want to start %s?",
"confirm_service_stop": "Are you sure you want to stop %s?",
"confirm_uninstall": "Are you sure you want to uninstall %s?",
"confirm_postinstall": "You are about to launch the post-installation process on the domain {domain}. It may take a few minutes, *do not interrupt the operation*.",
"confirm_restore": "Are you sure you want to restore {name}?",
"confirm_service_restart": "Are you sure you want to restart {name}?",
"confirm_service_start": "Are you sure you want to start {name}?",
"confirm_service_stop": "Are you sure you want to stop {name}?",
"confirm_uninstall": "Are you sure you want to uninstall {name}?",
"confirm_update_apps": "Are you sure you want to update all applications?",
"confirm_update_system": "Are you sure you want to update all system packages?",
"confirm_update_specific_app": "Are you sure you want to update %s?",
"confirm_update_specific_app": "Are you sure you want to update {app}?",
"confirm_upnp_enable": "Are you sure you want to enable UPnP?",
"confirm_upnp_disable": "Are you sure you want to disable UPnP?",
"confirm_reboot_action_reboot": "Are you sure you want to reboot your server?",
@ -77,7 +102,8 @@
"created_at": "Created at",
"custom_app_install": "Install custom app",
"custom_app_url_only_github": "Currently only from GitHub",
"default": "Default",
"day_validity": " Expired | 1 day | {count} days",
"dead": "Inactive",
"delete": "Delete",
"description": "Description",
"details": "Details",
@ -90,41 +116,65 @@
"disable": "Disable",
"disabled": "Disabled",
"dns": "DNS",
"domain": "Domain",
"domain_add": "Add domain",
"domain_add_dns_doc": "… and I have <a href='//yunohost.org/dns'>set my DNS correctly</a>.",
"domain_add_dyndns_doc": "… and I want a dynamic DNS service.",
"domain_add_dyndns_forbidden": "You have already subscribed to a DynDNS domain, you can ask to remove your current DynDNS domain on the forum <a href='//forum.yunohost.org/t/nohost-domain-recovery-suppression-de-domaine-en-nohost-me-noho-st-et-ynh-fr/442'>in the dedicated thread</a>.",
"domain_add_panel_with_domain": "I already have a domain name…",
"domain_add_panel_without_domain": "I don't have a domain name…",
"domain_default_desc": "The default domain is the connection domain where users log in.",
"domain_default_longdesc": "This is your default domain.",
"domain_delete_longdesc": "Delete this domain",
"domain_delete_forbidden_desc": "You cannot remove '{domain}' since it's the default domain, you need to choose another domain (or <a href='#/domains/add'>add a new one</a>) and set it as the default domain to be able to remove this one.",
"domain_dns_config": "DNS configuration",
"domain_dns_longdesc": "View DNS configuration",
"domain_name": "Domain name",
"domain_visit": "Visit",
"domain_visit_url": "Visit %s",
"domain_visit_url": "Visit {url}",
"domains": "Domains",
"download": "Download",
"enable": "Enable",
"enabled": "Enabled",
"error": "Error",
"error_modify_something": "You should modify something",
"error_retrieve_feed": "Could not retrieve feed: %s. You might have a plugin prevent your browser from performing this request (or the website is down).",
"error_select_domain": "You should indicate a domain",
"error_server_unexpected": "Unexpected server error (%s)",
"error_connection_interrupted": "The server closed the connection instead of answering it. Has nginx or the yunohost-api been restarted or stopped for some reason? (Error code/message: %s)",
"error_server_unexpected": "Unexpected server error",
"error_connection_interrupted": "The server closed the connection instead of answering it. Has nginx or the yunohost-api been restarted or stopped for some reason?",
"everything_good": "Everything good!",
"experimental": "Experimental",
"experimental_warning": "Warning: this feature is experimental and not consider stable, you shouldn't be using it except if you know what you are doing.",
"firewall": "Firewall",
"footer_version": "Powered by <a href='https://yunohost.org'>YunoHost</a> %s (%s).",
"form_input_example": "Example: %s",
"from_to": "from %s to %s",
"footer_version": "Powered by <a href='https://yunohost.org'>YunoHost</a> {version} ({repo}).",
"footer": {
"documentation": "Documentation",
"help": "Need help?",
"donate": "Donate"
},
"form_errors": {
"alpha": "Value must be alphabetical characters only.",
"alphalownum_": "Value must be lower-case alphanumeric and underscore characters only.",
"between": "Value must be between {min} and {max}.",
"domain": "Invalid domain name: Must be lower-case alphanumeric, dot and dash characters only",
"dynDomain": "Invalid domain name: Must be lower-case alphanumeric and dash characters only",
"email": "Invalid email: must be alphanumeric and <code>_.-</code> characters only (e.g. someone@example.com, s0me-1@example.com)",
"emailForward": "Invalid email forward: must be alphanumeric and <code>_.-+</code> characters only (e.g. someone+tag@example.com, s0me-1+tag@example.com)",
"githubLink": "Url must be a valid Github link to a repository",
"name": "Names may not includes special characters except <code> ,.'-</code>",
"minValue": "Value must be a number equal or greater than {min}.",
"notInUsers": "The user '{value}' already exists.",
"number": "Value must be a number.",
"passwordLenght": "Password must be at least 8 characters long.",
"passwordMatch": "Passwords don't match.",
"required": "Field is required."
},
"form_input_example": "Example: {example}",
"from_to": "from {0} to {1}",
"good_practices_about_admin_password": "You are now about to define a new admin password. The password should be at least 8 characters - though it is good practice to use longer password (i.e. a passphrase) and/or to use various kind of characters (uppercase, lowercase, digits and special characters).",
"good_practices_about_user_password": "You are now about to define a new user password. The password should be at least 8 characters - though it is good practice to use longer password (i.e. a passphrase) and/or to use various kind of characters (uppercase, lowercase, digits and special characters).",
"group": "Group",
"group_name": "Group name",
"group_all_users": "All users",
"group_visitors": "Visitors",
"group_format_name_help": "You can use alpha-numeric chars and space",
"group_format_name_help": "You can use alpha-numeric chars and underscore",
"group_add_member": "Add a user",
"group_add_permission": "Add a permission",
"group_new": "New group",
@ -132,10 +182,18 @@
"group_explain_visitors": "This is a special group representing anonymous visitors",
"group_explain_visitors_needed_for_external_client": "Be careful that you need to keep some applications allowed to visitors if you intend to use them with external clients. For example, this is the case for Nextcloud if you want intend to use a synchronization client on your smartphone or desktop computer.",
"group_specific_permissions": "User specific permissions",
"groups": "Groups",
"groups_and_permissions": "Groups and permissions",
"groups_and_permissions_manage": "Manage groups and permissions",
"permissions": "Permissions",
"history": {
"title": "History",
"last_action": "Last action:",
"methods": {
"POST": "create/execute",
"PUT": "modify",
"DELETE": "delete"
}
},
"home": "Home",
"hook_adminjs_group_configuration": "System configurations",
"hook_conf_cron": "Automatic tasks",
@ -154,32 +212,37 @@
"hook_data_mail_desc": "Raw emails stored on the server",
"id": "ID",
"ignore": "Ignore",
"ignored": "%s ignored",
"inactive": "Inactive",
"ignored": "{count} ignored",
"infos": "Info",
"install": "Install",
"install_name": "Install %s",
"install_name": "Install {id}",
"install_time": "Install time",
"installation_complete": "Installation complete",
"installed": "Installed",
"internal_exception": "<strong>Yunohost encountered an internal error:/</strong><br><em>Really sorry about that.<br>You should look for help on <a href=\"https://forum.yunohost.org/\">the forum</a> or <a href=\"https://chat.yunohost.org/\">the chat</a> to fix the situation, or report the bug on <a href=\"https://github.com/YunoHost/issues\">the bugtracker</a>.</em><br>The following information might be useful for the person helping you:<h3>Action</h3><pre>%s%s</pre><h3>Traceback</h3><pre>%s</pre>",
"ipv4": "IPv4",
"ipv6": "IPv6",
"issues": "%s issues",
"issues": "{count} issues",
"items": {
"apps": "no apps | app | {c} apps",
"backups": "no backups | backup | {c} backups",
"domains": "no domains | domain | {c} domains",
"groups": "no groups | group | {c} groups",
"installed_apps": "no installed apps | installed app | {c} installed apps",
"logs": "no logs | log | {c} logs",
"services": "no services | service | {c} services",
"users": "no users | user | {c} users"
},
"items_verbose_count": "There is {items}.",
"label": "Label",
"label_for_manifestname": "Label for %s",
"label_for_manifestname": "Label for {name}",
"last_ran": "Last time ran:",
"license": "License",
"loading": "Loading …",
"local_archives": "Local archives",
"logged_in": "Logged in",
"logged_out": "Logged out",
"login": "Login",
"logout": "Logout",
"mailbox_quota_description": "For example, 700M is a CD, 4700M is a DVD.",
"mailbox_quota_placeholder": "Leave empty or set to 0 to disable.",
"maintained": "maintained",
"maintained_details": "This app was maintained by its maintainer in the last few months.",
"mailbox_quota_description": "Set a storage size limit for email content.<br>Set to 0 to disable.",
"mailbox_quota_example": "700M is a CD, 4700M is a DVD",
"mailbox_quota_placeholder": "Set to 0 to disable.",
"manage_apps": "Manage apps",
"manage_domains": "Manage domains",
"manage_users": "Manage users",
@ -188,12 +251,12 @@
"migrations_done": "Previous migrations",
"migrations_no_pending": "No pending migrations",
"migrations_no_done": "No previous migrations",
"migrations_disclaimer_check_message": "I read and understood this disclaimer",
"migrations_disclaimer_not_checked": "This migration require you to acknowledge its disclaimer before running it.",
"multi_instance": "Multi instance",
"myserver": "myserver",
"myserver_org": "myserver.org",
"next": "Next",
"no": "No",
"no_installed_apps": "No installed apps.",
"nobody": "Nobody",
"ok": "OK",
"only_highquality_apps": "Only high-quality apps",
@ -207,13 +270,17 @@
"operation_failed_explanation": "This operation failed! Really sorry about that :( You can try to <a href='https://yunohost.org/help'>ask for help</a>. Please provide *the full log* of the operation to the people helping you. You can do so by clicking on the 'Share with Yunopaste' green button. When sharing the logs, YunoHost will automatically attempt to anonymize private data like domain names and IPs.",
"password": "Password",
"password_confirmation": "Password confirmation",
"password_empty": "The password field is empty",
"password_new": "New password",
"passwords_dont_match": "Passwords don't match",
"passwords_too_short": "Password is too short",
"path": "Path",
"perform": "Perform",
"placeholder": {
"username": "johndoe",
"firstname": "John",
"lastname": "Doe",
"groupname": "My group name",
"domain": "my-domain.com"
},
"logs": "Logs",
"log_suboperations": "Sub-operations",
"logs_suboperations": "Sub-operations",
"logs_operation": "Operations made on system with YunoHost",
"logs_history": "History of command run on system",
"logs_package": "Debian packages management history",
@ -227,34 +294,34 @@
"logs_started_at": "Start",
"logs_path": "Path",
"logs_context": "Context",
"logs_share_with_yunopaste": "Share with YunoPaste",
"logs_share_with_yunopaste": "Share logs with YunoPaste",
"logs_more": "Display more lines",
"path_url": "Path",
"pending_migrations": "There are some pending migrations waiting to be ran. Please go to the <a href='#/tools/migrations'>Tools > Migrations</a> view to run them.",
"permission_corresponding_url": "Corresponding URL",
"permission_main": "Main permission",
"permission_show_tile_enabled": "Show the tile in the user portal",
"permission_show_tile_enabled": "Visible as tile in user portal",
"port": "Port",
"ports": "Ports",
"postinstall": "Post-installation",
"postinstall_domain": "This is the first domain name linked to your YunoHost server, but also the one which will be used by your server's users to access the authentication portal. Accordingly, it will be visible by everyone, so choose it carefully.",
"postinstall_intro_1": "Congratulations! YunoHost has been successfully installed.",
"postinstall_intro_2": "Two more configuration steps are required to activate you server's services.",
"postinstall_intro_3": "You can obtain more information by visiting the <a href='//yunohost.org/postinstall' target='_blank'>appropriate documentation page</a>",
"postinstall_password": "This password will be used to manage everything on your server. Take the time to choose it wisely.",
"postinstall_set_domain": "Set main domain",
"postinstall_set_password": "Set administration password",
"previous": "Previous",
"protocol": "Protocol",
"read_more": "Read more",
"readme": "Readme",
"rerun_diagnosis": "Rerun diagnosis",
"request_adoption": "waiting adoption",
"request_adoption_details": "The current maintainer would like to stop maintaining this app. Feel free to propose yourself as the new maintainer!",
"request_help": "need help",
"request_help_details": "The current maintainer would like some help with the maintainance of this app. Feel free to come contribute on it!",
"restore": "Restore",
"restart": "Restart",
"run": "Run",
"running": "Running",
"save": "Save",
"search_for_apps": "Search for apps...",
"search": {
"for": "Search for {items}...",
"not_found": "There is {items} matching your criteria."
},
"select_all": "Select all",
"select_none": "Select none",
"service_start_on_boot": "Start on boot",
@ -277,56 +344,62 @@
"tip_about_user_email": "Users are created with an associated email address (and XMPP account) with the format username@domain.tld. Additional email aliases and email forwards can later be added by the admin and the user.",
"tools": "Tools",
"tools_adminpw": "Change administration password",
"tools_adminpw_confirm_placeholder": "Confirm the new password",
"tools_adminpw_current": "Current password",
"tools_adminpw_current_placeholder": "Enter your current password",
"tools_adminpw_new_placeholder": "Enter the new password",
"tools_download_ca": "Download SSL Certificate Authority (CA)",
"tools_download_ca_desc": "Click here to download your SSL certificate authority (CA)",
"tools_security_feed": "Security notifications",
"tools_security_feed_no_items": "No security notifications",
"tools_security_feed_subscribe_rss": "Subscribe to security notifications RSS",
"tools_security_feed_view_items": "View all security notifications",
"tools_power_up": "Your server seems to be accessible, you can now try to login.",
"tools_reboot": "Reboot your server",
"tools_reboot_btn": "Reboot",
"tools_reboot_done": "Rebooting...",
"tools_rebooting": "Your server is rebooting. To return to the web administration interface you need to wait for your server to be up. You can check that by refreshing this page (F5).",
"tools_rebooting": "Your server is rebooting. To return to the web administration interface you need to wait for your server to be up. You can wait for the login form to show up or check by refreshing this page (F5).",
"tools_shutdown": "Shutdown your server",
"tools_shutdown_btn": "Shutdown",
"tools_shutdown_done": "Shutting down...",
"tools_shuttingdown": "Your server is powering off. As long as your server is off, you won't be able to use the web administration.",
"tools_shutdown_reboot": "Shutdown/Reboot",
"tools_webadmin": {
"language": "Language",
"fallback_language": "Fallback language",
"fallback_language_description": "Language that will be used in case the translation is not available in the main language.",
"cache": "Cache",
"cache_description": "Consider disabling the cache if you plan on working with the CLI while also navigating in this web-admin.",
"experimental": "Experimental mode",
"experimental_description": "Gives you access to experimental features. These are considered unstable and may break your system.<br> Enabled this only if you know what you are doing.",
"transitions": "Page transition animations"
},
"tools_webadmin_settings": "Web-admin settings",
"traceback": "Traceback",
"udp": "UDP",
"unauthorized": "Unauthorized",
"unignore": "Unignore",
"uninstall": "Uninstall",
"unknown_action": "Unknown action %s",
"unknown_argument": "Unknown argument: %s",
"unknown": "Unknown",
"unmaintained": "Unmaintained",
"unmaintained_details": "This app has not been update for quite a while and the previous maintainer has gone away or does not have time to maintain this app. Feel free to check the app repository to provide your help",
"upload": "Upload",
"upload_archive": "Archive upload",
"upnp": "UPnP",
"upnp_disabled": "UPnP is disabled.",
"upnp_enabled": "UPnP is enabled.",
"url": "URL",
"user_email": "Email",
"user_emailaliases": "Mail aliases",
"user_emailaliases_add": "Add a mail alias",
"user_emailforward": "Mail forward",
"user_emailforward_add": "Add a mail forward",
"user_fullname": "Full name",
"user_interface_link": "User interface",
"user_mailbox_quota": "Mailbox quota",
"user_mailbox_use": "Mailbox used space",
"user_new_forward": "newforward@myforeigndomain.org",
"user_new_mail": "newmail@mydomain.org",
"user_username": "Username",
"user_username_edit": "Edit %ss account",
"user_username_edit": "Edit {name}s account",
"users": "Users",
"users_new": "New user",
"users_no": "No users.",
"version": "Version",
"warnings": "%s warnings",
"warning_first_user": "You probably need to <a href='#/users/create' class='alert-link'>create a user</a> first.",
"warnings": "{count} warnings",
"words": {
"collapse": "Collapse",
"default": "Default"
},
"wrong_password": "Wrong password",
"yes": "Yes",
"certificate_alert_not_valid": "CRITICAL: Current certificate is not valid! HTTPS won't work at all!",
@ -355,6 +428,6 @@
"regenerate_selfsigned_cert": "Regenerate self-signed certificate",
"revert_to_selfsigned_cert_message": "If you really want to, you can reinstall a self-signed certificate. (Not recommended)",
"revert_to_selfsigned_cert": "Revert to a self-signed certificate",
"purge_user_data_checkbox": "Purge %s's data? (This will remove the content of its home and mail directories.)",
"purge_user_data_checkbox": "Purge {name}'s data? (This will remove the content of its home and mail directories.)",
"purge_user_data_warning": "Purging user's data is not reversible. Be sure you know what you're doing!"
}

View file

@ -2,157 +2,93 @@
"password": "Pasvorto",
"login": "Ensaluti",
"logout": "Elsaluti",
"cancel": "Nuligi",
"error_connection_interrupted": "La servilo fermis la konekton anstataŭ respondi al ĝi. Ĉu nginx aŭ la yunohost-api estis restartigitaj aŭ haltigitaj pro iu kialo? (Erara kodo/mesaĝo: %s)",
"error_connection_interrupted": "La servilo fermis la konekton anstataŭ respondi al ĝi. Ĉu nginx aŭ la yunohost-api estis restartigitaj aŭ haltigitaj pro iu kialo?",
"license": "Permesilo",
"app_state_inprogress_explanation": "Ĉi tiu subtenanto de ĉi tiu app deklaris, ke ĉi tiu aplikaĵo ankoraŭ ne estas preta por produktado. ESPERANTU!",
"app_state_notworking_explanation": "Ĉi tiu prizorganto de ĉi tiu app deklaris ĝin \"ne funkcianta\". Ĝi BRAKOS vian sistemon!",
"app_state_high-quality": "alta kvalito",
"app_state_high-quality_explanation": "Ĉi tiu app estas bone integrita kun YunoHost. Ĝi estis (kaj estas!) Reviziita de la teamo de YunoHost. Ĝi povas atendi esti sekura kaj konservi longtempe.",
"app_state_highquality": "alta kvalito",
"app_state_highquality_explanation": "Ĉi tiu app estas bone integrita kun YunoHost. Ĝi estis (kaj estas!) Reviziita de la teamo de YunoHost. Ĝi povas atendi esti sekura kaj konservi longtempe.",
"app_state_working_explanation": "La prizorganto de ĉi tiu app deklaris ĝin \"laboranta\". Ĝi signifas, ke ĝi devas esti funkcia (c.f. aplika nivelo) sed ne nepre estas reviziita de pereloj, tamen ĝi eble enhavas problemojn aŭ ne plene integriĝas kun YunoHost.",
"maintained": "konservita",
"app_access_clearall_btn": "Forigi ĉiun aliron",
"good_practices_about_user_password": "Vi nun estas por difini novan uzantan pasvorton. La pasvorto devas esti almenaŭ 8 signoj - kvankam estas bone praktiki uzi pli longan pasvorton (t.e. pasfrazon) kaj / aŭ uzi diversajn specojn de signoj (majuskloj, minuskloj, ciferoj kaj specialaj signoj).",
"advanced": "Altnivela",
"from_to": "de %s al %s",
"allowed_users": "Permesitaj uzantoj",
"from_to": "de {0} al {1}",
"hook_data_home": "Uzantaj datumoj",
"app_info_uninstall_desc": "Forigu ĉi tiun aplikon.",
"logged_out": "Ensalutinta",
"app_repository": "Apliko-origino: ",
"app_install_cancel": "Instalado nuligita.",
"app_access_removeall_btn": "Forigu ĉian aliron",
"installed_apps": "Instalitaj aplikoj",
"count_min": "%s minimumajn",
"both": "Ambaŭ",
"connection": "Ligo",
"confirm_install_app_warning": "Averto: ĉi tiu aplikaĵo povas funkcii, sed ne bone integras en YunoHost. Iuj funkcioj kiel ekzemple aliĝilo kaj sekurkopio/restarigo eble ne haveblos.",
"hostname": "Hostname",
"confirm_access_clear": "Ĉu vi certas, ke vi volas forigi ĉiun aliron al %s ?",
"confirm_install_app_lowquality": "Averto: ĉi tiu aplikaĵo povas funkcii, sed ne bone integras en YunoHost. Iuj funkcioj kiel ekzemple aliĝilo kaj sekurkopio/restarigo eble ne haveblos.",
"all_apps": "Ĉiuj programoj",
"everyone_has_access": "Ĉiuj havas aliron.",
"app_no_actions": "Ĉi tiu apliko ne havas agojn",
"delete": "Forigi",
"download": "Elŝuti",
"confirm_restore": "Ĉu vi certas, ke vi volas restarigi %s ?",
"disk": "Disko",
"confirm_restore": "Ĉu vi certas, ke vi volas restarigi {name} ?",
"custom_app_url_only_github": "Nuntempe nur de GitHub",
"backup_new": "Nova sekurkopio",
"confirm_migrations_skip": "Forlasi migradojn ne rekomendas. Ĉu vi certas, ke vi volas fari tion ?",
"custom_app_install": "Instalu kutimon",
"app_access_clearall_desc": "Ĉiu uzanto havos aliron al %s.",
"confirm_service_disable": "Ĉu vi certas, ke vi volas malebligi %s ?",
"firewall": "Fajroŝirmilo",
"filesystem": "Dosier-sistemo",
"check_stmp": "haveno 25 aliro",
"home": "Hejmo",
"hook_conf_ynh_firewall": "Fajroŝirmilo",
"confirm_reboot_action_shutdown": "Ĉu vi certas, ke vi volas fermi vian servilon ?",
"hook_conf_ssh": "SSH",
"backup_archive_download": "Elŝutu ĉi tiun arkivon",
"free": "liberaj",
"confirm_update_system": "Ĉu vi certas, ke vi volas ĝisdatigi ĉiujn sistemajn pakaĵojn ?",
"backups_no": "Neniu sekurkopio",
"installation_complete": "Kompleta instalado",
"confirm_firewall_open": "Ĉu vi certas, ke vi volas malfermi havenojn %s ? (Protokoloj %s, konekto: %s)",
"application": "aplikaĵo",
"diagnosis_view_private": "Montri diagnozon kun privataj datumoj",
"confirm_postinstall": "Vi tuj lanĉos la postinstalaran procezon sur la domajno %s. Eble daŭras kelkajn minutojn, *ne interrompu la operacion*.",
"confirm_firewall_open": "Ĉu vi certas, ke vi volas malfermi havenojn {port} ? (Protokoloj {protocol}, konekto: {connection})",
"confirm_postinstall": "Vi tuj lanĉos la postinstalaran procezon sur la domajno {domain}. Eble daŭras kelkajn minutojn, *ne interrompu la operacion*.",
"description": "priskribo",
"hook_conf_ynh_mysql": "MySQL pasvorto",
"label_for_manifestname": "Etikedo por %s",
"label_for_manifestname": "Etikedo por {name}",
"diagnosis": "Diagnozo",
"inactive": "Senaktiva",
"confirm_install_app_danger": "AVERTO! Ĉi tiu aplikaĵo estas ankoraŭ eksperimenta (se ne eksplicite ne funkcias) kaj verŝajne rompos vian sistemon! Vi probable ne devas instali ĝin krom se vi scias kion vi faras. Ĉu vi pretas riski tion ?",
"confirm_install_app_inprogress": "AVERTO! Ĉi tiu aplikaĵo estas ankoraŭ eksperimenta (se ne eksplicite ne funkcias) kaj verŝajne rompos vian sistemon! Vi probable ne devas instali ĝin krom se vi scias kion vi faras. Ĉu vi pretas riski tion ?",
"install_time": "Dato de instalado",
"confirm_upnp_disable": "Ĉu vi certas, ke vi volas malebligi UPnP ?",
"domain_visit_url": "Vizitu %s",
"domain_visit_url": "Vizitu {url}",
"confirm_change_maindomain": "Ĉu vi certas, ke vi volas ŝanĝi la ĉefan domajnon ?",
"app_change_label": "Ŝanĝu Labeleton",
"app_install_custom_no_manifest": "Neniu manifest.json dosiero",
"error_server": "Servila eraro",
"hook_conf_ynh_certs": "SSL-atestiloj",
"app_access_addall_btn": "Ebligu aliron al ĉiuj",
"hook_conf_nginx": "Nginx",
"confirm_access_remove_user": "Ĉu vi certas, ke vi volas forigi aliron al %s por %s?",
"label": "vortiga",
"confirm_reboot_action_reboot": "Ĉu vi certas, ke vi volas reagordi vian servilon ?",
"confirm_upnp_enable": "Ĉu vi certas, ke vi volas ebligi UPnP ?",
"api_not_responding": "La API YunoHost ne respondas. Eble 'yunohost-api' estas malaperigita aŭ rekomencita?",
"domain_add_dyndns_doc": "... kaj mi volas dinamikan DNS-servon.",
"internal_exception": "<strong> YunoHost renkontis internan eraron: /</strong><br><em> Vere bedaŭras. <br> Vi devas serĉi helpon ĉe <a href = \"https://forum.yunohost.org/ \"> la forumo </a> aŭ <a href=\"https://chat.yunohost.org/\"> la spektaklo </a> por solvi la problemon, aŭ raporti la eraron pri <a href =\" https: / /github.com/YunoHost/issues\"> TheTracking Tool </a>. </em> <br>La jenaj informoj povas esti helpemaj al la helpa persono: <h3> Ago </h3> <antaŭ ><pre>%s %s</pre><h3>spuron</h3><pre>%s</pre>",
"hook_conf_ynh_currenthost": "Nuna ĉefa domajno",
"footer_version": "Funkciigita de <a href='https://yunohost.org'> YunoHost </a> %s (%s).",
"footer_version": "Funkciigita de <a href='https://yunohost.org'> YunoHost </a> {version} ({repo}).",
"close": "Proksimaj",
"enabled": "Ebligita",
"backup_type": "tipo",
"installing": "Instali",
"app_access_addall_desc": "Ĉiuj ekzistantaj uzantoj havos aliron al% s.",
"app_info_change_url_disabled_tooltip": "Ĉi tiu funkcio ankoraŭ ne estis efektivigita en ĉi tiu app",
"hook_conf_ssowat": "SSOwat",
"backup_archive_delete": "Forigi ĉi tiun ar archiveivon",
"cumulative_usage": "Akumula uzado",
"confirm_delete": "Ĉu vi certas, ke vi volas forigi %s ?",
"confirm_delete": "Ĉu vi certas, ke vi volas forigi {name} ?",
"domain_dns_conf_is_just_a_recommendation": "Ĉi tiu paĝo montras al vi la *rekomenditan* agordon. Ĝi *ne* agordas la DNS por vi. Estas via respondeco agordi vian DNS-zonon en via DNS-registristo laŭ ĉi tiu rekomendo.",
"available": "Havebla",
"domain_add_panel_with_domain": "Mi jam havas domajnan nomon…",
"error_select_domain": "Vi indiku domajnon",
"current_maintainer_title": "Aktuala subtenanto de ĉi tiu pako",
"copy": "Kopii",
"confirm_access_add": "Ĉu vi certas, ke vi volas aldoni aliron al %s por ĉiuj uzantoj?",
"hook_data_home_desc": "Datumoj pri uzanto lokitaj en /home/USER",
"confirm_service_stop": "Ĉu vi certas, ke vi volas ĉesi %s ?",
"confirm_service_stop": "Ĉu vi certas, ke vi volas ĉesi {name} ?",
"mailbox_quota_placeholder": "Lasu malplenan aŭ agordi al 0 por malaktivigi.",
"domain_default_desc": "La defaŭlta domajno estas la konekta domajno, kie uzantoj ensalutas.",
"domain_dns_longdesc": "Vidu DNS-agordon",
"domain_add_dns_doc": "... kaj mi <a href='//yunohost.org/dns'> agordis mian DNS ĝuste </a>.",
"confirm_update_apps": "Ĉu vi certas, ke vi volas ĝisdatigi ĉiujn aplikojn ?",
"confirm_install_custom_app": "AVERTO! Instali aplikojn de tria partio eble kompromitos la integrecon kaj sekurecon de via sistemo. Vi probable ne devas instali ĝin krom se vi scias kion vi faras. Ĉu vi pretas riski tion?",
"app_debug_tab": "Montriĝo-elpurigajn informojn",
"backup_archive_copy": "Kopiu ĉi tiun ar archiveivon sur alian stokadon",
"add": "Aldoni",
"check_mx": "MX rekordo",
"remove": "Forigi",
"gateway": "Pordego: ",
"confirm_update_specific_app": "Ĉu vi certas, ke vi volas ĝisdatigi %s ?",
"confirm_service_start": "Ĉu vi certas, ke vi volas komenci %s ?",
"confirm_update_specific_app": "Ĉu vi certas, ke vi volas ĝisdatigi {app} ?",
"confirm_service_start": "Ĉu vi certas, ke vi volas komenci {name} ?",
"local_archives": "Lokaj arkivoj",
"app_make_default": "Faru defaŭlta",
"app_info_default_desc": "Redirektu domajn radikon al ĉi tiu apliko (%s).",
"app_info_default_desc": "Redirektu domajn radikon al ĉi tiu apliko ({domain}).",
"hook_adminjs_group_configuration": "Sistemaj agordoj",
"error_server_unexpected": "Neatendita erara servilo (%s)",
"error_server_unexpected": "Neatendita erara servilo",
"domain_dns_config": "Agordo DNS",
"cpu_load": "CPU Ŝarĝo",
"form_input_example": "Ekzemplo: %s",
"form_input_example": "Ekzemplo: {example}",
"app_info_access_desc": "Grupoj/uzantoj nuntempe rajtas aliri ĉi tiun programon:",
"diagnosis_with_private": "Diagnozo kun privataj datumoj",
"install_name": "Instalu %s",
"domain_default": "Defaŭlta domajno",
"interface": "interfaco",
"install_name": "Instalu {id}",
"administration_password": "Administra pasvorto",
"app_access_removeall_desc": "Neniuj uzantoj havos aliron al %s.",
"app_info_changeurl_desc": "Ŝanĝu la aliron URL de ĉi tiu aplikaĵo (domajno kaj/aŭ vojo).",
"app_info_changelabel_desc": "Ŝanĝu etikedon en la portalo.",
"app_access": "Aliro",
"app_state": "Aplikoŝtato: ",
"app_debug_no_logs": "La protokoloj ne estas haveblaj",
"hook_data_mail": "Poŝto",
"confirm_service_enable": "Ĉu vi certas, ke vi volas ebligi %s ?",
"backup_create": "Krei sekurkopion",
"disabled": "Malebligita",
"io": "I/O",
"fs_type": "Tipo de dosiersistemo",
"domain_select": "Elekti domajnon",
"confirm_uninstall": "Ĉu vi certas, ke vi volas malinstali %s ?",
"confirm_firewall_close": "Ĉu vi certas, ke vi volas fermi havenon %s ? (protokolo: %s, rilato: %s)",
"confirm_uninstall": "Ĉu vi certas, ke vi volas malinstali {name} ?",
"confirm_firewall_close": "Ĉu vi certas, ke vi volas fermi havenon {port} ? (protokolo: {protocol}, rilato: {connection})",
"created_at": "Kreita ĉe",
"confirm_access_remove_all": "Ĉu vi certas, ke vi volas forigi ĉian aliron al %s ?",
"app_list": "Aplika listo",
"available_apps": "Haveblaj aplikoj",
"confirm_app_change_url": "Ĉu vi certas, ke vi volas ŝanĝi la URL-aliron de la aplikaĵo?",
"ipv6": "IPv6",
"begin": "Komencu",
"error_retrieve_feed": "Ne povis akiri la nutraĵon: %s . Vi eble havas kromprogramon malebligi vian retumilon plenumi ĉi tiun peton (aŭ la retejo malŝaltiĝas).",
"disable": "Malŝalti",
"domain_default_longdesc": "Jen via defaŭlta domajno.",
"hook_data_mail_desc": "Krudaj retpoŝtoj konservitaj en la servilo",
@ -161,22 +97,15 @@
"app_state_working": "laborante",
"installed": "Instalita",
"ok": "bone",
"logged_in": "Ensalutinta",
"local_ip": "Loka IP",
"backup_optional_password": "Laŭvola pasvorto",
"experimental_warning": "Averto: ĉi tiu funkcio estas eksperimenta kaj ne konsideras stabila, vi ne devas uzi ĝin krom se vi scias kion vi faras.",
"hook_conf_cron": "Aŭtomataj taskoj",
"log": "Ensaluto",
"domain_visit": "Vizitu",
"hook_conf_ldap": "Datumbazo LDAP",
"install": "Instalu",
"app_change_url": "Ŝanĝi URL",
"confirm_install_domain_root": "Vi ne povos instali iun alian app en %s. Daŭrigi ?",
"confirm_install_domain_root": "Vi ne povos instali iun alian app en {domain}. Daŭrigi ?",
"confirm_app_default": "Ĉu vi certas, ke vi volas igi ĉi tiun programon defaŭlta?",
"active": "Aktiva",
"error_modify_something": "Vi devus modifi ion",
"applications": "aplikoj",
"app_level": "Apliko nivelo",
"domain_add": "Aldoni domajnon",
"domain_delete_longdesc": "Forigi ĉi tiun domajnon",
"domain_name": "Domajna nomo",
@ -184,93 +113,55 @@
"mailbox_quota_description": "Ekzemple, 700M estas KD, 4700M estas DVD.",
"app_state_notworking": "ne funkcianta",
"enable": "Ebligi",
"backup_encryption_warning": "Ne forgesu ĉi tiun pasvorton, vi bezonos ĝin se vi volas restarigi la ar theivon",
"domain_add_panel_without_domain": "Mi ne havas domajnan nomon…",
"backup_optional_encryption": "Laŭvola ĉifrado",
"backup_content": "Rezerva enhavo",
"backup": "Rezerva",
"default": "Defaŭlta",
"domain_list": "Domajna Listo",
"domains": "Domajnoj",
"diagnosis_hide_private": "Montri diagnozon sen privataj datumoj",
"app_access_title": "%s aliro",
"ipv4": "IPv4",
"domain": "Domajno",
"app_state_inprogress": "ankoraŭ ne funkciante",
"dns": "DNS",
"app_info_debug_desc": "Montriĝo pri elpurigado de ĉi tiu apliko.",
"archive_empty": "Malplena arkivo",
"check": "Kontrolu",
"level": "nivelo",
"loading": "Ŝarĝante…",
"infos": "Informoj",
"bit_rate": "Bito kurzo",
"hook_conf_xmpp": "XMPP",
"id": "ID",
"logs_access": "Listo de aliroj kaj malpermesoj",
"maintained_details": "Ĉi tiu programo estis prizorgita de ĝia subtenanto dum la lastaj monatoj.",
"only_highquality_apps": "Nur altkvalitaj programoj",
"only_decent_quality_apps": "Nur deca kvalito apps",
"orphaned": "Ne konservita",
"request_adoption": "atendanta adopto",
"migrations_pending": "Pendaj migradoj",
"next": "Sekva",
"orphaned_details": "Ĉi tiu app ne estis konservita antaŭ tre tempo. Ĝi eble ankoraŭ funkcios, sed ne ricevos ian ĝisdatigon ĝis iu volontulas prizorgi ĝin. Bonvolu kontribui revivigi ĝin!",
"request_adoption_details": "La nuna prizorganto ŝatus ĉesi subteni ĉi tiun app. Bonvolu proponi vin kiel la novan prizorganton!",
"request_help": "bezonas helpon",
"request_help_details": "La nuna prizorganto ŝatus iom da helpo pri la bontenado de ĉi tiu app. Bonvolu veni kontribui pri ĝi!",
"user_email": "Retpoŝto",
"postinstall_intro_1": "Gratulojn! YunoHost estis sukcese instalita.",
"time_since_update": "Tempo ekde ĝisdatigo: ",
"no_installed_apps": "Neniuj instalitaj programoj.",
"usage": "uzo",
"uninstall": "Malinstali",
"users_new": "Nova uzanto",
"users": "Uzantoj",
"system_apps_nothing": "Ĉiuj aplikoj estas ĝisdatigitaj!",
"used": "Uzata",
"tools_security_feed_view_items": "Vidu ĉiujn sekurecajn sciigojn",
"certificate_alert_letsencrypt_about_to_expire": "Nuna atestilo estas preskaŭ eksvalidiĝi. Ĝi baldaŭ renoviĝu aŭtomate.",
"version": "versio",
"yes": "Jes",
"skip": "Salti",
"search_for_apps": "Serĉi aplikojn ...",
"upnp_disabled": "UPnP estas malebligita.",
"logs_no_logs_registered": "Neniu registro registrita por ĉi tiu kategorio",
"certificate_alert_good": "Bone, nuna atestilo aspektas bone!",
"network": "reto",
"purge_user_data_warning": "Purgaj datumoj de uzanto ne estas reverteblaj. Nepre vi scias, kion vi faras!",
"domain_not_eligible_for_ACME": "Ĉi tiu domajno ne ŝajnas preta por Letero-Ĉifrado. Bonvolu kontroli vian atingon de DNS-agordo kaj HTTP-servilo.",
"password_description": "Pasvorto devas esti almenaŭ %s signoj longa.",
"select_all": "Elekti ĉiujn",
"tcp": "TCP",
"domain_is_eligible_for_ACME": "Ĉi tiu domajno ŝajnas ĝuste agordita por instali atestilon Lasu Ĉifri!",
"system_upgrade_btn": "Altgradigon",
"ssl_certificate": "SSL-atestilo",
"certificate_manage": "Administri SSL-atestilon",
"tools_security_feed_subscribe_rss": "Aboni RSS pri sciigoj",
"tools_adminpw_confirm_placeholder": "Konfirmu la novan pasvorton",
"total": "Entute",
"confirm_cert_install_LE": "Ĉu vi certas, ke vi volas instali atestilon Lasu Ĉifri por ĉi tiu domajno?",
"myserver_org": "miaservisto.org",
"logs_operation": "Operacioj faritaj sur sistemo kun YunoHost",
"monitoring_check_glances": "Kontrolu <a href='#/services/glances'> rigardojn </a> servo-staton.",
"appslists": "Aplikoj-listoj",
"install_letsencrypt_cert": "Instalu atestilon Lasu-Ĉifri",
"appslists_custom": "Propra listo listo",
"no_log": "Neniu ŝtipo.",
"system_packages_nothing": "Ĉiuj sistemaj pakoj estas ĝisdatigitaj !",
"system_upgrade_all_applications_btn": "Ĝisdatigu ĉiujn aplikojn",
"postinstall": "post Instalaĵo",
"service_description": "Priskribo:",
"uptime": "Kuracado",
"revert_to_selfsigned_cert": "Reiru al mem-subskribita atestilo",
"certificate_old_letsencrypt_app_conflict": "La app 'letsencrypt' estas nuntempe instalita kaj konfliktas kun ĉi tiu funkcio. Bonvolu malinstali ĝin unue por uzi la novan registritan administran interfacon.",
"system_update": "Sistema ĝisdatigo",
"unauthorized": "Ne rajtigita",
"wrong_password": "Erara pasvorto",
"tools_security_feed": "Sekurecaj sciigoj",
"system_packages": "Sistempakaĵoj",
"certificate_alert_unknown": "Nekonata stato",
"tools_shutdown_reboot": "Ŝalti/Rekomenci",
"logs_started_at": "Komencu",
@ -281,150 +172,94 @@
"validity": "Valideco",
"upnp_enabled": "UPnP estas ebligita.",
"tools_reboot": "Reklamu vian servilon",
"mode": "Modon",
"manage_domains": "Administri domajnojn",
"user_username_edit": "Redakti %s konton",
"mount_point": "Montpunkto",
"user_username_edit": "Redakti {name} konton",
"logs_package": "Historio pri administrado de pakoj Debian",
"user_new_forward": "novjora@myforeigndomain.org",
"manually_renew_letsencrypt_message": "Atestilo estos aŭtomate renovigita dum la lastaj 15 tagoj de valideco. Vi povas permane renovigi ĝin se vi volas. (Ne rekomendita).",
"logs_share_with_yunopaste": "Kunhavigu kun YunoPaste",
"tools_download_ca": "Elŝutu SSL Atestilon-Aŭtoritaton (CA)",
"certificate": "Atestilo",
"logs_system": "Kernel ŝtipoj kaj aliaj malaltnivelaj eventoj",
"user_emailaliases": "Poŝti alias",
"certificate_authority": "Atestado-aŭtoritato",
"unmaintained": "Malkomprenita",
"regenerate_selfsigned_cert": "Regeneri mem-subskribitan atestilon",
"unknown_argument": "Nekonata argumento: %s",
"ports": "havenoj",
"select_user": "Elektu uzanton",
"system": "Sistemo",
"tools_reboot_btn": "Rekomencu",
"logs_history": "Historio de komando funkcianta sur sistemo",
"read_more": "Legu pli",
"monitoring_disabled": "Monitorado ne estas enŝaltita.",
"previous": "Antaŭa",
"services_list": "Servo-Listo",
"manage_users": "Administri uzantojn",
"logs_service": "Servoj ŝtipoj",
"tools_rebooting": "Via servilo rekomencas. Por reveni al la retadministra interfaco, vi devas atendi, ke via servilo funkcios. Vi povas kontroli tion per refreŝigado de ĉi tiu paĝo (F5).",
"tools_adminpw": "Ŝanĝu administran pasvorton",
"service_log": "%s ŝtipo",
"write": "Skribu",
"multi_instance": "Multaj ekzemploj",
"no_allowed_users": "Neniuj permesitaj uzantoj.",
"non_compatible_api": "Ne kongrua API",
"revert_to_selfsigned_cert_message": "Se vi vere volas, vi povas reinstali mem-subskribitan atestilon. (Ne rekomendita)",
"tools_adminpw_current_placeholder": "Enigu vian nunan pasvorton",
"user_mailbox_quota": "Poŝta kesto",
"operations": "Operacioj",
"migrations_done": "Antaŭaj migradoj",
"password_new": "Nova pasvorto",
"manually_renew_letsencrypt": "Mane renovigu nun",
"tools_adminpw_current": "Aktuala Pasvorto",
"appslists_manage": "Administri listojn de aplikoj",
"menu": "menuo",
"service_start_on_boot": "Komencu je ekkuro",
"storages_new": "Nova fora stokado",
"storage_create": "Aldonu forajn stokadojn",
"regenerate_selfsigned_cert_message": "Se vi volas, vi povas regeneri la mem-subskribitan atestilon.",
"migrations_no_pending": "Neniuj pritraktataj migradoj",
"appslists_last_update": "Lasta ĝisdatigo",
"logs_more": "Vidigu pliajn liniojn",
"logs_error": "Eraro",
"certificate_status": "Atestita statuso",
"no": "Ne",
"remove_access": "Forigi aliron",
"transmission": "transdono",
"upload_archive": "Alŝuta arkivo",
"tools_shutdown_btn": "Fermito",
"purge_user_data_checkbox": "Purigi datumojn de %s? (Ĉi tio forigos la enhavon de ĝiaj hejmaj kaj poŝtaj adresaroj.)",
"appslists_info_refresh_desc": "Refreŝigi statojn de ĉi tiu listo.",
"purge_user_data_checkbox": "Purigi datumojn de {name}? (Ĉi tio forigos la enhavon de ĝiaj hejmaj kaj poŝtaj adresaroj.)",
"migrations": "migrado",
"logs_ended_at": "Fino",
"restore": "Restaŭri",
"meltdown": "Vi estas vundebla al la <a target=\"_blank\" href=\"https://meltdownattack.com/\"> meltdown </a> maltrankviliga sekureco. Por ripari tion, vi devas <a href=\"#/update\"> ĝisdatigi vian sistemon </a> tiam <a href=\"#/tools/reboot\"> reŝalti ĝin </a> por ŝarĝi la novan linux-kernon.",
"view_user_profile": "Vidi %s profilon",
"user_mailbox_use": "Poŝtejo uzis spacon",
"appslists_unknown_list": "Listo de nekonataj programoj: %s",
"appslists_info_remove_desc": "Aplikoj de ĉi tiu listo ne plu estos haveblaj.",
"only_working_apps": "Nur funkciantaj programoj",
"postinstall_password": "Ĉi tiu pasvorto estos uzata por administri ĉion en via servilo. Prenu la tempon por elekti ĝin prudente.",
"start": "Komencu",
"certificate_alert_great": "Bonega! Vi uzas validan atestilon Lasu Ĉifri!",
"tools_download_ca_desc": "Alklaku ĉi tie por elŝuti vian SSL-atestan aŭtoritaton (CA)",
"confirm_cert_regen_selfsigned": "Ĉu vi certas, ke vi volas regeneri mem-subskribitan atestilon por ĉi tiu domajno?",
"storages_no": "Neniuj magazenoj.",
"passwords_too_short": "Pasvorto estas tro mallonga",
"appslists_confirm_remove": "Ĉu vi certas, ke vi volas forigi ĉi tiun liston de aplikoj?",
"myserver": "mia servisto",
"tools_adminpw_new_placeholder": "Enigu la novan pasvorton",
"user_emailforward": "Poŝti antaŭen",
"certificate_alert_about_to_expire": "AVERTO: Nuna atestilo finos! Ĝi ne renoviĝos aŭtomate!",
"system_upgrade_all_packages_btn": "Ĝisdatigu ĉiujn pakaĵojn",
"logs_end_with_error": "Ĉi tiu ŝtipo finiĝis per la eraro:",
"users_list": "Uzantlisto",
"migrations_no_done": "Neniuj antaŭaj migradoj",
"url": "URL",
"versions": "versioj",
"select_none": "Elektu neniun",
"size": "Grandeco",
"confirm_cert_manual_renew_LE": "Ĉu vi certas, ke vi volas permane renovigi la atestilon Lasu Ĉifri por ĉi tiu regado nun?",
"process": "Procezo",
"upload": "Alŝuti",
"logs": "Registroj",
"postinstall_intro_3": "Vi povas akiri pliajn informojn vizitante la <a href='//yunohost.org/postinstall' target='_blank'> taŭgan dokumentan paĝon </a>",
"user_new_mail": "novaĵisto@miadomino.org",
"tools_shuttingdown": "Via servilo elŝaltas. Tiel longe kiel via servilo malŝaltas, vi ne povos uzi la retan administradon.",
"logs_app": "Aplikoj ŝtipoj",
"tools_security_feed_no_items": "Neniuj sekurecaj sciigoj",
"running": "Kurado",
"reception": "Ricevo",
"appslists_no_lists": "Neniuj aplikoj-listoj",
"tools_shutdown_done": "Fermi ...",
"certificate_alert_not_valid": "KRITIKO: Nuna atestilo ne validas! HTTPS tute ne funkcios!",
"path_url": "Pado",
"status": "Statuso",
"set_default": "Fiksita defaŭlte",
"upnp": "UPnP",
"certificate_alert_selfsigned": "AVERTO: Nuna atestilo estas mem-subskribita. Foliumiloj aperigos timigan averton al novaj vizitantoj!",
"system_upgrade": "Sistema ĝisdatigo",
"protocol": "Protokolo",
"tools": "iloj",
"os": "Mastruma sistemo",
"port": "haveno",
"public_ip": "Publika IP: ",
"passwords_dont_match": "Pasvortoj ne kongruas",
"service_status": "Statuso: ",
"user_fullname": "Plena nomo",
"stop": "Ĉesu",
"save": "ŝpari",
"warning_first_user": "Vi probable devas <a href='#/users/create' class='alert-link'> krei unue uzanton </a>.",
"words": {
"default": "Defaŭlta"
},
"logs_context": "Kunteksto",
"services": "servoj",
"logs_path": "Pado",
"read": "legado",
"run": "Kuri",
"manage_apps": "Administri aplikon",
"system_apps": "Aplikoj",
"user_username": "Uzantnomo",
"path": "Pado",
"password_confirmation": "Pasvorta konfirmo",
"open": "Malfermu",
"unknown_action": "Nekonata ago %s",
"memory": "Memoro",
"refresh_app_list": "Refreŝigi liston",
"ram": "RAM",
"started_at": "Komencite ĉe:",
"tools_reboot_done": "Rekomencanta ...",
"monitoring": "Monitorado",
"password_empty": "La pasvorta kampo estas malplena",
"no_user_to_add": "Ne plu uzantoj aldoni.",
"postinstall_intro_2": "Du pliaj agordaj paŝoj necesas por aktivigi la servojn de via servilo.",
"name": "Nomo",
"udp": "UDP",
"swap": "Interŝanĝu",
"user_interface_link": "Uzantinterfaco",
"group_format_name_help": "Vi povas uzi alfa-numerikajn signojn kaj spacon",
"group_add_member": "Aldonu uzanton",
@ -444,26 +279,24 @@
"rerun_diagnosis": "Rerun diagnozo",
"details": "Detaloj",
"diagnosis_experimental_disclaimer": "Atentu, ke la diagnoza funkcio estas ankoraŭ eksperimenta kaj polurita, kaj ĝi eble ne estas plene fidinda.",
"errors": "%s eraroj",
"everything_good": "Ĉio bona!",
"ignore": "Ignori",
"ignored": "%s ignoris",
"warnings": "%s avertoj",
"ignored": "{count} ignoris",
"warnings": "{count} avertoj",
"last_ran": "Lastfoje kuris:",
"unignore": "un-ignori",
"configuration": "agordo",
"since": "el",
"all": "Ĉiuj",
"app_state_low_quality": "malkvalita",
"app_state_low_quality_explanation": "Ĉi tiu app eble funkcias, sed ankoraŭ enhavas problemojn, aŭ ne plene integras kun YunoHost, aŭ ĝi ne respektas la bonajn praktikojn.",
"app_state_lowquality": "malkvalita",
"app_state_lowquality_explanation": "Ĉi tiu app eble funkcias, sed ankoraŭ enhavas problemojn, aŭ ne plene integras kun YunoHost, aŭ ĝi ne respektas la bonajn praktikojn.",
"catalog": "Katalogo",
"others": "Aliaj",
"confirm_service_restart": "Ĉu vi certas, ke vi volas rekomenci %s ?",
"confirm_service_restart": "Ĉu vi certas, ke vi volas rekomenci {name} ?",
"diagnosis_first_run": "La diagnoza funkcio provos identigi oftajn problemojn pri la diversaj aspektoj de via servilo por certigi, ke ĉio funkcias glate. Bonvolu ne panikiĝi, se vi vidas amason da eraroj tuj post agordo de via servilo: ĝi ĝuste celas helpi vin identigi problemojn kaj gvidi vin ripari ilin. La diagnozo ankaŭ funkcios aŭtomate dufoje ĉiutage kaj retpoŝtu al la administranto se iuj problemoj ekestos.",
"group_explain_visitors_needed_for_external_client": "Atentu, ke vi bezonas konservi iujn aplikaĵojn permesitajn al vizitantoj se vi intencas uzi ilin kun eksteraj klientoj. Ekzemple, ĉi tiu estas la kazo de Nextcloud se vi volas intenci uzi sinkronigan klienton en via inteligenta telefono aŭ labortabla komputilo.",
"restart": "Rekomenci",
"unmaintained_details": "Ĉi tiu app ne estis ĝisdatigita antaŭ tre tempo kaj la antaŭa prizorganto foriĝis aŭ ne havas tempon por subteni ĉi tiun app. Bonvolu kontroli la app-deponejon por doni vian helpon",
"run_first_diagnosis": "Kuru komencan diagnozon",
"groups": "Grupoj",
"issues": "%s aferoj"
"issues": "{count} aferoj"
}

View file

@ -2,129 +2,62 @@
"action": "Acción",
"add": "Añadir",
"administration_password": "Contraseña de administración",
"allowed_users": "Usuarios permitidos",
"api_not_responding": "La API de YunoHost no responde. ¿Tal vez «yunohost-api» está inoperativa o ha sido reiniciada?",
"app_access": "Acceso",
"app_access_addall_btn": "Habilitar acceso para todos",
"app_access_addall_desc": "Todos los usuarios existentes tendrán acceso a %s 1.",
"app_access_clearall_btn": "Desactive todos los accesos",
"app_access_clearall_desc": "Cada usuario tendrá acceso a %s 2.",
"app_access_removeall_btn": "Eliminar todos los accesos",
"app_access_removeall_desc": "Ningún usuario tendrá acceso a %s 3.",
"app_access_title": "Acceso %s 4",
"app_debug_no_logs": "Los registros de la aplicación no están disponibles",
"app_debug_tab": "Mostrar información de depuración",
"app_info_access_desc": "Grupos / usuarios actualmente autorizados a acceder a esta aplicación:",
"app_info_debug_desc": "Mostrar información de depuración para esta aplicación.",
"app_info_default_desc": "Redirigir la raíz del dominio para esta aplicación (%s 6).",
"app_info_default_desc": "Redirigir la raíz del dominio para esta aplicación ({domain} 6).",
"app_info_uninstall_desc": "Eliminar a esta aplicación.",
"app_install_cancel": "Instalación cancelada.",
"app_install_custom_no_manifest": "Archivo manifest.json no encontrado",
"app_list": "Lista de aplicaciones",
"app_make_default": "Establecer como predeterminado",
"app_repository": "Origen de la aplicación: ",
"app_state": "Estado de la aplicación: ",
"app_state_inprogress": "Todavía no trabajando",
"app_state_notworking": "No está funcionado",
"app_state_validated": "Validado",
"app_state_working": "Funcionando",
"application": "Aplicación",
"applications": "Aplicaciones",
"archive_empty": "Archivo vacío",
"available": "Disponible",
"available_apps": "Aplicaciones disponibles",
"backup": "Sistema de copia de seguridad",
"backup_action": "Copia de seguridad",
"backup_archive_copy": "Copiar este archivo en otro almacén",
"backup_archive_delete": "Eliminar este archivo",
"backup_archive_download": "Bajar este archivo",
"backup_content": "Contenido de la copia de la seguridad",
"backup_create": "Crear copia de seguridad",
"backup_encryption_warning": "No olvide esta contraseña, la necesitará para restaurar el archivo",
"backup_experimental_warning": "Tenga en cuenta que la función de copia de seguridad es todavía experimental, y puede no ser totalmente fiable.",
"backup_new": "Nueva copia de seguridad",
"backup_optional_encryption": "Cifrado opcional",
"backup_optional_password": "Contraseña opcional",
"backup_type": "Tipo",
"backup_warning_desc": "Usted debe tener cuidado de realizar copias de seguridad de datos para usted mismo ahora.",
"backup_warning_title": "El sistema de copia de seguridad no se ha implementado todavía.",
"backups_no": "No hay copia de seguridad",
"begin": "Empezar",
"bit_rate": "Tasa de bits",
"both": "Ambos",
"cancel": "Cancelar",
"check": "Comprobar",
"check_mx": "Registro MX",
"check_stmp": "Acceso al puerto 25",
"close": "Cerrar",
"confirm_access_add": "¿Está seguro que desea añadir el acceso a %s para todos los usuarios?",
"confirm_access_clear": "¿Está seguro que desea borrar todos los accesos a %s?",
"confirm_access_remove_all": "¿Está seguro de que desea eliminar todos los accesos a %s?",
"confirm_access_remove_user": "¿Está seguro que desea eliminar el acceso a %s para %s?",
"confirm_app_default": "¿Está seguro que desea convertir esta aplicación en predeterminada?",
"confirm_change_maindomain": "¿Está seguro de que desea cambiar el dominio principal?",
"confirm_delete": "¿Está seguro que desea eliminar %s?",
"confirm_firewall": "Está seguro de %s puerto %s (protocolo: %s, conexión: %s)",
"confirm_delete": "¿Está seguro que desea eliminar {name}?",
"confirm_install_custom_app": "¡AVISO! La instalación de aplicaciones de terceros puede comprometer la seguridad e integridad de su sistema. Probablemente debería NO instalarla salvo que sepa lo que está haciendo. ¿Está dispuesto a correr el riesgo?",
"confirm_install_domain_root": "No podrá instalar otra aplicación en %s. ¿Desea continuar?",
"confirm_postinstall": "Está a punto de lanzar el proceso de post-instalación para el dominio %s. Puede tardar unos pocos minutos, *no interrumpa la operación*.",
"confirm_restore": "¿Está seguro que desea restaurar %s?",
"confirm_service_action": "¿Estás seguro que deseas %s %s?",
"confirm_uninstall": "¿Está seguro que desea desinstalar %s?",
"confirm_update_type": "¿Está que desea actualizar cada %s?",
"confirm_upnp_action": "¿Está seguro que desea %s UPnP?",
"confirm_install_domain_root": "No podrá instalar otra aplicación en {domain}. ¿Desea continuar?",
"confirm_postinstall": "Está a punto de lanzar el proceso de post-instalación para el dominio {domain}. Puede tardar unos pocos minutos, *no interrumpa la operación*.",
"confirm_restore": "¿Está seguro que desea restaurar {name}?",
"confirm_uninstall": "¿Está seguro que desea desinstalar {name}?",
"connection": "Conexión",
"copy": "Copia",
"count_min": "Min %s",
"cpu_load": "Carga de la CPU",
"created_at": "Creado en",
"cumulative_usage": "Uso acumulado",
"custom_app_install": "Instalar aplicación personalizada",
"custom_app_url_only_github": "Por ahora solo desde GitHub",
"default": "Predeterminado",
"delete": "Suprimir",
"description": "Descripción",
"diagnosis": "Diagnóstico",
"diagnosis_hide_private": "Mostrar diagnóstico sin datos privados",
"diagnosis_view_private": "Mostrar diagnóstico incluyendo datos privados",
"diagnosis_with_private": "Diagnóstico con datos privados",
"disable": "Inhabilitar",
"disabled": "Desactivado",
"disk": "Disco",
"dns": "DNS",
"domain": "Dominio",
"domain_add": "Añadir dominio",
"domain_add_dns_doc": "... y tengo <a href='//yunohost.org/dns'>mi DNS correctamente configurado</a>.",
"domain_add_dyndns_doc": "…y quiero un servicio de DNS dinámico.",
"domain_add_panel_with_domain": "Ya tengo un nombre de dominio…",
"domain_add_panel_without_domain": "No tengo un nombre de dominio…",
"domain_default": "Dominio predeterminado",
"domain_default_desc": "El dominio predeterminado es el dominio donde los usuarios inician sesión.",
"domain_default_longdesc": "Este es su dominio predeterminado.",
"domain_delete_longdesc": "Eliminar este dominio",
"domain_dns_config": "Configuración DNS",
"domain_dns_longdesc": "Ver configuración DNS",
"domain_list": "Lista de dominios",
"domain_name": "Nombre de dominio",
"domain_select": "Seleccione un dominio",
"domain_visit": "Visitar",
"domain_visit_url": "Visita %s",
"domain_visit_url": "Visita {url}",
"domains": "Nombres de dominio",
"download": "Bajar",
"enable": "Habilitar",
"enabled": "Habilitado",
"error_modify_something": "Debe modificar algo",
"error_occured": "Ha ocurrido un error, inténtelo de nuevo",
"error_retrieve_feed": "No se pudo recuperar la fuente: %s. Puede que tenga una extensión en su navegador bloqueando esta solicitud (o puede que el sitio web esté caído).",
"error_select_domain": "Debe indicar un dominio",
"error_server": "Error del servidor",
"error_server_unexpected": "Error inesperado en el servidor (%s)",
"everyone_has_access": "Todo el mundo tiene acceso.",
"filesystem": "Sistema de archivos",
"error_server_unexpected": "Error inesperado en el servidor",
"firewall": "Cortafuegos",
"free": "Libre",
"fs_type": "Tipo de sistema de archivos",
"gateway": "Puerta: ",
"home": "Inicio",
"hook_adminjs_group_configuration": "ajustes del sistema",
"hook_conf_cron": "Tareas automáticas",
@ -140,29 +73,18 @@
"hook_data_home_desc": "Datos de usuario en /home/USUARIO",
"hook_data_mail": "Correo",
"hook_data_mail_desc": "Correos sin procesar almacenados en el servidor",
"hostname": "Nombre del anfitrión",
"id": "ID",
"inactive": "Inactivo",
"infos": "Información",
"install": "Instalar",
"install_name": "Instalar %s",
"install_name": "Instalar {id}",
"install_time": "Tiempo de instalación",
"installation_complete": "Instalación finalizada",
"installed": "Instalado",
"installed_apps": "Aplicaciones instaladas",
"installing": "Instalando",
"interface": "Interfaz",
"io": "I/O",
"ipv4": "IPv4",
"ipv6": "IPv6",
"label": "Etiqueta",
"label_for_manifestname": "Etiqueta para %s",
"loading": "Cargando…",
"label_for_manifestname": "Etiqueta para {name}",
"local_archives": "Archivos locales",
"local_ip": "IP local",
"log": "Registro",
"logged_in": "Sesión iniciada",
"logged_out": "Sesión cerrada",
"login": "Iniciar sesión",
"logout": "Cerrar sesión",
"mailbox_quota_description": "Por ejemplo, 700M es un CD y 4700M es un DVD.",
@ -170,112 +92,51 @@
"manage_apps": "Gestión aplicaciones",
"manage_domains": "Gestión de dominios",
"manage_users": "Gestión de usuarios",
"memory": "Memoria",
"menu": "Menú",
"mode": "Modo",
"monitoring": "Monitoreo",
"monitoring_check_glances": "Revise el estado del servicio <a href='#/services/glances'>glances</a>.",
"monitoring_disabled": "La monitorización no está habilitada.",
"mount_point": "Punto de montaje",
"multi_instance": "Instancias múltiples",
"myserver": "miservidor",
"myserver_org": "miservidor.org",
"network": "Red",
"next": "Próximo",
"no": "No",
"no_allowed_users": "No hay usuarios permitidos.",
"no_installed_apps": "No hay aplicaciones instaladas.",
"no_log": "Ningún registro.",
"no_user_to_add": "No hay más usuarios para añadir.",
"non_compatible_api": "API no compatible",
"open": "Abierto",
"operations": "Operaciones",
"os": "Sistema operativo",
"password": "Contraseña",
"password_confirmation": "Confirmación contraseña",
"password_description": "La contraseña debe contener al menos %s caracteres.",
"password_empty": "El campo de la contraseña está vacío",
"password_new": "Nueva contraseña",
"passwords_dont_match": "Las contraseñas no coinciden",
"passwords_too_short": "La contraseña es demasiado corta",
"path": "Ruta",
"port": "Puerto",
"ports": "Puertos",
"postinstall": "Post-instalación",
"postinstall_domain": "Este es el primer nombre de dominio vinculado a su servidor YunoHost, pero también el que será utilizado por los usuarios para acceder al portal de identificación. Será visible por todos, elegir con cuidado.",
"postinstall_intro_1": "¡Felicitaciones! YunoHost se ha instalado correctamente.",
"postinstall_intro_2": "Todavía faltan dos pasos más para activar los servicios de su servidor.",
"postinstall_intro_3": "Más información disponible en <a href='//yunohost.org/postinstall' target='_blank'></a>",
"postinstall_password": "Esta contraseña se utiliza para gestionar todo su servidor. Tómese su tiempo para elegirla sabiamente.",
"previous": "Anterior",
"process": "Proceso",
"protocol": "Protocolo",
"public_ip": "IP pública: ",
"ram": "RAM",
"read": "Leer",
"read_more": "Leer más",
"reception": "Recepción",
"refresh_app_list": "Actualizar lista",
"remove_access": "Elimine el acceso",
"restore": "Restaurar",
"running": "Funcionando",
"save": "Guardar",
"select_user": "Seleccionar usuario",
"service_log": "%s log",
"service_start_on_boot": "Inicie en el arranque",
"service_status": "Estado: ",
"services": "Servicios",
"services_list": "Lista de servicios",
"set_default": "Establecer predeterminado",
"size": "Tamaño",
"sleeping": "Dormido",
"start": "Empezar",
"status": "Estado",
"stop": "Stop",
"storage_create": "Añadir almacenamiento remoto",
"storages_new": "Nuevo almacenamiento remoto",
"storages_no": "Sin almacenamiento.",
"swap": "Swap",
"system": "Sistema",
"system_apps": "Aplicaciones",
"system_apps_nothing": "¡Todas las aplicaciones están actualizadas!",
"system_delayed_upgrade": "Retraso en actualización",
"system_delayed_upgrade_warning": "<b>%s</b> será actualizada automáticamente en la próxima hora.",
"system_packages": "Paquetes",
"system_packages_nothing": "¡Todos los paquetes del sistema están actualizados!",
"system_update": "Actualización del sistema",
"system_upgrade": "Actualización del sistema",
"system_upgrade_btn": "Actualización",
"tcp": "TCP",
"time_since_update": "Tiempo desde la actualización: ",
"tools": "Herramientas",
"tools_adminpw": "Cambiar contraseña del administrador",
"tools_adminpw_confirm_placeholder": "Confirme la nueva contraseña",
"tools_adminpw_current": "Contraseña actual",
"tools_adminpw_current_placeholder": "Introduzca su contraseña actual",
"tools_adminpw_new_placeholder": "Introduzca la nueva contraseña",
"tools_download_ca": "Descargar certificado SSL de la Autoridad Certificadora (CA)",
"tools_download_ca_desc": "Haga clic aquí para descargar el certificado SSL de la Autoridad Certificadora (CA)",
"tools_security_feed": "Notificaciones de seguridad",
"tools_security_feed_no_items": "No hay ninguna notificación de seguridad",
"tools_security_feed_subscribe_rss": "Suscribirse al canal RSS de notificaciones de seguridad",
"tools_security_feed_view_items": "Ver todas las notificaciones de seguridad",
"total": "Total",
"transmission": "Transmisión",
"udp": "UDP",
"unauthorized": "No autorizado",
"uninstall": "Desinstalar",
"unknown_action": "Acción desconocida %s",
"unknown_argument": "Argumento desconocido: %s",
"upload": "Subir",
"upload_archive": "Subir archivo",
"upnp": "UPnP",
"upnp_disabled": "UPnP está desactivado.",
"upnp_enabled": "UPnP está habilitado.",
"uptime": "Tiempo de actividad",
"url": "URL",
"usage": "Uso",
"used": "Usado",
"user_email": "Correo electrónico",
"user_emailaliases": "Alias de correo electrónico",
"user_emailforward": "Reenvío de correo electrónico",
@ -283,21 +144,15 @@
"user_interface_link": "Interfaz de usuario",
"user_mailbox_quota": "Cuota de correo",
"user_new_forward": "nuevoreenviar@dominioexterior.org",
"user_new_mail": "direccionnueva@midominio.com",
"user_username": "Nombre de usuario",
"user_username_edit": "Editar la cuenta de %s",
"user_username_edit": "Editar la cuenta de {name}",
"users": "Usuarios",
"users_list": "Lista de usuarios",
"users_new": "Nuevo usuario",
"users_no": "No hay usuarios.",
"versions": "Versiones",
"view_user_profile": "Ver perfil de %s",
"warning_first_user": "Es probable que tenga que crear primero un usuario <a href='#/users/create' class='alert-link'> </a>.",
"write": "Escribir",
"wrong_password": "Contraseña incorrecta",
"yes": "Sí",
"footer_version": "Con tecnología <a href='https://yunohost.org'> YunoHost </a> %s (%s).",
"form_input_example": "Por ejemplo: %s",
"footer_version": "Con tecnología <a href='https://yunohost.org'> YunoHost </a> {version} ({repo}).",
"form_input_example": "Por ejemplo: {example}",
"certificate_alert_not_valid": "CRÍTICO: ¡El certificado actual no es válido! ¡HTTPS no funcionará!",
"certificate_alert_selfsigned": "ADVERTENCIA: Está usando un certificado autofirmado. ¡Los navegadores mostrarán una advertencia a los nuevos visitantes!",
"certificate_alert_letsencrypt_about_to_expire": "El certificado actual está a punto de expirar. Pronto debería renovarse automáticamente.",
@ -306,7 +161,6 @@
"certificate_alert_great": "¡Excelente! ¡Está usando un certificado \"Let's Encrypt\" válido!",
"certificate_alert_unknown": "Estado desconocido",
"certificate_manage": "Administrar certificado SSL",
"certificate_old_letsencrypt_app_conflict": "La aplicación 'letsencrypt' está instalada y produce un conflicto. Por favor desinstále la aplication para poder usar la nueva interfaz de administración de certificados.",
"ssl_certificate": "Certificado SSL",
"confirm_cert_install_LE": "¿Está seguro de que desea instalar un certificado Let's Encrypt para este dominio?",
"confirm_cert_regen_selfsigned": "¿Está seguro de que desea regenerar un certificado autofirmado para este dominio?",
@ -326,28 +180,20 @@
"revert_to_selfsigned_cert_message": "Si realmente lo desea, puede reinstalar un certificado autofirmado. (No recomendado)",
"revert_to_selfsigned_cert": "Volver a un certificado autofirmado",
"user_mailbox_use": "Espacio utilizado",
"confirm_firewall_open": "¿Está seguro de que desea abrir el puerto %s? (protocolo: %s, conexión: %s)",
"confirm_firewall_close": "¿Está seguro de que desea cerrar el puerto %s? (protocolo: %s, conexión: %s)",
"confirm_service_start": "¿Está seguro de que desea iniciar %s?",
"confirm_service_stop": "¿Está seguro de que desea parar %s?",
"confirm_service_enable": "¿Está seguro de que desea habilitar %s?",
"confirm_service_disable": "¿Está seguro de que desea deshabilitar %s?",
"confirm_firewall_open": "¿Está seguro de que desea abrir el puerto {port}? (protocolo: {protocol}, conexión: {connection})",
"confirm_firewall_close": "¿Está seguro de que desea cerrar el puerto {port}? (protocolo: {protocol}, conexión: {connection})",
"confirm_service_start": "¿Está seguro de que desea iniciar {name}?",
"confirm_service_stop": "¿Está seguro de que desea parar {name}?",
"confirm_update_apps": "¿Está seguro de que desea actualizar todas las aplicaciones?",
"confirm_update_packages": "¿Está seguro de que desea actualizar todos los paquetes?",
"confirm_upnp_enable": "¿Está seguro de que desea habilitar UPnP?",
"confirm_upnp_disable": "¿Está seguro de que desea deshabilitar UPnP?",
"ok": "OK",
"active": "Activo",
"remove": "Eliminar",
"app_change_label": "Cambiar Etiqueta",
"app_change_url": "Cambiar URL",
"app_info_changelabel_desc": "Cambiar la etiqueta de la aplicación en el portal.",
"app_info_changeurl_desc": "Cambiar la URL de acceso de esta aplicación (dominio y/o ruta).",
"app_info_change_url_disabled_tooltip": "Esta función no ha sido implementada en esta aplicación todavía",
"app_no_actions": "Esta aplicación no tiene ninguna acción",
"confirm_app_change_url": "¿Está seguro de que desea cambiar la URL de acceso a la aplicación?",
"confirm_migrations_skip": "No se recomienda saltarse las migraciones. ¿Está seguro de que desea hacer eso?",
"confirm_update_specific_app": "¿Está seguro de que desea actualizar %s ?",
"confirm_update_specific_app": "¿Está seguro de que desea actualizar {app} ?",
"confirm_reboot_action_reboot": "¿Está seguro de que desea reiniciar su servidor?",
"confirm_reboot_action_shutdown": "¿Está seguro de que desea apagar su servidor?",
"domain_dns_conf_is_just_a_recommendation": "Esta página muestra la configuración *recomendada*. *No* configura el DNS para usted. Es su responsabilidad configurar su zona DNS en su registrador DNS de acuerdo con esta recomendación.",
@ -356,77 +202,51 @@
"migrations_done": "Migraciones anteriores",
"logs_operation": "Operaciones realizadas en el sistema con YunoHost",
"all_apps": "Todas las aplicaciones",
"app_license": "Licencia de la aplicación",
"app_level": "Nivel de la aplicación",
"app_state_official": "Oficial",
"confirm_install_app_warning": "Aviso: esta aplicación puede funcionar pero no está bien integrada en YunoHost. Algunas características como inicio de sesión único y copia de seguridad/restauración podría no estar disponible.",
"confirm_install_app_danger": "¡AVISO! ¡Esta aplicación es aún experimental (puede que ni funcione) y es probable que rompa su sistema! Seguramente debería NO instalarla salvo que sepa lo que está haciendo. ¿Está dispuesto a correr ese riesgo?",
"current_maintainer_title": "Mantenedor actual de este paquete",
"error_connection_interrupted": "El servidor cerró la conexión en vez de responder. ¿Ha sido reiniciado o parado nginx o yunohost-api por cualquier motivo? (Código de error/mensaje: %s)",
"confirm_install_app_lowquality": "Aviso: esta aplicación puede funcionar pero no está bien integrada en YunoHost. Algunas características como inicio de sesión único y copia de seguridad/restauración podría no estar disponible.",
"confirm_install_app_inprogress": "¡AVISO! ¡Esta aplicación es aún experimental (puede que ni funcione) y es probable que rompa su sistema! Seguramente debería NO instalarla salvo que sepa lo que está haciendo. ¿Está dispuesto a correr ese riesgo?",
"error_connection_interrupted": "El servidor cerró la conexión en vez de responder. ¿Ha sido reiniciado o parado nginx o yunohost-api por cualquier motivo?",
"experimental_warning": "Aviso: esta característica es experimental y no se considera estable, no debería usarla salvo que sepa lo que está haciendo.",
"good_practices_about_admin_password": "Está a punto de establecer una nueva contraseña de administrador. La contraseña debería de ser de al menos 8 caracteres, aunque es una buena práctica usar una contraseña más larga (es decir, una frase de paso) y/o usar varias clases de caracteres (mayúsculas, minúsculas, dígitos y caracteres especiales).",
"good_practices_about_user_password": "Está a punto de establecer una nueva contraseña de usuario. La contraseña debería de ser de al menos 8 caracteres, aunque es una buena práctica usar una contraseña más larga (es decir, una frase de paso) y/o usar varias clases de caracteres (mayúsculas, minúsculas, dígitos y caracteres especiales).",
"app_state_notworking_explanation": "El mantenedor de esta aplicación declaró que «no funciona». ¡ROMPERÁ SU SISTEMA!",
"app_state_high-quality": "Alta calidad",
"app_state_highquality": "Alta calidad",
"license": "Licencia",
"maintained": "mantenido",
"maintained_details": "Esta aplicación ha sido mantenida por su mantenedor en los últimos meses.",
"confirm_update_system": "¿Seguro que quiere actualizar todos los paquetes del sistema?",
"advanced": "Avanzado",
"from_to": "desde %s a %s",
"from_to": "desde {0} a {1}",
"only_highquality_apps": "Solo aplicaciones de alta calidad",
"only_decent_quality_apps": "Solo aplicaciones de calidad aceptable",
"orphaned": "No mantenido",
"request_adoption": "pendiente de adopción",
"request_adoption_details": "Al mantenedor actual le gustaría dejar de mantener esta aplicación. ¡No dude en ofrecerse como el nuevo mantenedor!",
"request_help": "necesita ayuda",
"app_state_inprogress_explanation": "El mantenedor de esta aplicación declara que aún no está lista para su uso en producción. ¡TENGA CUIDADO!",
"app_state_high-quality_explanation": "Esta aplicación está bien integrada en YunoHost. Ha sido (¡y continúa siendo!) revisada por especialistas del equipo de aplicaciones de YunoHost. Se puede esperar que sea segura y mantenida a largo plazo.",
"app_state_highquality_explanation": "Esta aplicación está bien integrada en YunoHost. Ha sido (¡y continúa siendo!) revisada por especialistas del equipo de aplicaciones de YunoHost. Se puede esperar que sea segura y mantenida a largo plazo.",
"app_state_working_explanation": "El mantenedor de esta aplicación declara que «funciona». Significa que debería ser funcional (comparada a nivel de aplicación) pero no está revisada por especialistas necesariamente, puede tener aún problemas o no está totalmente integrada en YunoHost.",
"orphaned_details": "Esta aplicación no se ha mantenido durante bastante tiempo. Todavía puede estar funcionando, pero no recibirá ninguna actualización hasta que alguien se ofrezca como voluntario para encargarse de ello. ¡Siéntase libre de contribuir para revivirlo!",
"request_help_details": "Al mantenedor actual le gustaría recibir alguna ayuda con el mantenimiento de esta aplicación. ¡No dude en venir a contribuir!",
"tools_rebooting": "Su servidor se está reiniciando. Para volver a la interfaz de administración web necesita esperar a que el servidor esté listo. Puede comprobarlo recargando esta página (F5).",
"tools_shutdown_btn": "Apagar",
"name": "Nombre",
"logs": "Registros",
"logs_app": "Registros de aplicaciones",
"logs_ended_at": "Fin",
"appslists_last_update": "Última actualización",
"internal_exception": "<strong>Yunohost encontró un error interno:/</strong><br><em>Lo siento realmente.<br>Debería buscar ayuda en <a href=\"https://forum.yunohost.org/\">el foro</a> o en <a href=\"https://chat.yunohost.org/\">el chat</a> para arreglarlo o informar del fallo en <a href=\"https://github.com/YunoHost/issues\">el seguimiento de errores («bugtracker»)</a>.</em><br>La siguiente información podría ser útil para la persona que le ayude:<h3>Acción</h3><pre>%s%s</pre><h3>Rastreo</h3><pre>%s</pre>",
"unmaintained": "Sin mantenimiento",
"appslists_info_refresh_desc": "Actualizar el estado de las aplicaciones para esta lista.",
"logs_no_logs_registered": "Ningún registro para esta categoría",
"path_url": "Ruta",
"started_at": "Comenzó en:",
"hook_conf_ynh_currenthost": "dominio principal actual",
"purge_user_data_warning": "Los datos de usuario eliminados no se pueden recuperar. ¡Asegúrese de saber lo que está haciendo!",
"logs_end_with_error": "Este registro terminó con el error:",
"search_for_apps": "Buscar aplicaciones...",
"logs_context": "Contexto",
"meltdown": "Es vulnerable al problema crítico de seguridad de <a target=\"_blank\" href=\"https://meltdownattack.com/\">meltdown</a>. Para solucionarlo necesita <a href=\"#/update\">actualizar su sistema</a> y luego <a href=\"#/tools/reboot\">reiniciar</a> para que se cargue el nuevo núcleo de Linux.",
"only_working_apps": "Solo aplicaciones que funcionan",
"logs_system": "Registros del núcleo y otros eventos de bajo nivel",
"logs_share_with_yunopaste": "Compartir con YunoPaste",
"logs_package": "Historial de la gestión de los paquetes de Debian",
"logs_history": "Historial de órdenes ejecutadas en el sistema",
"migrations_no_pending": "Ninguna migración pendiente",
"appslists_unknown_list": "Lista de aplicaciones desconocidas: %s",
"tools_shutdown_reboot": "Apagar/Reiniciar",
"logs_more": "Mostrar más líneas",
"select_none": "No seleccionar ninguna",
"appslists_manage": "Administrar listas de aplicaciones",
"logs_path": "Ruta",
"purge_user_data_checkbox": "¿Eliminar los datos de %s? (Esto eliminará el contenido de sus directorios «home» y «mail».)",
"purge_user_data_checkbox": "¿Eliminar los datos de {name}? (Esto eliminará el contenido de sus directorios «home» y «mail».)",
"migrations_no_done": "Ninguna migración anterior",
"logs_access": "Lista de accesos y prohibiciones",
"tools_reboot_done": "Reiniciando...",
"appslists_custom": "Lista de aplicaciones personalizada",
"tools_shutdown": "Apagar su servidor",
"appslists_no_lists": "Ninguna lista de aplicaciones",
"tools_reboot_btn": "Reiniciar",
"appslists": "Listas de aplicaciones",
"version": "Versión",
"appslists_info_remove_desc": "Las aplicaciones de esta lista ya no estarán disponibles.",
"tools_shutdown_done": "Apagando...",
"tools_reboot": "Reiniciar su servidor",
"tools_shuttingdown": "Su servidor se está apagando. Mientras que el servidor esté apagado no podrá usar la administración web.",
@ -434,11 +254,8 @@
"logs_service": "Registros de servicios",
"run": "Ejecutar",
"logs_error": "Error",
"service_description": "Descripción:",
"skip": "Omitir",
"system_upgrade_all_packages_btn": "Actualizar todos los paquetes",
"appslists_confirm_remove": "¿Seguro que quiere eliminar esta lista de aplicaciones?",
"level": "nivel",
"system_upgrade_all_applications_btn": "Actualizar todas las aplicaciones",
"select_all": "Seleccionar todo",
"group_explain_all_users": "Este es un grupo especial que contiene todas las cuentas de usuarios en el servidor",
@ -459,13 +276,15 @@
"rerun_diagnosis": "Repetir diagnóstico",
"details": "Detalles",
"diagnosis_experimental_disclaimer": "Tenga en cuenta que la característica de diagnóstico es aún experimental y está siendo mejorada y puede no ser totalmente fiable.",
"errors": "%s errores",
"everything_good": "¡Todo bien!",
"ignore": "Ignorar",
"ignored": "%s ignorado",
"ignored": "{count} ignorado",
"last_ran": "Ejecutado por última vez:",
"unignore": "Dejar de ignorar",
"warnings": "%s avisos",
"warnings": "{count} avisos",
"words": {
"default": "Predeterminado"
},
"all": "Todo",
"diagnosis_first_run": "El diagnóstico intentará identificar los errores comunes en diferentes aspectos del servidor para asegurar que todo funcione de la mejor manera. No se asuste si observa algunos errores justo después de la configuracion del servidor: estos le ayudarán a identificar los incidentes y le guiarán para corregirlos. El diagnostico correrá 2 veces al día y enviará un correo electrónico al administrador si encuentra incidentes.",
"since": "desde",
@ -473,13 +292,12 @@
"run_first_diagnosis": "Procesando el primer diagnostico",
"configuration": "Configuración",
"catalog": "Catálogo",
"app_state_low_quality_explanation": "Asta app esta probablemente funcional, pero puede fallar, no esta completamente integrada con YunoHost, o no respeta las buenas practicas.",
"app_state_low_quality": "baja qualidad",
"confirm_service_restart": "¿Estás seguro de que quieres reiniciar %s ?",
"app_state_lowquality_explanation": "Asta app esta probablemente funcional, pero puede fallar, no esta completamente integrada con YunoHost, o no respeta las buenas practicas.",
"app_state_lowquality": "baja qualidad",
"confirm_service_restart": "¿Estás seguro de que quieres reiniciar {name} ?",
"group_explain_visitors_needed_for_external_client": "Tenga cuidado de que necesita mantener algunas aplicaciones permitidas a los visitantes si tiene la intención de usarlas con clientes externos. Por ejemplo, este es el caso de Nextcloud si desea utilizar un cliente de sincronización en su teléfono inteligente o computadora de escritorio.",
"issues": "%s problemas",
"issues": "{count} problemas",
"unmaintained_details": "Esta aplicación no se ha actualizado durante bastante tiempo y el responsable anterior se ha ido o no tiene tiempo para mantenerla. No dude en consultar el repositorio de aplicaciones para brindar su ayuda",
"groups": "Grupos",
"restart": "Reiniciar",
"diagnosis_explanation": "La funcionalidad de diagnóstico intentará identificar problemas comunes en varios aspectos del servidor para asegurarse de que todo vaya bien. El diagnóstico se ejecuta automáticamente dos veces al día y un correo electrónico se envía al administrador si se encuentra algún problema. Note que algunas pruebas pueden ser irrelevantes si no desea utilizar ciertas funcionalidades (por ejemplo XMPP) o podrían fallar si tiene una configuración compleja. En esos casos, si sabe lo que está haciendo, no hay problema con ignorar los errores o alertas correspondientes.",
"tip_about_user_email": "Los usuarios son creados con una dirección de correo electrónico (y cuenta XMPP) con el formato username@domain.ltd. Aliases de correo y reenvíos de correo pueden ser agregados luego por el administrador o el usuario.",
@ -487,9 +305,7 @@
"permission_main": "Permiso principal",
"permission_corresponding_url": "URL Correspondiente",
"pending_migrations": "Hay algunas migraciones esperando ejecutar. Por favor vaya a <a href='#/tools/migrations'>Herramientas > Migraciones</a> para verlas.",
"log_suboperations": "Sub-operaciones",
"logs_suboperations": "Sub-operaciones",
"operation_failed_explanation": "¡Esta operación falló! Lo sentimos mucho :( Puede intentar <a href='https://yunohost.org/help'>pedir ayuda</a>. Por favor comparta el *log completo* de la operación a la gente que ayude. Puede hacerlo haciendo click en el botón verde que dice 'Share with Yunopaste'. Cuando comparta los logs, YunoHost intentará automáticamente anonimizar datos privados como nombres de dominio y IPs.",
"app_manage_label_and_tiles": "Administrar etiquetas y tiles",
"app_info_managelabel_desc": "Administrar etiquetas de permisos en el portal.",
"apply": "Aplicar"
"app_manage_label_and_tiles": "Administrar etiquetas y tiles"
}

View file

@ -0,0 +1,4 @@
{
"password": "Pasahitza",
"ok": "Ados"
}

View file

@ -2,129 +2,62 @@
"action": "Action",
"add": "Ajouter",
"administration_password": "Mot de passe d'administration",
"allowed_users": "Utilisateurs autorisés",
"api_not_responding": "L'API YunoHost ne répond pas. Peut-être que 'yunohost-api' est en panne ou a été redémarré ?",
"app_access": "Accès",
"app_access_addall_btn": "Ajouter l'accès à tous les utilisateurs",
"app_access_addall_desc": "Tous les utilisateurs ont accès à %s.",
"app_access_clearall_btn": "Effacer toutes les règles accès",
"app_access_clearall_desc": "Tous les utilisateurs auront accès à %s.",
"app_access_removeall_btn": "Supprimer tous les accès",
"app_access_removeall_desc": "Aucun utilisateur n'aura accès à %s.",
"app_access_title": "Accès à %s",
"app_debug_no_logs": "Les journaux de cette application ne sont pas disponibles",
"app_debug_tab": "Afficher les informations de débogage",
"app_info_access_desc": "Groupes / utilisateurs actuellement autorisés à accéder à cette application :",
"app_info_debug_desc": "Afficher les informations de débogage pour cette application.",
"app_info_default_desc": "Redirige la racine du domaine vers cette application (%s).",
"app_info_default_desc": "Redirige la racine du domaine vers cette application ({domain}).",
"app_info_uninstall_desc": "Supprimer cette application.",
"app_install_cancel": "Installation annulée.",
"app_install_custom_no_manifest": "Aucun fichier manifest.json",
"app_list": "Liste des applications",
"app_make_default": "Définir par défaut",
"app_repository": "Origine de lapplication : ",
"app_state": "État de l'application : ",
"app_state_inprogress": "ne fonctionne pas encore",
"app_state_notworking": "Non fonctionnelle",
"app_state_validated": "Validée",
"app_state_working": "fonctionnelle",
"application": "Application",
"applications": "Applications",
"archive_empty": "Larchive est vide",
"available": "Disponible",
"available_apps": "Applications disponibles",
"backup": "Sauvegarde",
"backup_action": "Sauvegarder",
"backup_archive_copy": "Copier cette archive sur un autre stockage",
"backup_archive_delete": "Supprimer cette sauvegarde",
"backup_archive_download": "Télécharger cette sauvegarde",
"backup_content": "Contenu de la sauvegarde",
"backup_create": "Créer une sauvegarde",
"backup_encryption_warning": "N'oubliez pas ce mot de passe, vous en aurez besoin pour restaurer cette sauvegarde",
"backup_experimental_warning": "Soyez conscient que la fonctionnalité de sauvegarde est encore expérimentale, et n'est pas parfaitement fiable.",
"backup_new": "Nouvelle sauvegarde",
"backup_optional_encryption": "Chiffrement optionnel",
"backup_optional_password": "Mot de passe optionnel",
"backup_type": "Type",
"backup_warning_desc": "Vous devriez prendre soin de sauvegarder vos données vous-mêmes pour le moment.",
"backup_warning_title": "Le système de sauvegarde n'est pas encore implémenté.",
"backups_no": "Aucune sauvegarde",
"begin": "C'est parti !",
"bit_rate": "Débit",
"both": "Les deux",
"cancel": "Annuler",
"check": "Vérification",
"check_mx": "Enregistrement MX",
"check_stmp": "Accessibilité du port 25",
"close": "Fermer",
"confirm_access_add": "Voulez-vous vraiment ajouter l'accès à %s pour tous les utilisateurs ?",
"confirm_access_clear": "Voulez-vous vraiment supprimer tous les accès à %s ?",
"confirm_access_remove_all": "Voulez-vous vraiment supprimer tous les accès à %s ?",
"confirm_access_remove_user": "Voulez-vous vraiment supprimer laccès à %s pour %s ?",
"confirm_app_default": "Voulez-vous vraiment définir cette application par défaut ?",
"confirm_change_maindomain": "Voulez-vous vraiment changer le domaine principal ?",
"confirm_delete": "Voulez-vous vraiment supprimer %s ?",
"confirm_firewall": "Voulez-vous vraiment %s le port %s (protocole: %s, connexion: %s)",
"confirm_delete": "Voulez-vous vraiment supprimer {name} ?",
"confirm_install_custom_app": "ATTENTION ! Linstallation dapplications tierces peut compromettre lintégrité et la sécurité de votre système. Vous ne devriez probablement PAS linstaller si vous ne savez pas ce que vous faites. Prenez-vous ce risque ?",
"confirm_install_domain_root": "Vous ne pourrez pas installer d'autres applications sur %s. Continuer ?",
"confirm_postinstall": "Vous êtes sur le point de lancer le processus de post-installation sur le domaine %s. Cela peut prendre du temps, *n'interrompez pas l'opération avant la fin*.",
"confirm_restore": "Voulez-vous vraiment restaurer %s ?",
"confirm_service_action": "Voulez-vous vraiment %s %s ?",
"confirm_uninstall": "Voulez-vous vraiment désinstaller %s ?",
"confirm_update_type": "Voulez-vous vraiment mettre à jour toutes les %s ?",
"confirm_upnp_action": "Voulez-vous vraiment %s l'UPnP ?",
"confirm_install_domain_root": "Vous ne pourrez pas installer d'autres applications sur {domain}. Continuer ?",
"confirm_postinstall": "Vous êtes sur le point de lancer le processus de post-installation sur le domaine {domain}. Cela peut prendre du temps, *n'interrompez pas l'opération avant la fin*.",
"confirm_restore": "Voulez-vous vraiment restaurer {name} ?",
"confirm_uninstall": "Voulez-vous vraiment désinstaller {name} ?",
"connection": "Connexion",
"copy": "Copier",
"count_min": "%s min",
"cpu_load": "Charge CPU",
"created_at": "Crée le",
"cumulative_usage": "Utilisation cumulée",
"custom_app_install": "Installer une application personnalisée",
"custom_app_url_only_github": "Uniquement depuis GitHub pour linstant",
"default": "Défaut",
"delete": "Supprimer",
"description": "Description",
"diagnosis": "Diagnostic",
"diagnosis_hide_private": "Afficher le diagnostic sans les données sensibles",
"diagnosis_view_private": "Afficher le diagnostic en incluant les données sensibles",
"diagnosis_with_private": "Diagnostic avec les données sensibles",
"disable": "Désactiver",
"disabled": "Désactivé",
"disk": "Disque",
"dns": "DNS",
"domain": "Domaine",
"domain_add": "Ajouter un domaine",
"domain_add_dns_doc": "… et j'ai <a href='//yunohost.org/dns'>configuré mes DNS correctement</a>.",
"domain_add_dyndns_doc": "… et je souhaite ajouter un service DNS dynamique.",
"domain_add_panel_with_domain": "J'ai déjà un nom de domaine …",
"domain_add_panel_without_domain": "Je n'ai pas de nom de domaine …",
"domain_default": "Domaine par défaut",
"domain_default_desc": "Les utilisateurs se connecteront au domaine par défaut.",
"domain_default_longdesc": "Ceci est votre domaine par défaut.",
"domain_delete_longdesc": "Supprimer ce domaine",
"domain_dns_config": "Configuration DNS",
"domain_dns_longdesc": "Voir la configuration DNS",
"domain_list": "Liste des domaines",
"domain_name": "Nom de domaine",
"domain_select": "Sélectionnez un domaine",
"domain_visit": "Visiter",
"domain_visit_url": "Visiter %s",
"domain_visit_url": "Visiter {url}",
"domains": "Domaines",
"download": "Télécharger",
"enable": "Activer",
"enabled": "Activé",
"error_modify_something": "Vous devez modifier quelque chose",
"error_occured": "Une erreur est survenue, veuillez réessayer",
"error_retrieve_feed": "Impossible de récupérer le flux : %s. Il se peut quune extension empêche votre navigateur d'exécuter cette requête (ou que le site web soit hors service).",
"error_select_domain": "Vous devriez indiquer un domaine",
"error_server": "Erreur serveur",
"error_server_unexpected": "Erreur serveur inattendue (%s)",
"everyone_has_access": "Tous les utilisateurs y ont accès.",
"filesystem": "Système de fichier",
"error_server_unexpected": "Erreur serveur inattendue",
"firewall": "Pare-feu",
"free": "Libre",
"fs_type": "Type de système de fichier",
"gateway": "Passerelle : ",
"home": "Accueil",
"hook_adminjs_group_configuration": "Configuration système",
"hook_conf_cron": "Tâches automatiques",
@ -140,29 +73,18 @@
"hook_data_home_desc": "Les données de lutilisateur situées dans /home/USER",
"hook_data_mail": "Courriel",
"hook_data_mail_desc": "Courriels (au format brut) stockés sur le serveur",
"hostname": "Nom d'hôte",
"id": "ID",
"inactive": "Inactif",
"infos": "Info",
"install": "Installer",
"install_name": "Installer %s",
"install_name": "Installer {id}",
"install_time": "Date d'installation",
"installation_complete": "Installation terminée",
"installed": "Installé",
"installed_apps": "Applications installées",
"installing": "Installation",
"interface": "Interface",
"io": "Entrée/Sortie",
"ipv4": "IPv4",
"ipv6": "IPv6",
"label": "Libellé",
"label_for_manifestname": "Libellé pour %s",
"loading": "Chargement …",
"label_for_manifestname": "Libellé pour {name}",
"local_archives": "Archives locales",
"local_ip": "IP locale",
"log": "Journal",
"logged_in": "Connecté",
"logged_out": "Déconnecté",
"login": "Connexion",
"logout": "Déconnexion",
"mailbox_quota_description": "Par exemple, 700M est un CD, 4700M est un DVD.",
@ -170,113 +92,53 @@
"manage_apps": "Gérer les applications",
"manage_domains": "Gérer les domaines",
"manage_users": "Gérer les utilisateurs",
"memory": "Mémoire",
"menu": "Menu",
"mode": "Mode",
"monitoring": "État du serveur",
"monitoring_check_glances": "Verifiez l'état du service <a href='#/services/glances'>glances</a>.",
"monitoring_disabled": "Le suivi de l'état du serveur n'est pas activé.",
"mount_point": "Point de montage",
"multi_instance": "Instance multiple",
"myserver": "monserveur",
"myserver_org": "monserveur.fr",
"network": "Réseau",
"next": "Suivant",
"no": "Non",
"no_allowed_users": "Aucun utilisateur autorisé.",
"no_installed_apps": "Aucune application installée.",
"no_log": "Aucun journal.",
"no_user_to_add": "Aucun utilisateur à ajouter.",
"non_compatible_api": "API non compatible",
"open": "Ouvrir",
"operations": "Opérations",
"os": "Système dexploitation",
"password": "Mot de passe",
"password_confirmation": "Confirmation du mot de passe",
"password_description": "Le mot de passe doit faire au moins %s caractères.",
"password_empty": "Le champ pour le mot de passe est vide",
"password_new": "Nouveau mot de passe",
"passwords_dont_match": "Les mots de passe ne correspondent pas",
"passwords_too_short": "Le mot de passe est trop court",
"path": "Chemin",
"port": "Port",
"ports": "Ports",
"postinstall": "Post-installation",
"postinstall_domain": "C'est le premier nom de domaine lié à votre serveur YunoHost, mais également celui qui servira pour le portail d'authentification. Il sera donc visible pour tous vos utilisateurs, choisissez-le avec soin.",
"postinstall_intro_1": "Félicitations ! YunoHost a été installé avec succès.",
"postinstall_intro_2": "Deux étapes de configuration supplémentaires sont nécessaires pour activer les services de votre serveur.",
"postinstall_intro_3": "Vous pouvez obtenir plus d'informations en vous rendant sur <a href='//yunohost.org/postinstall_fr' target='_blank'>la page de documentation appropriée</a>",
"postinstall_password": "C'est le mot de passe qui vous permettra d'accéder à l'interface d'administration et de contrôler votre serveur. Prenez le temps d'en choisir un bon.",
"previous": "Précédent",
"process": "Processus",
"protocol": "Protocole",
"public_ip": "IP publique : ",
"ram": "Mémoire vive",
"read": "Lecture",
"read_more": "En savoir plus",
"reception": "Réception",
"refresh_app_list": "Rafraîchir la liste",
"remove_access": "Retirer les accès",
"restore": "Restaurer",
"running": "En cours dexécution",
"save": "Sauvegarder",
"select_user": "Choisissez un utilisateur",
"select_all": "Tout sélectionner",
"select_none": "Tout désélectionner",
"service_log": "Journal de %s",
"service_start_on_boot": "Lancement au démarrage :",
"service_status": "Statut : ",
"services": "Services",
"services_list": "Liste des services",
"set_default": "Définir par défaut",
"size": "Taille",
"start": "Démarrer",
"status": "Statut",
"stop": "Arrêter",
"storage_create": "Ajouter un stockage distant",
"storages_new": "Nouveau stockage distant",
"storages_no": "Aucun stockage.",
"swap": "Espace déchange",
"system": "Système",
"system_apps": "Applications",
"system_apps_nothing": "Toutes les applications sont à jour !",
"system_delayed_upgrade": "Mise à jour différée",
"system_delayed_upgrade_warning": "<b>%s</b> sera mis-à-jour automatiquement durant l'heure suivante.",
"system_packages": "Paquets système",
"system_packages_nothing": "Tous les packages système sont à jour !",
"system_update": "Mettre à jour le système",
"system_upgrade": "Mise à jour du système",
"system_upgrade_btn": "Mettre à jour",
"tcp": "TCP",
"time_since_update": "Dernière mise à jour : ",
"tools": "Outils",
"tools_adminpw": "Changer le mot de passe d'administration",
"tools_adminpw_confirm_placeholder": "Confirmez le nouveau mot de passe",
"tools_adminpw_current": "Mot de passe actuel",
"tools_adminpw_current_placeholder": "Entrez le mot de passe actuel",
"tools_adminpw_new_placeholder": "Entrez le nouveau mot de passe",
"tools_download_ca": "Télécharger l'autorité de certification SSL (CA)",
"tools_download_ca_desc": "Cliquez ici pour télécharger l'autorité de certification SSL (CA)",
"tools_security_feed": "Alertes de sécurité",
"tools_security_feed_no_items": "Aucune alertes de sécurité",
"tools_security_feed_subscribe_rss": "S'inscrire au flux RSS des alertes de sécurité",
"tools_security_feed_view_items": "Voir toutes les alertes de sécurité",
"total": "Total",
"transmission": "Émission",
"udp": "UDP",
"unauthorized": "Non autorisé",
"uninstall": "Désinstaller",
"unknown_action": "Action %s inconnue",
"unknown_argument": "Argument inconnu : %s",
"upload": "Téléversement",
"upload_archive": "Téléverser une archive",
"upnp": "UPnP",
"upnp_disabled": "LUPnP est désactivé.",
"upnp_enabled": "LUPnP est activé.",
"uptime": "Durée de fonctionnement",
"url": "URL",
"usage": "Utilisation",
"used": "Utilisé",
"user_email": "Courriel",
"user_emailaliases": "Alias de courriel",
"user_emailforward": "Adresses de transfert",
@ -284,21 +146,15 @@
"user_interface_link": "Interface utilisateur",
"user_mailbox_quota": "Quota de la boite aux lettres",
"user_new_forward": "nouveau_transfert@domainedistant.org",
"user_new_mail": "nouvelle_adresse@domaine.org",
"user_username": "Nom d'utilisateur",
"user_username_edit": "Éditer le compte de %s",
"user_username_edit": "Éditer le compte de {name}",
"users": "Utilisateurs",
"users_list": "Liste des utilisateurs",
"users_new": "Nouvel utilisateur",
"users_no": "Aucun utilisateur.",
"versions": "Versions",
"view_user_profile": "Voir le profil de %s",
"warning_first_user": "Vous devez probablement d'abord <a href='#/users/create' class='alert-link'>créer un utilisateur</a>.",
"write": "Écriture",
"wrong_password": "Mot de passe incorrect",
"yes": "Oui",
"form_input_example": "Exemple : %s",
"footer_version": "Propulsé par <a href='https://yunohost.org'>YunoHost</a> %s (%s).",
"form_input_example": "Exemple : {example}",
"footer_version": "Propulsé par <a href='https://yunohost.org'>YunoHost</a> {version} ({repo}).",
"certificate_alert_not_valid": "CRITIQUE : le certificat actuel nest pas valide ! Le HTTPS ne fonctionnera pas du tout !",
"certificate_alert_selfsigned": "AVERTISSEMENT : le certificat actuel est auto-signé. Les navigateurs afficheront un avertissement effrayant pour les nouveaux visiteurs !",
"certificate_alert_letsencrypt_about_to_expire": "Le certificat actuel est sur le point dexpirer. Il devrait bientôt être renouvelé automatiquement.",
@ -307,7 +163,6 @@
"certificate_alert_great": "Parfait ! Vous utilisez un certificat Lets Encrypt valide !",
"certificate_alert_unknown": "Statut inconnu",
"certificate_manage": "Gérer les certificats SSL",
"certificate_old_letsencrypt_app_conflict": "Lapplication « letsencrypt » est actuellement installée et est en conflit avec cette fonctionnalité. Veuillez la désinstaller pour utiliser la nouvelle interface de gestion des certificats.",
"ssl_certificate": "Certificat SSL",
"confirm_cert_install_LE": "Voulez-vous vraiment installer un certificat Lets Encrypt pour ce domaine ?",
"confirm_cert_regen_selfsigned": "Voulez-vous vraiment régénérer un certificat auto-signé pour ce domaine ?",
@ -327,36 +182,17 @@
"revert_to_selfsigned_cert_message": "Si vous le souhaitez vraiment, vous pouvez réinstaller un certificat auto-signé (non recommandé).",
"revert_to_selfsigned_cert": "Retourner à un certificat auto-signé",
"user_mailbox_use": "Espace utilisé de la boite aux lettres",
"confirm_firewall_open": "Voulez-vous vraiment ouvrir le port %s ? (protocole : %s, connexion : %s)",
"confirm_firewall_close": "Voulez-vous vraiment fermer le port %s ? (protocole : %s, connexion : %s)",
"confirm_service_start": "Voulez-vous vraiment démarrer %s ?",
"confirm_service_stop": "Voulez-vous vraiment arrêter %s ?",
"confirm_service_enable": "Voulez-vous vraiment activer %s ?",
"confirm_service_disable": "Voulez-vous vraiment désactiver %s ?",
"confirm_firewall_open": "Voulez-vous vraiment ouvrir le port {port} ? (protocole : {protocol}, connexion : {connection})",
"confirm_firewall_close": "Voulez-vous vraiment fermer le port {port} ? (protocole : {protocol}, connexion : {connection})",
"confirm_service_start": "Voulez-vous vraiment démarrer {name} ?",
"confirm_service_stop": "Voulez-vous vraiment arrêter {name} ?",
"confirm_update_apps": "Voulez-vous vraiment mettre à jour toutes les applications ?",
"confirm_update_packages": "Voulez-vous vraiment mettre à jour tous les paquets ?",
"confirm_upnp_enable": "Voulez-vous vraiment activer l'UPnP ?",
"confirm_upnp_disable": "Voulez-vous vraiment désactiver l'UPnP ?",
"remove": "Supprimer",
"appslists": "Listes dapplications",
"appslists_no_lists": "Aucune liste dapplications",
"appslists_custom": "Liste personnalisée dapplications",
"appslists_manage": "Gérer les listes dapplications",
"appslists_confirm_remove": "Voulez-vous vraiment supprimer cette liste dapplications ?",
"appslists_info_refresh_desc": "Actualiser le statut des applications de cette liste.",
"appslists_info_remove_desc": "Les applications de cette liste ne seront plus disponibles.",
"appslists_last_update": "Dernière mise à jour",
"appslists_unknown_list": "La liste d'applications %s est inconnue",
"appslists_community_list": "Liste des applications communautaires",
"name": "Nom",
"install_community_appslists_info": "La liste des applications communautaires vous permet dinstaller des applications maintenues par la communauté. <br />Parcourez la liste complète sur <a href='https://yunohost.org/apps'>yunohost.org/apps</a>.",
"install_community_appslists_warning": "Notez que ces applications ne sont <strong>pas</strong> officielles, et non maintenues par léquipe YunoHost. <br />Installer ces applications est à vos risques et périls, et peut casser votre système.",
"install_custom_app_appslists_info": "Vous pouvez utiliser des listes alternatives dapplications pour installer dautres applications maintenues par la communauté YunoHost.",
"domain_dns_conf_is_just_a_recommendation": "Cette page montre la configuration *recommandée*. Elle ne configure *pas* le DNS pour vous. Il est de votre responsabilité de configurer votre zone DNS chez votre bureau denregistrement DNS (registrar) en fonction de cette recommandation.",
"internal_exception": "<strong>YunoHost a rencontré une erreur interne :/</strong><br><em>Vraiment navré.<br>Vous devriez chercher de laide sur <a href=\"https://forum.yunohost.org/\">le forum</a> ou <a href=\"https://chat.yunohost.org/\">le salon</a> pour résoudre le problème, ou rapporter le bogue sur <a href=\"https://github.com/YunoHost/issues\">loutil de suivi</a>.</em><br>Les informations suivantes peuvent être utile à linterlocuteur vous aidant :<h3>Action</h3><pre>%s %s</pre><h3>Trace</h3><pre>%s</pre>",
"confirm_reboot_action_reboot": "Êtes vous sûr de vouloir redémarrer votre serveur ?",
"confirm_reboot_action_shutdown": "Êtes vous sûr de vouloir éteindre votre serveur ?",
"confirm_update_specific_app": "Êtes vous sûr de vouloir mettre à jour %s ?",
"confirm_update_specific_app": "Êtes vous sûr de vouloir mettre à jour {app} ?",
"ok": "OK",
"system_upgrade_all_applications_btn": "Mettre à jour toutes les applications",
"system_upgrade_all_packages_btn": "Mettre à jour tous les paquets",
@ -369,14 +205,9 @@
"tools_shutdown_done": "Extinction…",
"tools_shuttingdown": "Votre serveur est en train de sarrêter. Tant quil restera éteint vous ne pourrez plus utiliser linterface d'administration.",
"tools_shutdown_reboot": "Arrêter/Redémarrer",
"app_change_label": "Changer le libellé",
"app_change_url": "Changer lURL",
"app_info_changelabel_desc": "Change le libellé de lapplication dans le portail.",
"app_info_changeurl_desc": "Modifier lURL daccès de cette application (domaine et/ou chemin).",
"app_info_change_url_disabled_tooltip": "Cette fonctionnalité na pas encore été implémentée pour cette application",
"confirm_app_change_url": "Voulez-vous vraiment modifier lURL daccès de cette application ?",
"path_url": "Chemin",
"meltdown": "Vous êtes vulnérable à la faille de sécurité critique <a target=\"_blank\" href=\"https://meltdownattack.com/\">meltdown</a>. Pour résoudre le problème, vous devez <a href=\"#/update\">mettre à jour votre système</a> puis <a href=\"#/tools/reboot\">le redémarrer</a> pour charger le nouveau noyau Linux.",
"confirm_migrations_skip": "Ne pas appliquer les migrations nest pas recommandé. Voulez-vous vraiment le faire ?",
"migrations": "Migrations",
"migrations_pending": "Migrations en attente",
@ -385,23 +216,14 @@
"migrations_no_done": "Aucune migration précédente",
"run": "Exécuter",
"skip": "Passer",
"service_description": "Description :",
"started_at": "Démarré à :",
"active": "Actif",
"all_apps": "Toutes les applications",
"app_license": "Licence de l'application",
"app_level": "Niveau de qualité de lapplication",
"app_no_actions": "Cette application ne possède aucune action",
"app_state_official": "Officielle",
"confirm_install_app_warning": "Avertissement : cette application peut fonctionner mais nest pas bien intégrée dans YunoHost. Certaines fonctionnalités telles que lauthentification unique et la sauvegarde/restauration pourraient ne pas être disponibles.",
"confirm_install_app_danger": "AVERTISSEMENT ! Cette application est encore expérimentale et risque de casser votre système ! Vous ne devriez probablement PAS linstaller si vous ne savez pas ce que vous faites. Voulez-vous vraiment prendre ce risque ?",
"current_maintainer_title": "Mainteneur actuel de ce paquet",
"error_connection_interrupted": "Le serveur a fermé la connexion au lieu dy répondre. Est-ce que NGINX ou l'API YunoHost aurait été redémarré ou arrêté ? (code/message derreur : %s)",
"confirm_install_app_lowquality": "Avertissement : cette application peut fonctionner mais nest pas bien intégrée dans YunoHost. Certaines fonctionnalités telles que lauthentification unique et la sauvegarde/restauration pourraient ne pas être disponibles.",
"confirm_install_app_inprogress": "AVERTISSEMENT ! Cette application est encore expérimentale et risque de casser votre système ! Vous ne devriez probablement PAS linstaller si vous ne savez pas ce que vous faites. Voulez-vous vraiment prendre ce risque ?",
"error_connection_interrupted": "Le serveur a fermé la connexion au lieu dy répondre. Est-ce que NGINX ou l'API YunoHost aurait été redémarré ou arrêté ?",
"experimental_warning": "Attention : cette fonctionnalité est expérimentale et ne doit pas être considérée comme stable, vous ne devriez pas lutiliser à moins que vous ne sachiez ce que vous faites...",
"good_practices_about_admin_password": "Vous êtes maintenant sur le point de définir un nouveau mot de passe administrateur. Le mot de passe doit comporter au moins 8 caractères — bien quil soit recommandé dutiliser un mot de passe plus long (cest-à-dire une phrase secrète) et/ou dutiliser différents types de caractères (majuscules, minuscules, chiffres et caractères spéciaux).",
"good_practices_about_user_password": "Vous êtes maintenant sur le point de définir un nouveau mot de passe pour l'utilisateur. Le mot de passe doit comporter au moins 8 caractères - bien quil soit recommandé dutiliser un mot de passe plus long (cest-à-dire une phrase secrète) et/ou dutiliser différents types de caractères tels que : majuscules, minuscules, chiffres et caractères spéciaux.",
"level": "niveau",
"only_official_apps": "Applications officielles uniquement",
"only_working_apps": "Applications fonctionnelles uniquement",
"logs": "Journaux",
"logs_operation": "Opérations effectuées sur le système avec YunoHost",
@ -412,7 +234,6 @@
"logs_service": "Journaux des services",
"logs_app": "Journaux des applications",
"logs_no_logs_registered": "Aucun journal na été enregistré pour cette catégorie",
"logs_end_with_error": "Ce journal a fini avec lerreur :",
"logs_error": "Erreur",
"logs_ended_at": "Fin",
"logs_started_at": "Début",
@ -420,7 +241,6 @@
"logs_context": "Contexte",
"logs_share_with_yunopaste": "Partager avec YunoPaste",
"logs_more": "Afficher plus de lignes",
"search_for_apps": "Recherche des applications…",
"unmaintained": "Non maintenue",
"purge_user_data_checkbox": "Purger les données de l'utilisateur %s ? (Cela supprimera le contenu du dossier personnel de %s ainsi que tous les courriers électroniques de %s .)",
"purge_user_data_warning": "La purge des données de lutilisateur nest pas réversible. Assurez-vous de savoir ce que vous faites !",
@ -428,23 +248,16 @@
"confirm_update_system": "Voulez-vous vraiment mettre à jour tous les paquets système ?",
"app_state_inprogress_explanation": "Le responsable de cette application a déclaré que cette application n'est pas encore prête pour une utilisation en production. ATTENTION !",
"app_state_notworking_explanation": "Le responsable de cette application l'a décrite comme 'non fonctionnelle'. ATTENTION : SON INSTALLATION POURRAIT CASSER VOTRE SYSTÈME !",
"app_state_high-quality": "bonne qualité",
"app_state_high-quality_explanation": "Cette application est bien intégrée à YunoHost. Elle a été (et est !) revue par l'équipe applicative de YunoHost. On peut s'attendre à ce qu'elle soit sûre et maintenue sur le long terme.",
"app_state_highquality": "bonne qualité",
"app_state_highquality_explanation": "Cette application est bien intégrée à YunoHost. Elle a été (et est !) revue par l'équipe applicative de YunoHost. On peut s'attendre à ce qu'elle soit sûre et maintenue sur le long terme.",
"app_state_working_explanation": "Le responsable de cette application l'a déclarée comme 'fonctionnelle'. Cela signifie qu'elle doit fonctionner (voir son niveau d'intégration) mais n'est pas nécessairement revue, elle peut encore contenir des bugs ou bien n'est pas entièrement intégrée à YunoHost.",
"hook_conf_ynh_currenthost": "Domaine principal actuellement utilisé",
"license": "Licence",
"maintained": "Maintenue",
"maintained_details": "Cette application a été maintenue par son responsable au cours des derniers mois.",
"only_highquality_apps": "Seulement les applications de bonne qualité",
"only_decent_quality_apps": "Seulement les applications d'une qualité satisfaisante",
"orphaned": "Non maintenue",
"orphaned_details": "Cette application n'a pas été maintenue depuis un certain temps. Il peut encore fonctionner, mais ne recevra aucune mise à niveau jusqu'à ce que quelqu'un se porte volontaire pour s'en occuper. N'hésitez pas à contribuer à la faire revivre !",
"request_adoption": "en attente d'adoption",
"request_adoption_details": "Le responsable actuel ne souhaite plus s'occuper de cette application. N'hésitez pas à vous proposer comme nouveau responsable !",
"request_help": "besoin d'assistance",
"request_help_details": "Le mainteneur actuel souhaiterait de l'aide pour la maintenance de cette application. N'hésitez pas à contribuer !",
"advanced": "Avancée",
"from_to": "de %s à %s",
"from_to": "de {0} à {1}",
"group_name": "Nom du groupe",
"nobody": "Personne",
"group": "Groupe",
@ -463,37 +276,36 @@
"rerun_diagnosis": "Relancer le diagnostic",
"details": "Détails",
"diagnosis_experimental_disclaimer": "Sachez que la fonction de diagnostic est encore expérimentale et en cours de perfectionnement et quelle nest peut-être pas totalement fiable.",
"errors": "%s erreurs",
"everything_good": "Tout va bien !",
"ignore": "Ignore",
"ignored": "%s ignoré",
"ignored": "{count} ignoré",
"last_ran": "Dernière exécution :",
"unignore": "Cesser d'ignorer",
"warnings": "%s avertissements",
"warnings": "{count} avertissements",
"words": {
"default": "Défaut"
},
"configuration": "Configuration",
"since": "depuis",
"all": "Tout",
"app_state_low_quality": "faible qualité",
"app_state_low_quality_explanation": "Cette application peut être fonctionnelle, mais peut toujours contenir des problèmes, ou n'est pas entièrement intégrée à YunoHost, ou elle ne respecte pas les bonnes pratiques.",
"app_state_lowquality": "faible qualité",
"app_state_lowquality_explanation": "Cette application peut être fonctionnelle, mais peut toujours contenir des problèmes, ou n'est pas entièrement intégrée à YunoHost, ou elle ne respecte pas les bonnes pratiques.",
"catalog": "Catalogue",
"others": "Autres",
"diagnosis_first_run": "La fonctionnalité de diagnostic va tenter de trouver certains problèmes communs sur différents aspects de votre serveur pour être sûr que tout fonctionne normalement. Merci de ne pas paniquer si vous voyez une multitude d'erreurs après avoir configuré votre serveur : la fonctionnalité est précisément prévue pour les identifier et vous aider à les résoudre. Le diagnostic sera également effectué deux fois par jour et enverra un courriel à l'administrateur si des erreurs sont détectées.",
"run_first_diagnosis": "Démarrer le diagnostic initial",
"confirm_service_restart": "Êtes-vous certain de vouloir redémarrer %s ?",
"groups": "Groupes",
"confirm_service_restart": "Êtes-vous certain de vouloir redémarrer {name} ?",
"restart": "Redémarrer",
"unmaintained_details": "Cette application n'a pas été mise à jour depuis un bon moment et le responsable précédent est parti ou n'a pas le temps de maintenir cette application. N'hésitez pas à consulter le référentiel des applications pour apporter votre aide",
"group_explain_visitors_needed_for_external_client": "Veillez à ce que certaines applications soient autorisées pour les visiteurs si vous avez l'intention de les utiliser avec des clients externes. Par exemple, c'est le cas pour Nextcloud si vous souhaitez avoir l'intention d'utiliser un client de synchronisation sur votre smartphone ou ordinateur de bureau.",
"issues": "%s problèmes",
"issues": "{count} problèmes",
"operation_failed_explanation": "L'opération a échoué ! Veuillez-nous excuser pour ça :( Vous pouvez essayer de <a href='https://yunohost.org/help'>demander de l'aide</a>. Merci de fournir *le log complet* de l'opération pour les personnes qui vont vous aider. Vous pouvez cliquer sur le bouton vert 'Partager avec Yunopaste'. Quand vous partagez les logs, YunoHost essaie automatiquement d'anonymiser les informations privées comme le nom de domaine et l'adresses IP.",
"diagnosis_explanation": "La fonctionnalité de diagnostic va tenter de trouver certains problèmes communs sur différents aspects de votre serveur pour être sûr que tout fonctionne normalement. Le diagnostic sera également effectué deux fois par jour et enverra un courriel à l'administrateur si des erreurs sont détectées. À noter que certains tests ne seront pas montrés si vous n'utilisez pas certaines fonctions spécifiques (XMPP, par exemple) ou s'ils échouent à cause d'une configuration trop complexe. Dans ce cas, et si vous savez ce que vous avez modifié, vous pouvez ignorer les problèmes et les avertissements correspondantes.",
"pending_migrations": "Il y a des migrations en suspens qui attentent d'être exécutées. Veuillez aller dans <a href='#/tools/migrations'>Outils > Migrations</a> pour les exécuter.",
"tip_about_user_email": "Les utilisateurs sont créés avec une adresse e-mail associée (et un compte XMPP) au format username@domain.tld. Des alias d'email et des transferts d'emails supplémentaires peuvent être ajoutés ultérieurement par l'administrateur et l'utilisateur.",
"log_suboperations": "Sous-opérations",
"logs_suboperations": "Sous-opérations",
"permission_show_tile_enabled": "Montrer la tuile dans le portail utilisateur",
"permission_main": "Permission principale",
"permission_corresponding_url": "URL correspondante",
"app_manage_label_and_tiles": "Gérer les étiquettes et les tuiles",
"app_info_managelabel_desc": "Gérer les étiquettes des permissions et autorisations dans le portail web.",
"apply": "Appliquer"
"app_manage_label_and_tiles": "Gérer les étiquettes et les tuiles"
}

View file

@ -1,10 +1,7 @@
{
"logged_in": "लोग्ड इन",
"logged_out": "लॉग आउट",
"password": "पासवर्ड",
"action": "कार्रवाई",
"add": "जोड़े।",
"administration_password": "एडमिनिस्ट्रेटर का पासवर्ड।",
"cancel": "रद्द करना",
"ok": "ठीक है"
}

View file

@ -0,0 +1,4 @@
{
"password": "Jelszó",
"ok": "Rendben"
}

View file

@ -2,98 +2,44 @@
"action": "Azione",
"add": "Aggiungi",
"administration_password": "Password amministrazione",
"allowed_users": "Utenti consentiti",
"api_not_responding": "Le API YunoHost non rispondono. Forse 'yunohost-api' è giù o è stato riavviato?",
"app_access": "Accesso",
"app_access_addall_btn": "Attiva l'accesso per tutti",
"app_access_addall_desc": "Tutti gli utenti esistenti avranno accesso a %s.",
"app_access_clearall_btn": "Cancella tutti gli accessi",
"app_access_clearall_desc": "Tutti gli utenti avranno accesso a %s.",
"app_access_removeall_btn": "Rimuovi tutti gli accessi",
"app_access_removeall_desc": "Nessun utente avrà accesso a %s.",
"app_access_title": "accesso %s",
"app_debug_no_logs": "Registri dell'applicazione non disponibili",
"app_debug_tab": "Visualizzare informazioni di debug",
"app_info_access_desc": "Gruppi / utenti attualmente autorizzati ad accedere a questa applicazione:",
"app_info_debug_desc": "Visualizzare informazioni di debug per quest'applicazione.",
"app_info_default_desc": "Redirigi root dominio su questa applicazione (%s).",
"app_info_default_desc": "Redirigi root dominio su questa applicazione ({domain}).",
"app_info_uninstall_desc": "Rimuovi questa applicazione.",
"app_install_cancel": "Installazione cancellata.",
"app_install_custom_no_manifest": "Nessun file manifest.json",
"app_list": "Lista app",
"app_make_default": "Imposta predefinito",
"app_repository": "Origine dell'applicazione: ",
"app_state_validated": "Convalidato",
"application": "Applicazione",
"applications": "Applicazioni",
"archive_empty": "Archivio vuoto",
"available": "Disponibile",
"available_apps": "App disponibili",
"backup": "Backup",
"backup_action": "Backup",
"backup_archive_delete": "Elimina l'archivio",
"backup_archive_download": "Scarica questo archivio",
"backup_content": "Contenuto del backup",
"backup_create": "Creare un backup",
"backup_encryption_warning": "Non dimenticare questa password, ne avrai bisogno se vorrai ripristinare l'archivio",
"backup_new": "Nuovo backup",
"backup_optional_password": "Password facoltativa",
"backup_type": "Tipo",
"backup_warning_title": "Il sistema di backup non è ancora stato implementato.",
"backups_no": "Nessun backup",
"bit_rate": "Bit rate",
"both": "Entrambi",
"cancel": "Annulla",
"check_stmp": "accesso alla porta 25",
"close": "Chiudi",
"confirm_access_add": "Sei sicuro di voler aggiungere l'accesso a %s per tutti gli utenti ?",
"confirm_access_clear": "Sei sicuro di voler cancellare tutti gli accessi a %s ?",
"confirm_access_remove_all": "Sei sicuro di voler rimuovere tutti gli accessi a %s ?",
"confirm_access_remove_user": "Sei sicuro di voler rimuovere l'accesso a %s per %s ?",
"confirm_app_default": "Sei sicuro di voler impostare questa app come predefinita ?",
"confirm_change_maindomain": "Sei sicuro di voler cambiare il dominio principale?",
"confirm_delete": "Sei sicuro di voler eliminare %s ?",
"confirm_service_action": "Sei sicuro di voler %s %s ?",
"confirm_uninstall": "Sei sicuro di voler disinstallare %s ?",
"confirm_update_type": "Sei sicuro di voler aggiornare ogni %s ?",
"confirm_upnp_action": "Sei sicuro di voler %s UPnP ?",
"confirm_delete": "Sei sicuro di voler eliminare {name} ?",
"confirm_uninstall": "Sei sicuro di voler disinstallare {name} ?",
"connection": "Connessione",
"cpu_load": "Carico del processore",
"created_at": "Creato a",
"cumulative_usage": "Utilizzo cumulativo",
"custom_app_install": "Installa app personalizzata",
"custom_app_url_only_github": "Al momento solo da GitHub",
"default": "Predefinito",
"delete": "Elimina",
"description": "Descrizione",
"disable": "Disabilita",
"disabled": "Disattivato",
"disk": "Disco",
"domain": "Dominio",
"domain_add": "Aggiungi dominio",
"domain_add_dns_doc": "… e ho <a href='//yunohost.org/dns'>correttamente impostato il mio DNS</a>.",
"domain_add_dyndns_doc": "... e voglio un servizio DNS dinamico.",
"domain_add_panel_with_domain": "Ho già un nome di domino…",
"domain_add_panel_without_domain": "Non ho un nome di domino…",
"domain_default": "Dominio predefinito",
"domain_dns_config": "Configurazione del DNS",
"domain_list": "Lista domini",
"domain_name": "Nome a domino",
"domain_select": "Scegli dominio",
"domains": "Domini",
"download": "Scaricare",
"enable": "Abilita",
"error_modify_something": "Dovresti modificare qualcosa",
"error_occured": "Si è verificato un errore, prova di nuovo",
"error_retrieve_feed": "Non è possibile ricevere il flusso: %s. Potresti avere un plugin che non consente al tuo browser di eseguire questa richiesta (o il sito web è caduto).",
"error_select_domain": "Dovresti indicare un dominio",
"error_server": "Errore del server",
"everyone_has_access": "Tutti hanno accesso.",
"filesystem": "Filesystem",
"firewall": "Firewall",
"free": "Disponibile",
"fs_type": "FS Type",
"gateway": "Gateway: ",
"home": "Home",
"hook_adminjs_group_configuration": "Configurazioni di sistema",
"hook_conf_ldap": "Database LDAP",
@ -105,128 +51,63 @@
"hook_data_home": "Dati utente",
"hook_data_mail": "Mail",
"hook_data_mail_desc": "Mail raw presenti sul server",
"hostname": "Nome host",
"id": "ID",
"inactive": "Inattivo",
"infos": "Info",
"install": "Installa",
"install_name": "Installa %s",
"install_name": "Installa {id}",
"install_time": "Tempo installazione",
"installation_complete": "Installazione completata",
"installed": "Installato",
"installed_apps": "App installate",
"installing": "Installazione",
"interface": "Interfaccia",
"io": "I/O",
"ipv4": "IPv4",
"ipv6": "IPv6",
"label": "Etichetta",
"label_for_manifestname": "Etichetta per %s",
"loading": "Caricamento …",
"local_ip": "IP locale",
"log": "Log",
"logged_in": "Connesso",
"logged_out": "Disconnesso",
"label_for_manifestname": "Etichetta per {name}",
"login": "Accedi",
"logout": "Esci",
"mailbox_quota_description": "Per esempio, 700M è un CD, 4700M è un DVD.",
"manage_apps": "Gestisci app",
"manage_domains": "Gestisci domini",
"manage_users": "Gestisci utenti",
"memory": "Memoria",
"menu": "Menù",
"mode": "Modalità",
"monitoring": "Monitoraggio",
"monitoring_check_glances": "Controlla lo stato del servizio <a href='#/services/glances'>glances</a>.",
"monitoring_disabled": "Il monitoraggio non è attivo.",
"mount_point": "Punto di montaggio",
"multi_instance": "Istanze multiple",
"myserver": "mioserver",
"myserver_org": "mioserver.org",
"network": "Rete",
"next": "Successivo",
"no": "No",
"no_allowed_users": "Nessun utente permesso.",
"no_installed_apps": "Nessuna app installata.",
"no_log": "Nessun log.",
"no_user_to_add": "Nessun altro utente da aggiungere.",
"non_compatible_api": "API non-compatibile",
"open": "Apri",
"operations": "Operazioni",
"os": "OS",
"password": "Password",
"password_confirmation": "Conferma password",
"password_description": "La password deve essere lunga almeno %s caratteri.",
"password_empty": "Il campo password è vuoto",
"password_new": "Nuova password",
"passwords_dont_match": "Le password non corrispondono",
"passwords_too_short": "La password è troppo corta",
"path": "Percorso",
"port": "Porta",
"ports": "Porte",
"postinstall": "Post-installazione",
"postinstall_intro_1": "Congratulazioni! YunoHost è stato installato con successo.",
"postinstall_password": "Questa password sarà usata per gestire tutto sul tuo server. Prenditi un attimo per sceglierla con attenzione.",
"previous": "Precedente",
"protocol": "Protocollo",
"public_ip": "IP pubblico: ",
"ram": "RAM",
"read": "Lettura",
"read_more": "Leggi altro",
"reception": "Ricezione",
"refresh_app_list": "Aggiorna lista",
"remove_access": "Rimuovi accesso",
"restore": "Ripristina",
"save": "Salva",
"select_user": "Scegli utente",
"service_log": "%s log",
"service_start_on_boot": "In esecuzione all'avvio",
"service_status": "Stato: ",
"services": "Servizi",
"services_list": "Lista dei servizi",
"set_default": "Imposta predefinito",
"size": "Dimensione",
"start": "Avvia",
"status": "Stato",
"stop": "Arresta",
"storages_new": "Nuovo supporto di memoria remoto",
"swap": "Swap",
"system": "Sistema",
"system_apps": "App",
"system_apps_nothing": "Tutte le applicazioni sono aggiornate!",
"system_delayed_upgrade": "Aggiornamento rimandato",
"system_delayed_upgrade_warning": "<b>%s</b> sarà aggiornato automaticamente entro un'ora.",
"system_packages": "Pacchetti",
"system_packages_nothing": "Tutti i pacchetti di sistema sono aggiornati!",
"system_upgrade": "Aggiornamento del sistema",
"system_upgrade_btn": "Aggiorna",
"tcp": "TCP",
"time_since_update": "Tempo dall'ultimo aggiornamento: ",
"tools": "Strumenti",
"tools_adminpw": "Cambia password amministrazione",
"tools_adminpw_confirm_placeholder": "Conferma la nuova password",
"tools_adminpw_current": "Password attuale",
"tools_adminpw_current_placeholder": "Inserisci la tua attuale password",
"tools_adminpw_new_placeholder": "Inserisci la nuova password",
"tools_security_feed": "Notifiche di sicurezza",
"tools_security_feed_no_items": "Nessuna notifica di sicurezza",
"tools_security_feed_subscribe_rss": "Sottoscrivi RSS di notifiche di sicurezza",
"tools_security_feed_view_items": "Visualizza tutte le notifiche di sicurezza",
"total": "Totale",
"transmission": "Trasmissione",
"udp": "UDP",
"unauthorized": "Non autorizzato",
"uninstall": "Disinstalla",
"unknown_action": "Azione sconosciuta %s",
"unknown_argument": "Argomenti sconosciuti : %s",
"upload": "Caricare",
"upnp": "UPnP",
"upnp_disabled": "UPnP è disabilitato.",
"upnp_enabled": "UPnP è abilitato.",
"uptime": "Uptime",
"url": "URL",
"usage": "Utilizzato",
"used": "Usato",
"user_email": "Email",
"user_emailaliases": "Alias email",
"user_emailforward": "Inoltro email",
@ -234,49 +115,33 @@
"user_interface_link": "Interfaccia utente",
"user_mailbox_quota": "Quota della casella di posta",
"user_new_forward": "nuovoinoltro@miodominiodifferente.org",
"user_new_mail": "nuovaemail@miodominio.org",
"user_username": "Nome utente",
"user_username_edit": "Modifica account di %s",
"user_username_edit": "Modifica account di {name}",
"users": "Utenti",
"users_list": "Lista utenti",
"users_new": "Nuovo utente",
"users_no": "Nessun utente.",
"view_user_profile": "Vedi il profilo di %s",
"warning_first_user": "Probabilmente dovresti <a href='#/users/create' class='alert-link'>creare un utente</a> prima.",
"write": "Scrittura",
"wrong_password": "Password sbagliata",
"yes": "Si",
"app_state": "Stato dell'applicazione: ",
"app_state_inprogress": "ancora non funzionante",
"confirm_install_custom_app": "ATTENZIONE! L'installazione di applicazioni di terze parti può compromettere l'integrità e la sicurezza del tuo sistema. Probabilmente NON dovresti installarle a meno che tu non sappia cosa stai facendo. Sei sicuro di volerti prendere questo rischio?",
"backup_archive_copy": "Copia questo archivio in un altro supporto di memoria",
"confirm_install_domain_root": "Non sarai in grado di installare qualsiasi altra applicazione su %s. Continuare ?",
"confirm_install_domain_root": "Non sarai in grado di installare qualsiasi altra applicazione su {domain}. Continuare ?",
"app_state_notworking": "non funzionante",
"app_state_working": "funzionante",
"backup_experimental_warning": "Nota: la funzione backup è ancora sperimentale e potrebbe non essere completamente affidabile.",
"backup_optional_encryption": "Cifratura opzionale",
"begin": "Iniziamo",
"check": "Verifica",
"confirm_firewall": "Sei sicuro di %s la porta %s (protocollo: %s, connessione: %s)",
"confirm_postinstall": "Stai per lanciare il processo di post-installazione sul dominio %s. Potrebbe richiedere alcuni minuti, *non interrompere l'operazione*.",
"confirm_restore": "Sei sicuro di volere ripristinare %s ?",
"copy": "Copia",
"count_min": "%s min",
"confirm_postinstall": "Stai per lanciare il processo di post-installazione sul dominio {domain}. Potrebbe richiedere alcuni minuti, *non interrompere l'operazione*.",
"confirm_restore": "Sei sicuro di volere ripristinare {name} ?",
"diagnosis": "Diagnosi",
"diagnosis_hide_private": "Mostra informazioni diagnostiche senza dati privati",
"diagnosis_view_private": "Mostra informazioni diagnostiche includendo dati privati",
"diagnosis_with_private": "Diagnostica con dati privati",
"dns": "DNS",
"domain_default_desc": "Il dominio predefinito è il dominio di connessione dove gli utenti effettuano l'accesso.",
"domain_default_longdesc": "Questo è il tuo dominio predefinito.",
"domain_delete_longdesc": "Rimuovi questo dominio",
"domain_dns_longdesc": "Vedi la configurazione DNS",
"domain_visit": "Visita",
"domain_visit_url": "Visita %s",
"enabled": "Attivato",
"error_server_unexpected": "Errore server inaspettato (%s)",
"footer_version": "Offerto da <a href='https://yunohost.org'>YunoHost</a> %s (%s).",
"form_input_example": "Esempio: %s",
"domain_visit_url": "Visita {url}",
"error_server_unexpected": "Errore server inaspettato",
"footer_version": "Offerto da <a href='https://yunohost.org'>YunoHost</a> {version} ({repo}).",
"form_input_example": "Esempio: {example}",
"hook_conf_cron": "Operazioni automatiche",
"hook_conf_ynh_certs": "Certificati SSL",
"hook_conf_ynh_mysql": "Password MySQL",
@ -286,54 +151,34 @@
"postinstall_domain": "Questo è il primo nome di dominio collegato al tuo server Yunohost, ma anche quello che verrà usato dagli utenti del tuo server per accedere al portale di autenticazione. Di conseguenza sarà visibile da tutti, perciò sceglilo con attenzione.",
"postinstall_intro_2": "Sono richiesti ancora due passi da configurare per attivare i servizi del tuo server.",
"postinstall_intro_3": "Puoi ottenere ulteriori informazioni visitando la <a href='//yunohost.org/postinstall' target='_blank'>pagina appropriata nella documentazione</a>",
"process": "Procedi",
"running": "In esecuzione",
"storage_create": "Aggiungi un supporto di memoria remoto",
"storages_no": "Nessun supporto di memoria.",
"system_update": "Aggiornamento del sistema",
"tools_download_ca": "Scarica il Certificato di Autorità SSL (CA)",
"tools_download_ca_desc": "Clicca per scaricare il tuo Certificato di Autorità SSL (CA)",
"upload_archive": "Caricamento dell'archivio",
"check_mx": "Record MX",
"user_mailbox_use": "Spazio utilizzato dalla casella di posta",
"versions": "Versioni",
"certificate_alert_not_valid": "CRITICO: il certificato attuale non è valido ! L'HTTPS non funzionerà per niente !",
"certificate_alert_selfsigned": "ATTENZIONE: il certificato attuale è auto-firmato. I browser mostreranno un avvertimento ai nuovi visitatori !",
"ok": "OK",
"active": "Attivo",
"remove": "Rimuovere",
"app_change_label": "Cambia Etichetta",
"app_change_url": "Cambia URL",
"app_info_changelabel_desc": "Cambia l'etichetta dell'applicazione dal portale.",
"app_info_changeurl_desc": "Cambia l'URL di accesso di questa applicazione (dominio e/o percorso).",
"app_info_change_url_disabled_tooltip": "Questa funzionalità non è ancora stata implementata in questa applicazione",
"confirm_app_change_url": "Sei sicuro di voler cambiare l'URL di accesso all'applicazione ?",
"confirm_firewall_open": "Sei sicuro di voler aprire la porta %s? (protocollo: %s, connessione: %s)",
"confirm_firewall_close": "Sei sicuro di voler chiudere la porta %s? (protocollo: %s, connessione: %s)",
"confirm_firewall_open": "Sei sicuro di voler aprire la porta {port}? (protocollo: {protocol}, connessione: {connection})",
"confirm_firewall_close": "Sei sicuro di voler chiudere la porta {port}? (protocollo: {protocol}, connessione: {connection})",
"confirm_migrations_skip": "Saltare le migrazioni è sconsigliato. Sei sicuro di volerlo fare?",
"confirm_service_start": "Sei sicuro di voler eseguire %s?",
"confirm_service_stop": "Sei sicuro di voler fermare %s?",
"confirm_service_enable": "Sei sicuro di voler abilitare %s?",
"confirm_service_disable": "Sei sicuro di voler disabilitare %s?",
"confirm_service_start": "Sei sicuro di voler eseguire {name}?",
"confirm_service_stop": "Sei sicuro di voler fermare {name}?",
"confirm_update_apps": "Sei sicuro di voler aggiornare tutte le applicazioni?",
"confirm_update_packages": "Sei sicuro di voler aggiornare tutti i pacchetti?",
"confirm_update_specific_app": "Sei sicuro di voler aggiornare %s?",
"confirm_update_specific_app": "Sei sicuro di voler aggiornare {app}?",
"confirm_upnp_enable": "Sei sicuro di voler abilitare UPnP?",
"confirm_upnp_disable": "Sei sicuro di voler disabilitare UPnP?",
"confirm_reboot_action_reboot": "Sei sicuro di voler riavviare il tuo server?",
"confirm_reboot_action_shutdown": "Sei sicuro di voler spegnere il tuo server?",
"domain_dns_conf_is_just_a_recommendation": "Questa pagina ti mostra la configurazione *raccomandata*. *Non* configura il DNS per te. Configurare le tue zone DNS e il registrar DNS in accordo con queste raccomandazioni è compito tuo.",
"internal_exception": "<strong>Si è verificato un errore interno a Yunohost :/</strong><br><em>Ci dispiace molto per questo.<br>Prova a dare un'occhiata sul <a href=\"https://forum.yunohost.org/\">forum</a> o sulla <a href=\"https://chat.yunohost.org/\">chat</a> per trovare una soluzione, o segnala il problema sul <a href=\"https://github.com/YunoHost/issues\">bugtracker</a>.</em><br>Le seguenti informazioni possono essere utili per le persone che ti aiuteranno :<h3>Action</h3><pre>%s%s</pre><h3>Traceback</h3><pre>%s</pre>",
"migrations": "Migrazioni",
"migrations_pending": "Migrazioni in attesa",
"migrations_done": "Migrazioni precedenti",
"migrations_no_pending": "Nessuna migrazione in attesa",
"migrations_no_done": "Nessuna migrazione precedente",
"path_url": "Percorso",
"run": "Esegui",
"service_description": "Descrizione:",
"skip": "Salta",
"started_at": "Avviato a:",
"system_upgrade_all_applications_btn": "Aggiorna tutte le applicazioni",
"system_upgrade_all_packages_btn": "Aggiorna tutti i pacchetti",
"tools_reboot": "Riavvia il tuo server",
@ -358,15 +203,6 @@
"validity": "Validità",
"install_letsencrypt_cert": "Installa un certificato Let's Encrypt",
"manually_renew_letsencrypt": "Rinnova manualmente ora",
"appslists": "Liste di applicazioni",
"appslists_no_lists": "Nessuna lista di applicazioni",
"appslists_custom": "Lista di applicazioni personalizzata",
"appslists_manage": "Gestisci liste di applicazioni",
"appslists_last_update": "Ultimo aggiornamento",
"appslists_unknown_list": "Lista di applicazioni sconosciuta: %s",
"appslists_community_list": "Lista di applicazioni della comunità",
"name": "Nome",
"certificate_old_letsencrypt_app_conflict": "L'applicazione 'letsencrypt' è attualmente installata ed è in conflitto con questa funzionalità. Per favore prima disinstalla questa per usare la nuova interfaccia di gestione dei certificati.",
"confirm_cert_install_LE": "Sei sicuro di voler installare un certificato Let's Encrypt per questo dominio ?",
"confirm_cert_regen_selfsigned": "Sei sicuro di voler rigenerare un certificato autofirmato per questo dominio ?",
"confirm_cert_manual_renew_LE": "Sei sicuro di voler rinnovare manualmente il certificato Let's Encrypt per questo dominio ora ?",
@ -374,31 +210,18 @@
"domain_is_eligible_for_ACME": "Questo dominio sembra correttamente configurato per l'installazione di un certificato Let's Encrypt !",
"domain_not_eligible_for_ACME": "Questo dominio non sembra pronto per un certificato Let's Encrypt. Per favore controlla la tua configurazione DNS e la raggiungibilità del tuo server HTTP. Le sezioni 'DNS records' e 'Web' nella <a href='#/diagnosis'>pagina di diagnosi</a> può aiutarti nel capire cosa non è ben configurato.",
"manually_renew_letsencrypt_message": "Il certificato sarà rinnovato automaticamente durante gli ultimi 15 giorni di validità. Puoi rinnovarlo manualmente se lo desideri (Non consigliato).",
"meltdown": "Sei esposto alla vulnerabilità critica di sicurezza <a target=\"_blank\" href=\"https://meltdownattack.com/\">meltdown</a>. Per risolverlo, hai bisogno di <a href=\"#/update\">aggiornare il tuo sistema</a> e successivamente <a href=\"#/tools/reboot\">riavviarlo</a> per caricare il nuovo kernel linux.",
"regenerate_selfsigned_cert_message": "Se lo desideri, puoi rigenerare il certificato autofirmato.",
"regenerate_selfsigned_cert": "Rigenera il certificato autofirmato",
"revert_to_selfsigned_cert_message": "Se lo desideri veramente, puoi reinstallare un certificato autofirmato. (Non consigliato)",
"revert_to_selfsigned_cert": "Ritorna ad un certificato autofirmato",
"appslists_confirm_remove": "Sei sicuro di voler rimuovere questa lista di applicazioni?",
"appslists_info_refresh_desc": "Aggiorna gli stati delle applicazioni per questa lista.",
"appslists_info_remove_desc": "Le applicazioni contenute in questa lista non saranno più disponibili.",
"install_community_appslists_info": "La lista delle applicazioni della comunità ti consente di installare le applicazioni mantenute dalla comunità.<br />Vedi la lista completa su <a href='https://yunohost.org/apps_in_progress'>yunohost.org/apps_in_progress</a>.",
"install_community_appslists_warning": "Tieni presente che questi pacchetti di applicazioni <strong>non</strong> sono ufficiali e non sono mantenuti dalla team di YunoHost.<br />Installare queste applicazioni è a tuo rischio e può danneggiare il tuo sistema.",
"install_custom_app_appslists_info": "Tieni presente che puoi usare liste alternative di applicazioni per installare altre applicazioni mantenute dalla comunità di YunoHost.",
"all_apps": "Tutte le app",
"app_license": "Licenza dell'app",
"app_level": "Livello dell'app",
"app_no_actions": "Questa applicazione non ha nessuna azione",
"app_state_official": "Ufficiale",
"confirm_install_app_warning": "Attenzione: questa applicazione può funzionare ma non è ben integrata in Yunohost. Alcune funzionalità come il single sign-on (accesso unico) e backup/ripristino potrebbero non essere disponibili.",
"confirm_install_app_danger": "ATTENZIONE! Questa applicazione è ancora sperimentale (se non esplicitamente non funzionante) ed è probabile che rovini il tuo sistema! Probabilmente NON dovresti installarla a meno che tu non sappia cosa stai facendo. Sei sicuro di voler prenderti questo rischio?",
"current_maintainer_title": "Mantenitore attuale di questo pacchetto",
"error_connection_interrupted": "Il server ha chiuso la connessione invece che rispondere. Probabilmente nginx o le API di YunoHost sono stato riavviati per qualche ragione? (Codice di errore/messaggio: %s)",
"confirm_install_app_lowquality": "Attenzione: questa applicazione può funzionare ma non è ben integrata in Yunohost. Alcune funzionalità come il single sign-on (accesso unico) e backup/ripristino potrebbero non essere disponibili.",
"confirm_install_app_inprogress": "ATTENZIONE! Questa applicazione è ancora sperimentale (se non esplicitamente non funzionante) ed è probabile che rovini il tuo sistema! Probabilmente NON dovresti installarla a meno che tu non sappia cosa stai facendo. Sei sicuro di voler prenderti questo rischio?",
"error_connection_interrupted": "Il server ha chiuso la connessione invece che rispondere. Probabilmente nginx o le API di YunoHost sono stato riavviati per qualche ragione?",
"experimental_warning": "Attenzione: questa funzionalità è sperimentale e non è considerata stabile, non dovresti utilizzarla a meno che tu non sappia cosa stai facendo.",
"good_practices_about_admin_password": "Ora stai per impostare una nuova password di amministratore. La password dovrebbe essere di almeno 8 caratteri - anche se è buona pratica utilizzare password più lunghe (es. una sequenza di parole) e/o utilizzare vari tipi di caratteri (maiuscole, minuscole, numeri e simboli).",
"good_practices_about_user_password": "Ora stai per impostare una nuova password utente. La password dovrebbe essere di almeno 8 caratteri - anche se è buona pratica utilizzare password più lunghe (es. una sequenza di parole) e/o utilizzare vari tipi di caratteri (maiuscole, minuscole, numeri e simboli).",
"level": "livello",
"only_official_apps": "Solo app ufficiali",
"only_working_apps": "Solo app funzionanti",
"logs": "Registri",
"logs_operation": "Operazioni fatte sul sistema con YunoHost",
@ -409,7 +232,6 @@
"logs_service": "Registri dei servizi",
"logs_app": "Registri delle app",
"logs_no_logs_registered": "Nessun registro associato a questa categoria",
"logs_end_with_error": "Questo registro è terminato con un errore:",
"logs_error": "Errore",
"logs_ended_at": "Fine",
"logs_started_at": "Inizio",
@ -417,18 +239,17 @@
"logs_context": "Contesto",
"logs_share_with_yunopaste": "Condividi con YunoPaste",
"logs_more": "Mostra più linee",
"search_for_apps": "Cerca app...",
"select_all": "Seleziona tutto",
"select_none": "Deseleziona tutto",
"unmaintained": "Non mantenuta",
"version": "Versione",
"purge_user_data_checkbox": "Eliminare i dati di %s? (Questo rimuoverà il contenuto delle sue cartelle home e mail.)",
"purge_user_data_checkbox": "Eliminare i dati di {name}? (Questo rimuoverà il contenuto delle sue cartelle home e mail.)",
"purge_user_data_warning": "L'eliminazione dei dati utente non è annullabile. Assicurati di sapere cosa stai facendo!",
"hook_conf_ynh_currenthost": "Dominio principale attuale",
"confirm_update_system": "Sei sicuro di voler aggiornare tutti i pacchetti di sistema?",
"app_state_inprogress_explanation": "Questo maintainer di questa applicazione ha dichiarato che l'applicazione non è ancora pronta per l'uso in produzione. ATTENZIONE!",
"app_state_notworking_explanation": "Questo maintainer di questa applicazione ha dichiarato che \"non funziona\". SI ROMPERÀ IL VOSTRO SISTEMA!",
"app_state_high-quality": "alta qualità",
"app_state_highquality": "alta qualità",
"group_add_permission": "Aggiungere un permesso",
"group_explain_all_users": "Questo è un gruppo speciale contenente tutti gli account di tutti gli utenti sul server",
"group": "Gruppo",
@ -437,25 +258,22 @@
"group_visitors": "Visitori",
"group_format_name_help": "È possibile utilizzare caratteri alfanumerici e spazio",
"group_add_member": "Aggiungere un utente",
"app_state_high-quality_explanation": "Questa applicazione è ben integrata con YunoHost. È stata (ed è!) peer-reviewed dal team di YunoHost app. Ci si può aspettare che sia sicura e mantenuta a lungo termine.",
"app_state_highquality_explanation": "Questa applicazione è ben integrata con YunoHost. È stata (ed è!) peer-reviewed dal team di YunoHost app. Ci si può aspettare che sia sicura e mantenuta a lungo termine.",
"details": "Dettagli",
"diagnosis_experimental_disclaimer": "Siate consapevoli che la funzione di diagnosi è ancora sperimentale e in fase di perfezionamento, e potrebbe non essere completamente affidabile.",
"errors": "%s errori",
"everything_good": "Tutto bene!",
"from_to": "da %s a %s",
"from_to": "da {0} a {1}",
"configuration": "Configuratione",
"advanced": "Avanzate",
"app_state_working_explanation": "Il manutentore di questa applicazione lo ha dichiarato \"funzionante\". Significa che dovrebbe essere funzionale (c.f. livello di applicazione) ma non è necessariamente sottoposta a peer-reviewing, può ancora contenere problemi o non è pienamente integrata con YunoHost.",
"group_new": "Nuovo gruppo",
"warnings": "%s avvisi",
"warnings": "{count} avvisi",
"words": {
"default": "Predefinito"
},
"unmaintained_details": "Questa applicazione non è stata aggiornata da tempo e il mantainer precedente se n'è andato oppure non ha più tempo per manutenerla. Potresti controllare il repository per dare il tuo aiuto",
"unignore": "Non ignorare più",
"since": "da",
"restart": "Riavvia",
"request_help_details": "ll mantainer attuale vorrebbe un po' di aiuto nella manutenzione di questa applicazione. Potresti contribuire!",
"request_help": "necessita aiuto",
"request_adoption_details": "Il mantainer attuale vorrebbe smettere di manutenere questa applicazione. Potresti proporti come nuovo mantainer!",
"request_adoption": "in attesa di adozione",
"rerun_diagnosis": "Riavvia la diagnostica",
"operation_failed_explanation": "Questa operazione è fallita! Siamo spiacenti :( Puoi provare a <a href='https://yunohost.org/help'>chiedere aiuto</a>. Sei pregato di fornire *il log completo* dell'operazione alle persone che ti aiuteranno. Per farlo clicca sul bottone verde 'Condividi con Yunopaste'. Quando condividi i log YunoHost cercherà automaticamente di renderli anonimi eliminando dati privato come nomi di dominio e IP.",
"others": "Altre",
@ -464,35 +282,30 @@
"only_decent_quality_apps": "Solo applicazioni di qualità decente",
"only_highquality_apps": "Solo applicazioni di alta qualità",
"nobody": "Nessuno",
"maintained_details": "Questa applicazione è stata manutenuta dal suo mantainer negli ultimi mesi.",
"maintained": "mantenuta",
"license": "Licenza",
"last_ran": "Ultima esecuzione:",
"issues": "%s problemi",
"ignored": "%s ignorato",
"issues": "{count} problemi",
"ignored": "{count} ignorato",
"ignore": "Ignora",
"permissions": "Permessi",
"groups_and_permissions_manage": "Gestisci i gruppi e i permessi",
"groups_and_permissions": "Gruppi e permessi",
"groups": "Gruppi",
"group_specific_permissions": "Permessi specifici per l'utente",
"group_explain_visitors_needed_for_external_client": "Poni attenzione al fatto che dovrai dare l'accesso ai visitatori ad alcune applicazioni se pensi di usarle con dei client esterni. Ad esempio questo è il caso di Nextcloud nel caso tu lo voglia usare con un client di sincronizzazione dal tuo smartphone o dal computer desktop.",
"group_explain_visitors": "Questo è un gruppo speciale che individua i visitatori anonimi",
"run_first_diagnosis": "Avvio diagnosi iniziali",
"diagnosis_explanation": "La funzione di diagnosi cercherà di identificare problemi comuni nei differenti aspetti del tuo server per essere sicuri che tutto funzioni correttamente. La diagnosi si avvia automaticamente due volte al giorno e un email viene inviata all'amministratore se vengono identificati dei problemi. Nota che alcuni test possono non essere rilevanti se non vuoi usare alcune specifiche funzionalità (come ad esempio XMPP) oppure potrebbero fallire sei hai un setup complesso. In questi casi, se sai quello che stai facendo, puoi ignorare questi problemi o avvisi.",
"diagnosis_first_run": "La funzione di diagnosi cercherà di identificare problemi comuni nei differenti aspetti del tuo server per essere sicuri che tutto funzioni correttamente. Sei invitato a non farti prendere dal panico nel caso vengano indicati molti errori dopo la prima installazione del tuo server perché questa funzione cerca di aiutarti ad identificare i problemi e guidarti nella loro soluzione. La diagnosi inoltre si avvierà automaticamente due volte al giorno e un email verrà inviata all'amministratore se vengono identificati dei problemi.",
"confirm_service_restart": "Sei sicuro di voler riavviare %s?",
"confirm_service_restart": "Sei sicuro di voler riavviare {name}?",
"catalog": "Catalogo",
"app_state_low_quality_explanation": "Questa applicazione può essere funzionale ma potrebbe presentare dei problemi oppure non essere pienamente integrata con YunoHost oppure non rispettare le pratiche consigliate.",
"app_state_low_quality": "bassa qualità",
"app_state_lowquality_explanation": "Questa applicazione può essere funzionale ma potrebbe presentare dei problemi oppure non essere pienamente integrata con YunoHost oppure non rispettare le pratiche consigliate.",
"app_state_lowquality": "bassa qualità",
"all": "Tutti",
"pending_migrations": "Ci sono alcune migrazioni in sospeso in attesa di essere eseguite. Consulta <a href='#/tools/migrations'>Tools > Migrations</a> per visualizzarle.",
"tip_about_user_email": "Gli utenti sono creati associati ad un indirizzo email (e un account XMPP) del tipo utente@domain.tld. Indirizzi email addizionali e forward possono essere aggiunti successivamente dall'amministratore e dall'utente.",
"log_suboperations": "Sub-operazioni",
"logs_suboperations": "Sub-operazioni",
"permission_show_tile_enabled": "Mostra il tile nel portale dell'utente",
"permission_main": "Permesso principale",
"permission_corresponding_url": "URL corrispondente",
"app_manage_label_and_tiles": "Gestisci etichette e tiles",
"app_info_managelabel_desc": "Gestisci i permessi nel portale.",
"apply": "Applica"
"app_manage_label_and_tiles": "Gestisci etichette e tiles"
}

View file

@ -1,9 +1,6 @@
{
"cancel": "Avbryt",
"login": "Logg inn",
"ok": "OK",
"logout": "Logg ut",
"logged_out": "Utlogget",
"logged_in": "Innlogget",
"password": "Passord"
}

View file

@ -2,60 +2,37 @@
"configuration": "कन्फिगरेसन",
"close": "बन्द",
"check": "जाँच गर्नुहोस्",
"cancel": "रद्द गर्नुहोस्",
"both": "दुबै",
"begin": "सुरु गर्नुहोस्",
"backups_no": "कुनै ब्याकअप छैन",
"backup_type": "प्रकार",
"backup_optional_password": "वैकल्पिक पासवर्ड",
"backup_optional_encryption": "वैकल्पिक ईन्क्रिप्शन",
"backup_new": "नयाँ ब्याकअप",
"backup_encryption_warning": "यस पासवर्डलाई नबिर्सनुहोस्, यदि तपाईंलाई संग्रह पुनःबहाली चाहानुहुन्छ भने तपाईंलाई यसको आवश्यक पर्दछ",
"backup_create": "ब्याकअप सिर्जना गर्नुहोस्",
"backup_content": "सामग्री ब्याकअप",
"backup_archive_download": "यो संग्रह डाउनलोड गर्नुहोस्",
"backup_archive_delete": "यो संग्रह मेट्नुहोस्",
"backup_archive_copy": "यस संग्रहलाई अर्को भण्डारणमा प्रतिलिपि गर्नुहोस्",
"backup_action": "ब्याकअप",
"backup": "ब्याकअप",
"available_apps": "उपलब्ध अनुप्रयोगहरू",
"app_info_access_desc": "समूह / प्रयोगकर्ताहरूले हाल यो अनुप्रयोग पहुँच गर्न अनुमति दिइएको:",
"advanced": "बिकसित",
"archive_empty": "खाली अभिलेख",
"applications": "अनुप्रयोगहरू",
"application": "अनुप्रयोग",
"app_state_working": "काम गर्दै",
"app_state_high-quality": "उच्च गुणस्तर",
"app_state_low_quality_explanation": "यो अनुप्रयोग कार्यात्मक हुन सक्छ, तर अझै पनी मुद्दाहरू समावेश हुन सक्छ, वा YunoHost संग पूर्ण एकीकृत छैन, वा यसले राम्रो अभ्यासहरूको सम्मान गर्दैन।",
"app_state_low_quality": "कम गुणस्तर",
"app_state_highquality": "उच्च गुणस्तर",
"app_state_lowquality_explanation": "यो अनुप्रयोग कार्यात्मक हुन सक्छ, तर अझै पनी मुद्दाहरू समावेश हुन सक्छ, वा YunoHost संग पूर्ण एकीकृत छैन, वा यसले राम्रो अभ्यासहरूको सम्मान गर्दैन।",
"app_state_lowquality": "कम गुणस्तर",
"app_state_notworking_explanation": "यस अनुप्रयोगको मर्मतकर्ताले यसलाई 'काम गरिरहेको छैन' भनेर घोषणा गर्‍यो। यसले तपाईंको प्रणाली बिगार्न सक्छ !",
"app_state_notworking": "काम गरिरहेको छैन",
"app_state_inprogress_explanation": "यस अनुप्रयोगको मर्मतकर्ताले घोषणा गर्‍यो कि यो अनुप्रयोग उत्पादन प्रयोगको लागि अझै तयार छैन। होस् गर!",
"app_state_inprogress": "अहिले सम्म काम गरिरहेको छैन",
"app_state": "अनुप्रयोग अवस्था: ",
"app_repository": "अनुप्रयोग मूल: ",
"app_no_actions": "यस अनुप्रयोगसँग कुनै कार्यहरू छैन",
"app_make_default": "पूर्वनिर्धारित बनाउनुहोस्",
"app_level": "अनुप्रयोग स्तर",
"app_install_custom_no_manifest": "manifest.json छैन",
"app_install_cancel": "स्थापना रद्द गरियो।",
"app_info_uninstall_desc": "यस अनुप्रयोग हटाउनुहोस्।",
"app_info_change_url_disabled_tooltip": "यो सुविधा यस अनुप्रयोगमा अहिलेसम्म कार्यान्वयन भएको छैन",
"app_info_changeurl_desc": "यस अनुप्रयोगको पहुँच यूआरएल परिवर्तन गर्नुहोस् (डोमेन र / वा मार्ग)।",
"app_info_default_desc": "यस (%s) अनुप्रयोगमा डोमेन रूटलाई पुनःनिर्देशित गर्नुहोस्।",
"app_info_debug_desc": "यस अनुप्रयोगको लागि Debugging जानकारी प्रदर्शन गर्नुहोस्।",
"app_info_changelabel_desc": "पोर्टलमा अनुप्रयोग लेबल बदल्नुहोस्।",
"app_change_url": "URL परिवर्तन गर्नुहोस्",
"app_change_label": "लेबल परिवर्तन गर्नुहोस्",
"app_info_default_desc": "यस ({domain}) अनुप्रयोगमा डोमेन रूटलाई पुनःनिर्देशित गर्नुहोस्।",
"api_not_responding": "YunoHost API ले प्रतिक्रिया गरीरहेको छैन। हुनसक्छ 'Yunohost API' बन्द छ वा पुनः सुरु भयो ?",
"all_apps": "सबै अनुप्रयोगहरू",
"all": "सबै",
"administration_password": "प्रशासन पासवर्ड",
"remove": "हटाउनुहोस्",
"add": "थप्नुहोस्",
"active": "सक्रिय",
"action": "कार्य",
"password": "पासवर्ड",
"ok": "ठिक छ",
"logged_out": "लग आउट"
"ok": "ठिक छ"
}

View file

@ -0,0 +1,159 @@
{
"action": "Actie",
"add": "Toevoegen",
"administration_password": "Beheerderswachtwoord",
"api_not_responding": "De YunoHost API reageert niet. De 'yunohost-api' is misschien stuk of werd herstart?",
"app_info_access_desc": "Groepen/gebruikers die op dit ogenblik toegang hebben tot deze applicatie:",
"app_info_default_desc": "Domeinnaam wortel (root) doorverwijzen naar deze applicatie ({domain}).",
"app_info_uninstall_desc": "Deze applicatie verwijderen.",
"app_install_custom_no_manifest": "Geen manifest.json file",
"app_make_default": "Als standaard instellen",
"applications": "Applicaties",
"archive_empty": "Leeg archief",
"backup": "Back-up",
"backup_action": "Backup",
"backup_content": "Backupinhoud",
"backup_create": "Creëer een backup",
"backup_new": "Nieuwe backup",
"begin": "Beginnen",
"both": "Beide",
"check": "Controleer",
"close": "Sluiten",
"confirm_app_default": "Ben je zeker dat je dit de standaardapplicatie wil maken?",
"confirm_change_maindomain": "Ben je zeker dat je de domeinnaam wil wijzigen?",
"confirm_delete": "Ben je zeker dat je {name} wil verwijderen?",
"confirm_install_custom_app": "Applicaties van derden installeren kan de veiligheid van je systeem in gevaar brengen. Gebruik op eigen risico.",
"confirm_install_domain_root": "Het zal niet meer mogelijk zijn om een andere app te installeren op {domain}. Verdergaan?",
"confirm_postinstall": "Je gaat zo het post-installatieproces starten op domein {domain}. Dit kan enkele minuten duren, *onderbreek het proces niet*.",
"confirm_restore": "Weet je zeker dat je {name} wilt herstellen?",
"confirm_uninstall": "Ben je zeker dat je de installatie van {name} ongedaan wilt maken?",
"connection": "Verbinding",
"created_at": "Gemaakt op",
"custom_app_install": "Eigen app installeren",
"custom_app_url_only_github": "Momenteel enkel van GitHub",
"delete": "Verwijderen",
"description": "Beschrijving",
"disable": "Uitschakelen",
"domain_add": "Domeinnaam toevoegen",
"domain_add_dns_doc": "... en ik heb <a href='//yunohost.org/dns'>mijn DNS correct ingesteld</a>.",
"domain_add_dyndns_doc": "... en ik wil een dynamische DNS-dienst (Dynamic DNS).",
"domain_add_panel_with_domain": "Ik heb al een domeinnaam…",
"domain_add_panel_without_domain": "Ik heb nog geen domeinnaam…",
"domain_default_desc": "De standaarddomeinnaam is de domeinnaam via dewelke gebruikers inloggen.",
"domain_name": "Domeinnaam",
"domains": "Domeinnamen",
"download": "Download",
"enable": "Inschakelen",
"error_modify_something": "Je moet iets wijzigen",
"firewall": "Firewall",
"home": "Thuis",
"hook_adminjs_group_configuration": "Configuratie",
"hook_conf_cron": "Reguliere taken",
"hook_conf_ldap": "LDAP",
"hook_conf_nginx": "Nginx",
"hook_conf_ssh": "SSH",
"hook_conf_ssowat": "SSOwat",
"hook_conf_xmpp": "XMPP",
"hook_conf_ynh_certs": "Beveiligingscertificaten",
"hook_conf_ynh_firewall": "Firewall",
"hook_conf_ynh_mysql": "MySQL wachtwoord",
"hook_data_home": "Gebruikersgegevens",
"hook_data_home_desc": "Gebruikersdata gelegen in /home/USER",
"hook_data_mail": "Post",
"hook_data_mail_desc": "Post op de server",
"id": "ID",
"infos": "Informatie",
"install": "Installeren",
"install_name": "Installeer {id}",
"install_time": "Installatietijd",
"installation_complete": "Installatie voltooid",
"installed": "Geïnstalleerd",
"ipv4": "IPv4",
"ipv6": "IPv6",
"label": "Label",
"label_for_manifestname": "Label voor {name}",
"local_archives": "Lokale archieven",
"login": "Inloggen",
"logout": "Uitloggen",
"mailbox_quota_description": "",
"manage_apps": "Apps beheren",
"manage_domains": "Domeinnamen beheren",
"manage_users": "Gebruikers beheren",
"multi_instance": "Meerdere instanties",
"myserver": "mijnserver",
"next": "Volgende",
"no": "No",
"open": "Openen",
"operations": "Operaties",
"password": "Wachtwoord",
"password_confirmation": "Bevestiging wachtwoord",
"path": "Pad",
"port": "Poort",
"ports": "Poorten",
"postinstall_domain": "Dit is de eerst domeinnaam die aan je YunoHost server gelinkt is, maar ook hetgene gebruikt zal worden als portaal voor je gebruikers om je server te bezoeken. Het is dus zichtbaar door iedereen, kies het zorgvuldig.",
"postinstall_intro_1": "Gefeliciteerd! YunoHost is met succes geïnstalleerd.",
"postinstall_intro_2": "Er zijn nog twee configuratiestappen nodig om de diensten van je server te activeren.",
"postinstall_intro_3": "Je kan meer informatie verkrijgen door <a href='//yunohost.org/postinstall' target='_blank'>de gepaste documentatie</a> te bekijken",
"postinstall_password": "Dit wachtwoord zal gebruikt worden om alles binnen je server te beheren. Neem de tijd om het zorgvuldig te kiezen.",
"previous": "Vorige",
"protocol": "Protocol",
"restore": "Herstellen",
"running": "Bezig",
"save": "Opslaan",
"service_start_on_boot": "Starten bij opstarten: ",
"services": "Services",
"set_default": "Zet als standaard",
"size": "Grootte",
"start": "Starten",
"status": "Status",
"stop": "Stoppen",
"system": "Systeem",
"system_apps_nothing": "Er zijn geen apps om bij te werken.",
"system_packages_nothing": "Er zijn geen pakketten om bij te werken.",
"system_update": "Systeemupdate",
"system_upgrade_btn": "Upgrade",
"tcp": "TCP",
"tools": "Gereedschappen",
"tools_adminpw": "Verander administratorwachtwoord",
"tools_adminpw_current": "Huidig wachtwoord",
"tools_adminpw_current_placeholder": "Voer huidig wachtwoord in",
"udp": "UDP",
"unauthorized": "Geen toegang",
"uninstall": "Installatie ongedaan maken",
"upnp": "UPnP",
"upnp_disabled": "UPnP is uitgeschakeld.",
"upnp_enabled": "UPnP is ingeschakeld.",
"url": "URL",
"user_email": "Email",
"user_emailaliases": "Mailaliassen",
"user_emailforward": "Email forward",
"user_fullname": "Volledige naam",
"user_interface_link": "Gebruikersinterface",
"user_mailbox_quota": "Mailbox quota",
"user_new_forward": "nieuwedoorstuurmail@mijndomein.org",
"user_username": "Gebruikersnaam",
"user_username_edit": "Bewerk {name}'s account",
"users": "Gebruikers",
"users_new": "Nieuwe gebruiker",
"users_no": "Geen gebruikers.",
"words": {
"default": "Standaard"
},
"wrong_password": "Foutief wachtwoord",
"yes": "Ja",
"app_info_changeurl_desc": "URL van deze applicatie veranderen (domein en/of locatie).",
"app_info_change_url_disabled_tooltip": "Functie is nog niet geïmplementeerd voor deze applicatie",
"app_state_inprogress": "functioneert nog niet",
"app_state_notworking": "Werkt niet",
"app_state_working": "Werkt",
"ok": "OK",
"app_state_highquality_explanation": "Deze applicatie is goed geïntegreerd met Yunohost. Ze werd en wordt beoordeel door de applicatie ploeg van Yunohost. Er kan gesteld worden dat ze veilig werkt en op lange termijn onderhouden zal worden.",
"app_state_highquality": "hoge kwaliteit",
"app_state_lowquality_explanation": "Deze applicatie kan functioneren maar er zijn nog steeds openstaande problemen of ze is nog niet volledig geïntegreerd met Yunohost of ze respecteert de regels van de kunst niet.",
"app_state_lowquality": "lage kwaliteit",
"app_state_notworking_explanation": "De persoon die deze applicatie onderhoudt, verklaart dat ze niet functioneert. DE INSTALLATIE KAN UW SYSTEEM STUK MAKEN!",
"app_state_inprogress_explanation": "De persoon die deze applicatie onderhoudt, heeft verklaard dat ze nog niet klaar is voor een gebruik in productie. WEES VOORZICHTIG!",
"app_no_actions": "Deze applicaties beschikt niet over acties",
"all_apps": "Alle applicaties",
"all": "Alles"
}

View file

@ -1,147 +1,79 @@
{
"action": "Accion",
"add": "Ajustar",
"remove": "Levar",
"administration_password": "Senhal dadministracion",
"allowed_users": "Personas autorizadas",
"api_not_responding": "LAPI respond pas? Benlèu que « yunohost-api » es en pana o es estat reaviat ?",
"app_access": "Accès",
"app_access_addall_btn": "Activar laccès per totes",
"app_access_addall_desc": "Totes los utilizaires existents auràn accès a %s.",
"app_access_clearall_desc": "Qual que siá aurà accès a %s.",
"app_access_removeall_btn": "Levar totes los accèsses",
"app_access_removeall_desc": "Degun aurà pas accès a %s.",
"app_access_title": "Accès %s",
"app_change_label": "Cambiar lapelacion",
"app_change_url": "Cambiar lURL",
"app_debug_no_logs": "Los jornals dactivitats de laplicacions son pas disponibles",
"app_debug_tab": "Mostrar las informacions de desbugatge",
"app_info_access_desc": "Grops / utilizaires actualament autorizatsa accedir a aquesta aplicacion :",
"app_info_changelabel_desc": "Cambiar lapelacion de laplicacion pel portal.",
"app_info_change_url_disabled_tooltip": "Aquesta foncionalitat es pas encara presa en carga per aquesta aplicacion pel moment",
"app_info_uninstall_desc": "Suprimir aquesta aplicacion.",
"app_install_cancel": "Installacion anullada.",
"app_install_custom_no_manifest": "Cap de fichièr manifest.json",
"app_list": "Lista daplicacions",
"app_make_default": "Definir per defaut",
"app_state_inprogress": "pas encara en foncion",
"app_state_notworking": "fonciona pas",
"app_state_validated": "Validada",
"app_state_working": "fonciona",
"application": "Aplicacion",
"applications": "Aplicacions",
"archive_empty": "Archiu void",
"available": "Disponible",
"available_apps": "Aplicacions disponiblas",
"backup": "Salvagardas",
"backup_action": "Salvagardar",
"backup_archive_delete": "Suprimir larchiu",
"backup_archive_download": "Telecargar larchiu",
"backup_content": "Contengut de la salvagarda",
"backup_create": "Crear una salvagarda",
"backup_encryption_warning": "Doblidetz pas aqueste senhal, vos farà mestièr per restaurar aquesta salvagarda",
"backup_new": "Nòva salvagarda",
"backup_optional_encryption": "Chiframent opcional",
"backup_optional_password": "Senhal opcional",
"backup_type": "Tip",
"backups_no": "Cap de salvagarda",
"begin": "Zo",
"bit_rate": "Debit",
"cancel": "Anullar",
"check": "Verificacion",
"check_mx": "Enregistrament MX",
"check_stmp": "Accessibilitat del pòrt 25",
"close": "Tampar",
"app_access_clearall_btn": "Escafar totes los accèsses",
"app_info_debug_desc": "Mostrar las informacions de desbogatge per aquesta aplicacion.",
"app_info_default_desc": "Mandar la raiç del domeni cap a aquesta aplicacion (%s).",
"app_info_default_desc": "Mandar la raiç del domeni cap a aquesta aplicacion ({domain}).",
"app_info_changeurl_desc": "Cambiar ladreça daccès daquesta aplicacion (domeni e/o camin).",
"app_repository": "Origina de laplicacion: ",
"app_state": "Estat de laplicacion: ",
"backup_archive_copy": "Copiar aquesta salvagarda dins un autre emplaçament",
"backup_experimental_warning": "Gardatz al cap quaquesta foncionalitat de salvagarda es encara experimentala, e es pas totalament fiabla.",
"both": "Los dos",
"confirm_access_add": "Volètz vertadièrament ajustar laccès a %s per totes los utilizaires?",
"confirm_access_clear": "Volètz vertadièrament escafar totes los accèsses a %s?",
"confirm_access_remove_all": "Volètz vertadièrament escafar totes los accèsses a %s?",
"confirm_access_remove_user": "Volètz vertadièrament escafar laccès a %s per %s?",
"confirm_app_change_url": "Volètz vertadièrament cambiar ladreça daccès daquesta aplicacion?",
"confirm_app_default": "Volètz vertadièrament definir aquesta aplicacion coma aplicacion per defaut?",
"confirm_change_maindomain": "Volètz vertadièrament cambiar lo domeni màger?",
"confirm_delete": "Volètz vertadièrament escafar %s?",
"confirm_firewall_open": "Volètz vertadièrament dobrir lo pòrt %s? (protocòl: %s, connexion: %s)",
"confirm_firewall_close": "Volètz vertadièrament tampar lo pòrt %s? (protocòl: %s, connexion: %s)",
"confirm_delete": "Volètz vertadièrament escafar {name}?",
"confirm_firewall_open": "Volètz vertadièrament dobrir lo pòrt {port}? (protocòl: {protocol}, connexion: {connection})",
"confirm_firewall_close": "Volètz vertadièrament tampar lo pòrt {port}? (protocòl: {protocol}, connexion: {connection})",
"confirm_install_custom_app": "Atencion! Linstallacion daplicacions tèrças pòt perilhar lintegritat e la seguretat del sistèma. Auriatz PAS de ninstallar levat que saupèssetz çò que fasètz. Volètz vertadièrament córrer aqueste risc?",
"confirm_install_domain_root": "Poiretz pas installar mai aplicacions sus %s. Contunhar?",
"confirm_install_domain_root": "Poiretz pas installar mai aplicacions sus {domain}. Contunhar?",
"confirm_migrations_skip": "Passar las migracions es pas recomandat. Volètz vertadièrament o far?",
"confirm_postinstall": "Sètz a man de lançar lo processús de post-installacion sul domeni %s. Aquò pòt tardar una estona, *arrestetz pas loperacion*.",
"confirm_restore": "Volètz vertadièrament restaurar %s?",
"confirm_service_start": "Volètz vertadièrament aviar %s?",
"confirm_service_stop": "Volètz vertadièrament arrestar %s?",
"confirm_service_enable": "Volètz vertadièrament activar %s?",
"confirm_service_disable": "Volètz vertadièrament desactivar %s?",
"confirm_uninstall": "Volètz vertadièrament desinstallar %s?",
"confirm_postinstall": "Sètz a man de lançar lo processús de post-installacion sul domeni {domain}. Aquò pòt tardar una estona, *arrestetz pas loperacion*.",
"confirm_restore": "Volètz vertadièrament restaurar {name}?",
"confirm_service_start": "Volètz vertadièrament aviar {name}?",
"confirm_service_stop": "Volètz vertadièrament arrestar {name}?",
"confirm_uninstall": "Volètz vertadièrament desinstallar {name}?",
"confirm_update_apps": "Volètz vertadièrament metre a jorn totas las aplicacions?",
"confirm_update_packages": "Volètz vertadièrament metre a jorn totes los paquets?",
"confirm_update_specific_app": "Volètz vertadièrament metre a jorn %s?",
"confirm_update_specific_app": "Volètz vertadièrament metre a jorn {app}?",
"confirm_upnp_enable": "Volètz vertadièrament activar lUPnP?",
"confirm_upnp_disable": "Volètz vertadièrament desactivar lUPnP?",
"confirm_reboot_action_reboot": "Volètz vertadièrament reaviar lo servidor?",
"confirm_reboot_action_shutdown": "Volètz vertadièrament atudar lo servidor?",
"connection": "Connexion",
"copy": "Copiar",
"count_min": "%s min",
"cpu_load": "Carga CPU",
"created_at": "Creat lo",
"cumulative_usage": "Cumul",
"custom_app_install": "Installar una aplicacion personalizada",
"custom_app_url_only_github": "Sonque a partir de GitHub",
"default": "Defaut",
"delete": "Suprimir",
"description": "Descripcion",
"diagnosis": "Diagnostic",
"diagnosis_hide_private": "Mostrar lo diagnostic sens donadas sensiblas",
"diagnosis_view_private": "Mostrar lo diagnostic amb las donadas sensiblas",
"diagnosis_with_private": "Diagnostic amb las donadas sensiblas",
"disable": "Desactivar",
"disabled": "Desactivat",
"disk": "Disc",
"dns": "DNS",
"domain": "Domeni",
"domain_add": "Ajustar un domeni",
"domain_add_dns_doc": "… e ai <a href='//yunohost.org/dns'>>corrèctament configurat mos DNS</a>.",
"domain_add_dyndns_doc": "… e desiri un nom de domeni preconfigurat.",
"domain_add_panel_with_domain": "Ai ja mon nom de domeni…",
"domain_add_panel_without_domain": "Ai pas de nom de domeni…",
"domain_default": "Domeni per defaut",
"domain_default_desc": "Los utilizaires se connectaràn al domeni per defaut.",
"domain_default_longdesc": "Aquò es vòstre domeni per defaut.",
"domain_delete_longdesc": "Suprimir aqueste domeni",
"domain_dns_config": "Configuracion DNS",
"domain_dns_longdesc": "Veire la configuracion DNS",
"domain_list": "Lista de domenis",
"domain_name": "Nom de domeni",
"domain_select": "Seleccionatz un domeni",
"domain_visit": "Visitar",
"domain_visit_url": "Visitar %s",
"domain_visit_url": "Visitar {url}",
"domains": "Domenis",
"download": "Telecargar",
"enable": "Activar",
"enabled": "Activat",
"error_modify_something": "Vos cal modificar quicòm",
"error_occured": "Una error ses producha, tornatz ensajar",
"error_retrieve_feed": "Impossible de trapar lo flux: %s. Benlèu quavètz una extension al navigador que li permet pas de realizar aquesta requèsta (o la pagina es copada).",
"error_select_domain": "Deuriatz indicar un domeni",
"error_server": "Error servidor",
"error_server_unexpected": "Error pas esperada (%s)",
"everyone_has_access": "Totes los utilizaires an accès.",
"filesystem": "Sistèma de fichièr",
"error_server_unexpected": "Error pas esperada",
"firewall": "Parafuòc",
"footer_version": "Propulsat per <a href='https://yunohost.org'>YunoHost</a> %s (%s).",
"form_input_example": "Exemple%s",
"free": "Liure",
"fs_type": "Tipe de sistèma de fichièr",
"gateway": "Palanca: ",
"footer_version": "Propulsat per <a href='https://yunohost.org'>YunoHost</a> {version} ({repo}).",
"form_input_example": "Exemple{example}",
"home": "Acuèlh",
"hook_adminjs_group_configuration": "Configuracion del sistèma",
"hook_conf_cron": "Tascas automaticas",
@ -157,28 +89,18 @@
"hook_data_home_desc": "Las donadas utilizaires son plaçadas dins /home/USER",
"hook_data_mail": "Corrièl",
"hook_data_mail_desc": "Los corrièls gardats sul servidor",
"hostname": "Nom dòst",
"id": "ID",
"inactive": "Inactiu",
"infos": "Info",
"install": "Installar",
"install_name": "Installar %s",
"install_name": "Installar {id}",
"install_time": "Data dinstallacion",
"installation_complete": "Installacion acabada",
"installed": "Installat",
"installed_apps": "Aplicacions installadas",
"installing": "Installacion",
"interface": "Interfàcia",
"ipv4": "IPv4",
"ipv6": "IPv6",
"label": "Apelacion",
"label_for_manifestname": "Apelacion per %s",
"loading": "Cargament…",
"label_for_manifestname": "Apelacion per {name}",
"local_archives": "Archius locals",
"local_ip": "IP locala",
"log": "Jornal",
"logged_in": "Connectat",
"logged_out": "Desconnectat",
"login": "Connexion",
"logout": "Desconnexion",
"mailbox_quota_description": "Per exemple, 700M fa un CD, 4700M fa un DVD.",
@ -186,99 +108,50 @@
"manage_apps": "Gerir las aplicacions",
"manage_domains": "Gerir los domenis",
"manage_users": "Gerir los utilizaires",
"memory": "Memòria",
"menu": "Menú",
"migrations": "Migracions",
"migrations_pending": "Migracion en espèra",
"migrations_done": "Migracions precedentas",
"migrations_no_pending": "Pas cap de migracion en espèra",
"migrations_no_done": "Pas cap de migracion precedenta",
"mode": "Mòde",
"monitoring": "Estat del servidor",
"monitoring_check_glances": "Verificatz lestat del servici <a href='#/services/glances'>glances</a>.",
"monitoring_disabled": "Lo seguiment de lestat del servidor es pas activat.",
"multi_instance": "Instància multipla",
"myserver": "monservidor",
"myserver_org": "monservidor.com",
"network": "Ret",
"next": "Seguent",
"no": "Non",
"no_allowed_users": "Cap dutilizaire autorizat.",
"no_installed_apps": "Cap daplicacion installada.",
"no_log": "Cap de jornal.",
"no_user_to_add": "Degun a ajustar.",
"non_compatible_api": "API pas compatibla",
"ok": "OK",
"open": "Dobrir",
"operations": "Operacions",
"os": "OS",
"password": "Senhal",
"password_confirmation": "Confirmacion del senhla",
"password_description": "Lo senhal deu almens conténer %s caractèrs.",
"password_empty": "Lo camp senhal es void",
"password_new": "Nòu senhal",
"passwords_dont_match": "Los senhals correspondon pas",
"passwords_too_short": "Senhal tròp cort",
"path": "Repertòri",
"path_url": "Camin",
"port": "Pòrt",
"ports": "Pòrts",
"postinstall": "Post-installacion",
"postinstall_intro_1": "Òsca! YunoHost es estat corrèctament installat.",
"previous": "Precedent",
"process": "Processús",
"protocol": "Protocòl",
"public_ip": "IP publica: ",
"ram": "RAM",
"read": "Lectura",
"read_more": "Ne saber mai",
"reception": "Recepcion",
"refresh_app_list": "Actualizar la lista",
"remove_access": "Levar los accèsses",
"restore": "Restaurar",
"run": "Lançar",
"running": "En execucion",
"save": "Salvagardar",
"select_user": "Causissètz un utilizaire",
"service_log": "Jornal de %s",
"service_start_on_boot": "Lançar en aviar",
"service_status": "Estatut: ",
"services": "Servicis",
"services_list": "Lista dels servicis",
"set_default": "Definir per defaut",
"size": "Talha",
"skip": "Passar",
"start": "Aviar",
"status": "Estatut",
"stop": "Arrestar",
"storage_create": "Ajustar un emmagazinatge alonhat",
"storages_new": "Nòu emmagazinatge alonhat",
"storages_no": "Pas demmagazinatge.",
"swap": "Espaci descambi",
"system": "Sistèma",
"system_apps": "Aplicacions",
"system_apps_nothing": "Totas las aplicacions son a jorn !",
"system_delayed_upgrade": "Mesa a jorn reportada",
"system_delayed_upgrade_warning": "<b>%s</b> serà mes a jorn dins lora venenta.",
"system_packages": "Paquets sistèma",
"system_packages_nothing": "Totes los paquets sistèma son a jorn !",
"system_update": "Mesa a jorn del sistèma",
"system_upgrade": "Mesa a jorn del sistèma",
"system_upgrade_btn": "Metre a jorn",
"system_upgrade_all_applications_btn": "Metre a jorn totas las aplicacions",
"system_upgrade_all_packages_btn": "Metre a jorn totes los paquets",
"tcp": "TCP",
"time_since_update": "Darrièra mesa a jorn: ",
"tools": "Aisinas",
"tools_adminpw": "Cambiar lo senhal dadministracion",
"tools_adminpw_confirm_placeholder": "Confirmatz lo novèl senhal",
"tools_adminpw_current": "Senhal actual",
"tools_adminpw_current_placeholder": "Picatz lo senhal actual",
"tools_adminpw_new_placeholder": "Picatz lo novèl senhal",
"tools_security_feed": "Alèrtas de seguretat",
"tools_security_feed_no_items": "Pas cap dalèrta de seguretat",
"tools_security_feed_subscribe_rss": "Sinscriure al flux RSS de las alèrtas de seguretat",
"tools_security_feed_view_items": "Veire totas las alèrtas de seguretat",
"tools_reboot": "Reaviar lo servidor",
"tools_reboot_btn": "Reaviar",
"tools_reboot_done": "Reaviada…",
@ -286,20 +159,13 @@
"tools_shutdown_btn": "Atudar",
"tools_shutdown_done": "Arrèst en cors…",
"tools_shutdown_reboot": "Atudar/Reaviar",
"total": "Total",
"transmission": "Mandadís",
"udp": "UDP",
"unauthorized": "Pas autorizat",
"uninstall": "Desinstallar",
"unknown_action": "Accion %s desconeguda",
"unknown_argument": "Argument desconegut: %s",
"upload_archive": "Enviar una salvagarda",
"upnp": "UPnP",
"upnp_disabled": "LUPnP es desactivat.",
"upnp_enabled": "LUPnP es activat.",
"url": "URL",
"usage": "Utilizacion",
"used": "Utilizat",
"user_email": "Corrièl",
"user_emailaliases": "Adreças suplementàrias",
"user_emailforward": "Adreças de transferiment",
@ -307,29 +173,20 @@
"user_interface_link": "Interfàcia utilizaire",
"user_username": "Nom dutilizaire",
"users": "Utilizaires",
"users_list": "Lista dels utilizaires",
"users_new": "Nòu utilizaire",
"domain_dns_conf_is_just_a_recommendation": "Aquesta pagina mòstra la configuracion *recomandada*. Configura *pas* lo DNS per vos. Es vòstra responsabilitat la configuracion de la zòna DNS en çò vòstre registrar DNS amb aquesta recomandacion.",
"internal_exception": "<strong>YunoHost a rescontrat una error intèrna:/</strong><br><em>O planhèm.<br>Deuriatz cercar dajuda al <a href=\"https://forum.yunohost.org/\">forum</a> o al <a href=\"https://chat.yunohost.org/\">salon</a> per resòlver lo problèma, o senhalar lo bug sus <a href=\"https://yunohost.org/projects/YunoHost/issues\">laisina de seguiment</a>.</em><br>Las informacions seguentas pòdon èsser utilas a vòstres interlocutors que vos ajudan:<h3>Accion</h3><pre>%s%s</pre><h3>Traça</h3><pre>%s</pre>",
"mount_point": "Ponch de montatge",
"postinstall_domain": "Aquò es lo primièr nom de domeni ligat al servidor YunoHost, mas tanben lo que servirà al portanèl didentificacion. Serà doncas visible per totes los utilizaires, causissètz-lo amb suènh.",
"postinstall_intro_2": "Doas etapas mai son necessàrias per activar lo servidor.",
"postinstall_intro_3": "Podètz trapar mai dinformacion en anar a <a href='//yunohost.org/postinstall' target='_blank'> la pagina de documentacion en question</a>",
"postinstall_password": "Aqueste senhal vos permetrà daccedir a linterfàcia dadministracion e de contrarotlar lo servidor. Prenètz lo temps de ne causir un bon.",
"tools_download_ca": "Telecargar lautoritat de certificacion SSL (CA)",
"tools_download_ca_desc": "Clicatz aicí per telecargar lautoritat de certificacion SSL (CA)",
"tools_rebooting": "Lo servidor es a tornar aviar. Per tornar a linterfàcia dadministracion devètz esperar que lo servidor siá aviat. Podètz o verificar en actualizant aquesta pagina (F5).",
"tools_shuttingdown": "Lo servidor es atudat. Del temps que lo servidor es atudat podètz pas accedir a linterfàcia dadministracion.",
"upload": "Partejar amb yunopaste",
"uptime": "Durada de foncionament",
"user_new_forward": "novel_transferiment@domenialonhat.org",
"user_new_mail": "novela_adreça@domeni.org",
"user_username_edit": "Modificar lo compte a %s",
"user_username_edit": "Modificar lo compte a {name}",
"users_no": "Pas cap dutilizaire.",
"versions": "Versions",
"view_user_profile": "Veire lo perfil a %s",
"warning_first_user": "Vos cal den primièr <a href='#/users/create' class='alert-link'>crear un utilizaire</a>.",
"write": "Escriure",
"words": {
"default": "Defaut"
},
"wrong_password": "Senhal incorrècte",
"yes": "Òc",
"certificate_alert_good": "Va ben, lo certificat actual sembla bon!",
@ -350,22 +207,6 @@
"regenerate_selfsigned_cert_message": "Se volètz, podètz tornar generar los certificats auto-signats.",
"regenerate_selfsigned_cert": "Tornar generar los certificats auto-signats",
"revert_to_selfsigned_cert": "Tornar un certificat auto-signat",
"appslists": "Listas daplicacions",
"appslists_no_lists": "Pas cap de lista daplicacions",
"appslists_custom": "Lista personalizada daplicacions",
"appslists_manage": "Gerir las listas daplicacions",
"appslists_confirm_remove": "Volètz vertadièrament suprimir aquesta lista daplicacions?",
"appslists_info_refresh_desc": "Actualizar lestatut de las aplicacions de la lista.",
"appslists_info_remove_desc": "Las aplicacions daquesta lista seràn pas mai disponiblas.",
"appslists_last_update": "Darrièra mesa a jorn",
"appslists_unknown_list": "La lista « %s» es desconeguda",
"appslists_community_list": "Lista de las aplicacions de la comunitat",
"name": "Nom",
"install_community_appslists_info": "La lista de las aplicacions de la comunitat vos permet dinstallar daplicacions mantengudas per la comunitat.<br /> Gaitatz la lista complèta sus <a href='https://yunohost.org/apps'>yunohost.org/apps</a>.",
"install_community_appslists_warning": "Aquestas aplicacions <strong>son pas</strong> oficialas, nimai mantengudas per la còla YunoHost.<br /> Installar aquestas aplicacions es amb vòstra resèrva, pòt perilhar vòstre sistèma.",
"install_custom_app_appslists_info": "Podètz utilizar de listas alternativas daplicacions per installar mai aplicacions mantengudas per la comunitat YunoHost.",
"io": "E/S",
"service_description": "Descripcion:",
"user_mailbox_quota": "Quòta de la bóstia de las letras",
"user_mailbox_use": "Espaci utilizat per la bóstia de las letras",
"certificate_alert_not_valid": "Critic: lo certificat actual es invalid! Lo HTTPS foncionarà pas ges!",
@ -373,13 +214,9 @@
"certificate_alert_letsencrypt_about_to_expire": "Lo certificat actual es a man dexpirar. Calrà lèu lo renovar automaticament.",
"certificate_alert_about_to_expire": "Atencion: lo certificat actual es a man dexpirar! Serà pas renovat automaticament!",
"certificate_alert_great": "Perfièch! Sètz a utilizar un certificat Lets Encrypt valid!",
"certificate_old_letsencrypt_app_conflict": "Laplicacion «letsencrypt» es actualament installada e es en conflicte amb aquesta foncionalitat. Mercés de la desinstallar per utilizar la novèla interfàcia de gestion dels certificats.",
"domain_not_eligible_for_ACME": "Aqueste domeni sembla pas prèst per un certificat Lets Encrypt. Mercés de verificar la configuracion DNS e laccessibilitat del servidor HTTP. Las seccions «enregistrament DNS» e «Web» de <a href='#/diagnosis'>la pagina de diagnostic</a> pòt vos ajudar a comprendre çò ques pas configurat coma cal.",
"manually_renew_letsencrypt_message": "Lo certificat serà renovat automaticament pendent los darrièrs 15 jorns de validitat. Podètz lo renovar manualament se volètz. (Pas recomandat).",
"meltdown": "Sètz vulnerable a la falha de seguretat critica <a target=\"_blank\" href=\"https://meltdownattack.com/\">meltdown</a>. Per dire de resòlvre aqueste problèma, vos cal <a href=\"#/update\">actualizar vòstre sistèma</a> puèi <a href=\"#/tools/reboot\"> lo tornar aviar</a> per cargar lo nòu nuclèu linux.",
"revert_to_selfsigned_cert_message": "So volètz vertadièrament, podètz tornar installar lo certificat auto-signat. (Pas recomandat)",
"started_at": "Aviat a:",
"active": "Actiu",
"app_no_actions": "Aquesta aplicacion a pas cap daccions",
"experimental_warning": "Atencion: aquesta foncionalitat es experimentala e deu pas èsser considerada coma establa, deuriatz pas lutilizar levat que sapiatz çò que fasètz.",
"logs": "Jornals",
@ -391,7 +228,6 @@
"logs_service": "Jornals dels servicis",
"logs_app": "Jornals de las aplicacions",
"logs_no_logs_registered": "Cap de jornals enregistrats per aquesta categoria",
"logs_end_with_error": "Aqueste jornal acaba amb lerror:",
"logs_error": "Error",
"logs_ended_at": "Fin",
"logs_started_at": "Debuta",
@ -400,51 +236,36 @@
"logs_share_with_yunopaste": "Partejar amb YunoPaste",
"logs_more": "Mostrar mai de linhas",
"all_apps": "Totas las aplicacions",
"app_license": "Licéncia de laplicacion",
"app_level": "Nivèl de laplicacion",
"app_state_official": "Oficiala",
"confirm_install_app_warning": "Atencion: aquesta aplicacion foncionarà mas es pas encara ben integrada a YunoHost. Unas foncionalitats coma lidentificacion unica e la salvagarda/restauracion pòdon èsser pas disponiblas.",
"confirm_install_app_danger": "ATENCION! Aquesta aplicacion es encara experimentala (o fonciona pas dirèctament) e es probable que còpe lo sistèma! Deuriatz pas linstallar levat que saupèssetz çò que fasètz. Volètz vertadièrament córrer aqueste risc?",
"current_maintainer_title": "Mantenidor actual daqueste paquet",
"error_connection_interrupted": "Lo servidor a tampat la connexion allòc de respondre. Nginx o yunohost-api es estat relançat o arrestat per error? (Còdi derror/messatge: %s)",
"confirm_install_app_lowquality": "Atencion: aquesta aplicacion foncionarà mas es pas encara ben integrada a YunoHost. Unas foncionalitats coma lidentificacion unica e la salvagarda/restauracion pòdon èsser pas disponiblas.",
"confirm_install_app_inprogress": "ATENCION! Aquesta aplicacion es encara experimentala (o fonciona pas dirèctament) e es probable que còpe lo sistèma! Deuriatz pas linstallar levat que saupèssetz çò que fasètz. Volètz vertadièrament córrer aqueste risc?",
"error_connection_interrupted": "Lo servidor a tampat la connexion allòc de respondre. Nginx o yunohost-api es estat relançat o arrestat per error?",
"good_practices_about_admin_password": "Sètz a mand de definir un nòu senhal dadministrator. Lo nòu senhal deu conténer almens 8 caractèrs, es de bon far dutilizar un senhal mai long (es a dire una frasa de senhal) e/o utilizar mantuns tipes de caractèrs (majusculas, minusculas, nombres e caractèrs especials).",
"good_practices_about_user_password": "Sètz a mand de definir un nòu senhal dutilizaire. Lo nòu senhal deu conténer almens 8 caractèrs, es de bon far dutilizar un senhal mai long (es a dire una frasa de senhal) e/o utilizar mantuns tipes de caractèrs (majusculas, minusculas, nombres e caractèrs especials).",
"level": "nivèl",
"only_official_apps": "Solament aplicacions oficialas",
"only_working_apps": "Solament aplicacions que foncionan",
"search_for_apps": "Cercar daplicacion…",
"select_all": "O seleccionar tot",
"select_none": "O deselecionnar tot",
"unmaintained": "Pas mantenguda",
"purge_user_data_checkbox": "Purgar las donadas de %s?(Aquò suprimirà lo contengut dels repertòris home e mail)",
"purge_user_data_checkbox": "Purgar las donadas de {name}?(Aquò suprimirà lo contengut dels repertòris home e mail)",
"purge_user_data_warning": "Purgar las donadas de lutilizaire es pas reversible. Asseguratz-vos de saber çò que fasètz!",
"version": "Version",
"app_state_inprogress_explanation": "Lo manteneire daquesta aplicacion declarèt quaquesta aplicacion es pas encara prèsta per un usatge en produccion. SIATZ PRUDENT!",
"app_state_notworking_explanation": "Lo manteneire daquesta aplicacion declarèt que «fonciona pas». COPARÀ VÒSTRE SISTÈMA!",
"app_state_high-quality": "nauta qualitat",
"app_state_high-quality_explanation": "Aquesta aplicacion es plan integrada amb YunoHost. Es estada (e es) repassada per la còla daplicacion de YunoHost. Òm pòt esperar que siá segura e mantenguda per un long moment.",
"app_state_highquality": "nauta qualitat",
"app_state_highquality_explanation": "Aquesta aplicacion es plan integrada amb YunoHost. Es estada (e es) repassada per la còla daplicacion de YunoHost. Òm pòt esperar que siá segura e mantenguda per un long moment.",
"app_state_working_explanation": "Lo manteneire de laplicacion declarèt que «foncion». Significa que deu èsser foncionala (c.f. nivèls daplicacion) mas es pas forçadament repassada, e pòt totjorn contenir de problèmas o èsser pas complètament integrada a YunoHost.",
"confirm_update_system": "Volètz vertadièrament actualizar totes los paquets del sistèma?",
"hook_conf_ynh_currenthost": "Domeni principal actual",
"license": "Licéncia",
"maintained": "mantenguda",
"maintained_details": "Aquesta aplicacion es mantenguda per son manteneire dins los darrièrs meses passats.",
"only_highquality_apps": "Solament las apps de nauta qualitat",
"only_decent_quality_apps": "Solament aplicacion de qualitat convenabla",
"orphaned": "Pas mantenguda",
"orphaned_details": "Aquesta aplicacion es pas mai mantenguda dempuèi un moment. Pòt encara foncionar mas aurà pas cap dactualizacion fins que qualquun se cargue daquò. Esitetz pas a contribuïr per la reviscolar!",
"request_adoption": "en espèra dadopcion",
"request_adoption_details": "Lo manteneire actuala volriá quitar de la mantenir. Esitetz pas a vos prepausar per venir manteneire!",
"request_help": "ajuda necessària",
"request_help_details": "Lo manteneire actual volriá dajuda per la mantenença de laplicacion. Esitetz pas a i contribuïr!",
"advanced": "Avançat",
"from_to": "de %s fins a %s",
"from_to": "de {0} fins a {1}",
"rerun_diagnosis": "Tornar lançar lo diagnostic",
"last_ran": "Darrièra execucion :",
"permissions": "Permissions",
"details": "Detalhs",
"diagnosis_experimental_disclaimer": "Remembratz-vos que lopcion de diagnostic es encara experimentala e a se melhorar, e pòt pas èsser fisabla.",
"errors": "%s errors",
"everything_good": "Tot es bon !",
"group": "Grop",
"group_name": "Nom del grop",
@ -461,31 +282,28 @@
"groups_and_permissions": "Grops e permissions",
"groups_and_permissions_manage": "Gerir los grops e las permissions",
"ignore": "Ignorar",
"ignored": "%s ignorat",
"ignored": "{count} ignorat",
"unignore": "Ignorar pas",
"warnings": "%s avises",
"warnings": "{count} avises",
"configuration": "Configuracion",
"since": "dempuèi",
"app_state_low_quality_explanation": "Aquesta aplicacion pòt foncionar, mas pòt conténer de problèmas, o es pas complètament integrada a YunoHost, o respècta pas las bonas practicas.",
"app_state_lowquality_explanation": "Aquesta aplicacion pòt foncionar, mas pòt conténer de problèmas, o es pas complètament integrada a YunoHost, o respècta pas las bonas practicas.",
"all": "Totas",
"app_state_low_quality": "qualitat bassa",
"app_state_lowquality": "qualitat bassa",
"catalog": "Catalòg",
"others": "Autras",
"run_first_diagnosis": "Executar lo diagnostic inicial",
"confirm_service_restart": "Volètz vertadièrament reaviar %s?",
"confirm_service_restart": "Volètz vertadièrament reaviar {name}?",
"restart": "Reaviar",
"groups": "Grops",
"issues": "%s problèmas",
"issues": "{count} problèmas",
"unmaintained_details": "Fa un moment quaquesta aplicacion es pas mai mantenguda e la persona que la manteniá es partida o a pas de temps per la mantenir. Esitetz pas a consultar lo repertòri de las aplicacions per aportar vòstra ajuda",
"tip_about_user_email": "Los utilizaires son creats amb una adreça e-mails ligada (e un compte XMPP) al format utilizaire@domeni.tld. Las adreças de transferiments suplementàrias pòdon èsser ajustadas ulteriorament per ladministrator e lutilizaire.",
"operation_failed_explanation": "Aquesta operacion a pas capitat! O planhèm :( Podètz ensajar de <a href='https://yunohost.org/help'>demandar dajuda</a>. Se vos plai donar lo *jornal complèt* de loperacion quensajan de vos ajudar. Podètz clicar sul boton verd «Partejar amb Yunopaste». En partejant lo jornal daudit, YunoHost provarà automaticament danonimizar las donadas coma los noms de domeni e adreças IP.",
"group_explain_visitors_needed_for_external_client": "Agachatz que certanas aplicacions sián autorizadas pels visitaires se volètz las utilizar amb de clients extèrns. Per exemple, es lo cas per Nextcloud savètz idèa demplegar un client de sincronizacion pel vòstre smartphone o ordenador de burèu.",
"diagnosis_explanation": "La foncionalitat de diagnostic provarà trobar problèmas comuns sus diferents aspèctes de vòstre servidor per sassegurar que tot fonciona normalament. Lo diagnostic serà tanben realizat dos còps per jorn e enviarà un corrièl a ladministrator se derrors son detectadas. De notar que dunes ensages seràn pas mostrats sutilizatz pas certanas foncions especificas (XMPP, per exemple) o se fracassan a causa duna configuracion tròp complèxa. Dins aqueste cas, e se sabètz çò quavètz modificat, podètz ignorar los problèmas e avertiments correspondents.",
"pending_migrations": "I a unas migracions en espèra dexecucion. Anatz a <a href='#/tools/migrations'>Aisinas > Migracions</a> per las lançar.",
"log_suboperations": "Jos-operacions",
"logs_suboperations": "Jos-operacions",
"diagnosis_first_run": "La foncionalitat de diagnostic ensajarà didentificar los problèmas abituals de diferents aspèctes del servidor per dire dassegurar que tot foncione de la melhora manièra possibla. Ajatz pas paur se vesètz mantunas error aprèp configurar lo servidor: es precisament fach per ajudar a identificar los problèmas e ofrir una guida per los reglar. Lo diagnostic sexecutarà tanben dos còps per jorn e enviarà un corrièl a ladministrator se tròba unas error.",
"apply": "Aplicar",
"app_info_managelabel_desc": "Gerir las aplelacion de permission al portal.",
"app_manage_label_and_tiles": "Gestion de las apelacions e títols",
"permission_corresponding_url": "URL correspondenta",
"permission_main": "Permission principala",

View file

@ -0,0 +1,32 @@
{
"password": "Hasło",
"action": "Akcja",
"add": "Dodaj",
"administration_password": "Hasło Administratora",
"api_not_responding": "API nie odpowiada",
"app_info_access_desc": "Zarządzaj dostępem użytkowników. Dozwoleni użytkownicy: %s",
"app_info_default_desc": "Przekieruj główną domenę do tej aplikacji ({domain}).",
"app_info_changeurl_desc": "Zmień adres URL tej aplikacji (domenę i/lub ścieżkę).",
"app_info_change_url_disabled_tooltip": "Ta funkcjonalność nie została jeszcze zaimplementowana w tej aplikacji",
"app_info_uninstall_desc": "Usuń tą aplikację.",
"app_install_custom_no_manifest": "Brak pliku manifest.json",
"app_make_default": "Ustaw jako domyślna",
"app_no_actions": "Ta aplikacji nie posiada żadnych akcji",
"app_state_inprogress": "W trakcie",
"app_state_notworking": "Nie działa",
"app_state_working": "Działa",
"applications": "Aplikacje",
"archive_empty": "Źródło puste",
"backup": "Kopia",
"backup_action": "Kopia",
"backup_content": "Zrób kopię zapasową",
"backup_create": "Stwórz kopię zapasową",
"backup_new": "Nowa kopia",
"begin": "Rozpocznij",
"both": "Oba",
"check": "Sprawdź",
"close": "Zamknij",
"login": "Zaloguj",
"logout": "Wyloguj",
"ok": "OK"
}

View file

@ -2,307 +2,169 @@
"action": "Ação",
"add": "Adicionar",
"administration_password": "Senha de administração",
"allowed_users": "Usuários permitidos",
"app_access": "Aceder",
"app_access_addall_btn": "Habilitar acesso a todos",
"app_access_addall_desc": "Todos os utilizadores existentes terão acesso a %s.",
"app_access_clearall_btn": "Limpar todos os acessos",
"app_access_clearall_desc": "Qualquer utilizador terá acesso a %s.",
"app_access_removeall_btn": "Remover todos os acessos",
"app_access_removeall_desc": "Nenhum utilizador terá acesso a %s.",
"app_access_title": "%s acesso",
"app_info_access_desc": "Grupos / usuários atualmente permitidos para esta aplicação:",
"app_info_default_desc": "Redirecionar domínio principal para esta aplicação (%s).",
"app_info_default_desc": "Redirecionar domínio principal para esta aplicação ({domain}).",
"app_info_uninstall_desc": "Remover esta aplicação.",
"app_list": "Lista de aplicações",
"app_make_default": "Tornar padrão",
"application": "Aplicação",
"applications": "Aplicações",
"available": "Disponível",
"available_apps": "Aplicações disponíveis",
"backup": "Cópia de segurança",
"backup_optional_password": "Senha opcional",
"backup_type": "Tipo",
"backup_warning_desc": "Deve a partir de agora restaurar os dados manualmente.",
"backup_warning_title": "O sistema para cópia de segurança ainda não foi implementado.",
"begin": "Iniciar",
"bit_rate": "Velocidade de transmissão",
"both": "Ambos",
"close": "Fechar",
"confirm_access_add": "Confirma a adição de acesso de %s a todos os utilizadores?",
"confirm_access_clear": "Confirma a limpeza de todos os acessos a %s ?",
"confirm_access_remove_all": "Confirma a eliminação de todos os acessos a %s ?",
"confirm_access_remove_user": "Confirma a eliminação do acesso de %s a %s ?",
"confirm_app_default": "Confirma esta aplicação como pré-definida?",
"confirm_change_maindomain": "Confirma a alteração do domínio principal?",
"confirm_delete": "Confirma a eliminação de %s ?",
"confirm_firewall": "Deseja continuar com porta %s para %s (protocolo: %s, ligação: %s)?",
"confirm_postinstall": "Está prestes a iniciar o processo de pós-instalação no servidor %s. Poderá demorar alguns minutos.\n*não interrompa a operação*.",
"confirm_service_action": "Confirma %s %s ?",
"confirm_uninstall": "Confirma a desinstalação de %s ?",
"confirm_upnp_action": "Deseja continuar com %s UPnP?",
"confirm_delete": "Confirma a eliminação de {name} ?",
"confirm_postinstall": "Está prestes a iniciar o processo de pós-instalação no servidor {domain}. Poderá demorar alguns minutos.\n*não interrompa a operação*.",
"confirm_uninstall": "Confirma a desinstalação de {name} ?",
"connection": "Ligação",
"count_min": "%s min",
"cpu_load": "Utilização da CPU",
"cumulative_usage": "Utilização acumulada",
"custom_app_install": "Instalar aplicação personalizada",
"custom_app_url_only_github": "Atualmente apenas desde o GitHub",
"default": "Pré-definido",
"delete": "Eliminar",
"description": "Descrição",
"disable": "Desativar",
"disk": "Disco",
"domain": "Domínio",
"domain_add": "Adicionar domínio",
"domain_add_dns_doc": "… coloco <a href='//yunohost.org/dns'>para definir o meu DNS</a>.",
"domain_add_dyndns_doc": "... quero um serviço DNS dinâmico.",
"domain_add_panel_with_domain": "Já tenho um domínio registado…",
"domain_add_panel_without_domain": "Ainda não registei um domínio…",
"domain_default": "Domínio pré-definido",
"domain_default_desc": "O domínio pré-definido é o domínio a que o utilizador se liga para iniciar sessão.",
"domain_list": "Lista de domínios",
"domain_name": "Nome do domínio",
"domain_select": "Selecione o domínio",
"domains": "Domínios",
"enable": "Ativar",
"error_modify_something": "Deve realizar alterações",
"error_occured": "Ocorreu um erro, tente de novo",
"error_select_domain": "Deve especificar um domínio",
"error_server": "Erro no servidor",
"everyone_has_access": "Todos têm acesso.",
"filesystem": "Sistema de ficheiros",
"firewall": "Firewall",
"free": "Livre",
"fs_type": "Tipo de Sistema de Ficheiros",
"gateway": "Gateway: ",
"hook_conf_ldap": "Base de dados LDAP",
"hook_conf_nginx": "Nginx",
"hook_conf_ssh": "SSH",
"hook_conf_ssowat": "SSOwat",
"hook_conf_xmpp": "XMPP",
"hook_data_mail": "Mail",
"hostname": "Hostname",
"id": "ID",
"inactive": "Inactivo",
"infos": "Informações",
"install": "Instalar",
"install_name": "Instalar %s",
"install_name": "Instalar {id}",
"install_time": "Tempo de instalação",
"installation_complete": "Instalação concluída",
"installed": "Instalado",
"installed_apps": "Aplicações instaladas",
"installing": "A instalar",
"interface": "Dispositivo",
"io": "I/O",
"ipv4": "IPv4",
"ipv6": "IPv6",
"label": "Etiqueta",
"label_for_manifestname": "Rótulo para %s",
"loading": "Inicializando …",
"local_ip": "IP local",
"log": "Registo",
"logged_in": "Sessão iniciada",
"logged_out": "Sessão terminada",
"label_for_manifestname": "Rótulo para {name}",
"login": "Iniciar sessão",
"logout": "Terminar sessão",
"manage_apps": "Gerenciar aplicações",
"manage_domains": "Gerir domínios",
"manage_users": "Gerir utilizadores",
"memory": "Memória",
"menu": "Menu",
"mode": "Modo",
"monitoring": "Monitorizando",
"monitoring_check_glances": "Verifique <a href='#/services/glances'>define</a> estado do serviço.",
"monitoring_disabled": "A monitorização está desativada.",
"mount_point": "Ponto de montagem",
"multi_instance": "Multi tarefas",
"myserver": "meuservidor",
"myserver_org": "meuservidor.org",
"network": "Rede",
"next": "Seguinte",
"no": "Não",
"no_allowed_users": "Não são permitidos utilizadores.",
"no_installed_apps": "Não tem aplicações instaladas.",
"no_log": "Não existem registos.",
"no_user_to_add": "Não existem mais utilizadores para adicionar.",
"non_compatible_api": "API não compatível",
"open": "Abrir",
"operations": "Operações",
"os": "Sistema Operativo",
"password": "Senha",
"password_confirmation": "Confirmação da senha",
"password_description": "A senha deve ter o mínimo de 4 caracteres.",
"password_empty": "Campo da senha está vazio",
"password_new": "Nova senha",
"passwords_dont_match": "As senhas não coincidem",
"passwords_too_short": "Senha curta demais",
"path": "Caminho",
"port": "Porta",
"ports": "Portas",
"postinstall": "Post-installation",
"postinstall_domain": "Este é o seu primeiro domínio ativo no seu servidor YunoHost, é este que será utilizado pelos utilizadores para acederem ao portal de autenticação. Terá que ficar visível a todos, escolha sabiamente.",
"postinstall_intro_1": "Parabéns! YunoHost foi instalado com êxito.",
"postinstall_intro_2": "São requeridos mais dois passos nas configurações para ativar os serviços no seu servidor.",
"postinstall_intro_3": "Pode obter mais informação ao visitar <a href='//yunohost.org/postinstall' target='_blank'>pagina de documentação apropriada</a>",
"postinstall_password": "Esta senha será utilizada para gerir tudo no seu servidor. Escolha-a sabiamente e demore o tempo que precisar.",
"previous": "Anterior",
"process": "Processo",
"protocol": "Protocolo",
"public_ip": "IP público: ",
"ram": "RAM",
"read": "Leitura",
"reception": "Receção",
"refresh_app_list": "Atualizar lista",
"remove_access": "Remover acesso",
"restore": "Restaurar",
"running": "Em execução",
"save": "Guardar",
"select_user": "Selecione o utilizador",
"service_log": "%s registo",
"service_start_on_boot": "Iniciar no arranque: ",
"service_status": "Estado: ",
"services": "Serviços",
"services_list": "Lista de serviços",
"set_default": "Aplicar pré-definição",
"size": "Tamanho",
"sleeping": "Suspenso",
"start": "Iniciar",
"status": "Estado",
"stop": "Parar",
"swap": "Memória virtual",
"system": "Sistema",
"system_apps": "Aplicações",
"system_apps_nothing": "Não existem aplicações para atualizar.",
"system_delayed_upgrade": "Atualização adiada",
"system_delayed_upgrade_warning": "<b>%s</b> será atualizada automaticamente na próxima hora.",
"system_packages": "Pacotes",
"system_packages_nothing": "Não existem pacotes para atualizar.",
"system_update": "Atualização do sistema",
"system_upgrade": "Atualização do sistema",
"system_upgrade_btn": "Atualizar",
"tcp": "TCP",
"time_since_update": "Tempo desde atualização: ",
"tools": "Ferramentas",
"tools_adminpw": "Alterar senha administrativa",
"tools_adminpw_confirm_placeholder": "Confirme a sua nova senha",
"tools_adminpw_current": "Senha atual",
"tools_adminpw_current_placeholder": "Escreva a sua senha atual",
"tools_adminpw_new_placeholder": "Escreva a sua nova senha",
"tools_download_ca": "Transferir o Certificado de Autoridade (CA) SSL",
"tools_download_ca_desc": "Clique aqui para transferir o seu certificado de autoridade (CA) SSL",
"total": "Total",
"transmission": "Envio",
"udp": "UDP",
"unauthorized": "Não autorizado",
"uninstall": "Desinstalar",
"unknown_action": "Ação desconhecida %s",
"unknown_argument": "Argumento desconhecido: %s",
"upload": "Carregar",
"upnp": "UPnP",
"upnp_disabled": "UPnP está desativado.",
"upnp_enabled": "UPnP está ativo.",
"uptime": "Tempo ativo",
"url": "URL",
"usage": "Utilização",
"used": "Utilizada",
"user_email": "Correio eletrónico",
"user_emailaliases": "Pseudónimos de correio",
"user_emailforward": "Reencaminhar correio",
"user_fullname": "Nome completo",
"user_new_forward": "newforward@myforeigndomain.org",
"user_new_mail": "newmail@mydomain.org",
"user_username": "Nome de utilizador",
"user_username_edit": "Editar conta de %s",
"user_username_edit": "Editar conta de {name}",
"users": "Utilizadores",
"users_list": "Lista de utilizadores",
"users_new": "Novo utilizador",
"users_no": "Não existem utilizadores.",
"view_user_profile": "Ver o perfil de %s",
"warning_first_user": "Provavelmente precisa <a href='#/users/create' class='alert-link'>criar um utilizador</a> primeiro.",
"write": "Escrita",
"words": {
"default": "Pré-definido"
},
"wrong_password": "Senha errada",
"yes": "Sim",
"cancel": "Cancelar",
"remove": "Remover",
"api_not_responding": "A API YunoHost não está respondendo. Talvez 'yunohost-api' esteja desligada ou foi reiniciada?",
"app_change_label": "Mudar etiqueta",
"app_change_url": "Mudar URL",
"app_debug_no_logs": "Logs da aplicação não estão disponíveis",
"app_debug_tab": "Mostrar debug",
"ok": "Confirmar",
"all_apps": "Todas as aplicações",
"active": "Ativo",
"advanced": "Avançado",
"app_info_changelabel_desc": "Muda o nome da aplicação mostrado no portal.",
"app_info_debug_desc": "Mostrar as informações de debug para esta aplicação.",
"app_info_changeurl_desc": "Mudar o URL usado para acessar esta aplicação (domínio e/ou caminho).",
"app_info_change_url_disabled_tooltip": "Esta funcionalidade não foi implementada nesta aplicação ainda",
"app_install_cancel": "Instalação cancelada.",
"app_install_custom_no_manifest": "Nenhum arquivo manifest.json encontrado",
"app_level": "Nível da aplicação",
"app_no_actions": "Esta aplicação não tem nenhuma ação",
"app_repository": "Origem da aplicação: ",
"app_state": "Estado da aplicação: ",
"app_state_inprogress": "ainda não está funcionando",
"app_state_inprogress_explanation": "O responsável desta aplicação afirmou que não está pronta ainda para ser usada em produção. TENHA CUIDADO!",
"app_state_notworking": "Não funcionando",
"app_state_notworking_explanation": "O responsável desta aplicação afirmou que não está funcionando. INSTALANDO-A PODE QUEBRAR SEU SISTEMA!",
"app_state_high-quality": "Qualidade alta",
"app_state_high-quality_explanation": "Esta aplicação está bem integrada em Yunohost. Foi (e continua sendo!) avaliada pelos pares do grupo responsável da parte aplicativa de Yunohost. Pode-se esperar que seja segura e mantida no longo prazo.",
"app_state_highquality": "Qualidade alta",
"app_state_highquality_explanation": "Esta aplicação está bem integrada em Yunohost. Foi (e continua sendo!) avaliada pelos pares do grupo responsável da parte aplicativa de Yunohost. Pode-se esperar que seja segura e mantida no longo prazo.",
"app_state_working": "Funcionando",
"app_state_working_explanation": "O responsável desta aplicação afirmou que está funcionando. Significa que deveria estar funcionando (verifique o nível da aplicação) mais que não foi necessariamente avaliada pelos pares, poderia conter erros ou não estar completamente integrada em Yunohost.",
"archive_empty": "O arquivo é vazio",
"backup_action": "Cópia de segurança",
"backup_archive_copy": "Copiar este arquivo numa outra memória",
"backup_archive_delete": "Apagar este arquivo",
"backup_archive_download": "Baixar este arquivo",
"backup_content": "Conteúdo da cópia de segurança",
"backup_create": "Criar uma cópia de segurança",
"backup_encryption_warning": "Não esqueça desta senha, você vai precisar dela se quiser restaurar o arquivo",
"backup_new": "Nova cópia de segurança",
"backup_optional_encryption": "Criptografia opcional",
"backups_no": "Não tem cópia de segurança",
"check": "Verificação",
"check_mx": "Registro MX",
"check_stmp": "Acesso á porta 25",
"confirm_app_change_url": "Tem certeza que quer mudar o endereço URL para acessar esta aplicação?",
"confirm_firewall_open": "Tem certeza que quer abrir a porta %s? (protocolo: %s, conexão: %s)",
"confirm_firewall_close": "Tem certeza que quer fechar a porta %s? (protocolo: %s, conexão: %s)",
"confirm_firewall_open": "Tem certeza que quer abrir a porta {port}? (protocolo: {protocol}, conexão: {connection})",
"confirm_firewall_close": "Tem certeza que quer fechar a porta {port}? (protocolo: {protocol}, conexão: {connection})",
"confirm_install_custom_app": "CUIDADO! Instalar aplicações de terceiros pode comprometer a integridade e a segurança do seu sistema. Provavelmente NÃO deveria instalar esta aplicação se não tiver certeza do que está fazendo. Quer correr esses riscos?",
"confirm_install_domain_root": "Não será mas capaz de instalar outras aplicações em %s. Quer continuar?",
"confirm_install_app_warning": "Aviso: esta aplicação pode funcionar mais não está bem integrada em Yunohost. Algumas funcionalidades como logon único e/ou cópia de segurança/restauro pode não ser disponível.",
"confirm_install_app_danger": "CUIDADO! Esta aplicação é ainda experimental (pode nem funcionar) e é provável que vai quebrar seu sistema. Certamente NÃO deveria instalá-lo a menos que saiba o que está fazendo. Está pronto a tomar este risco?",
"confirm_install_domain_root": "Não será mas capaz de instalar outras aplicações em {domain}. Quer continuar?",
"confirm_install_app_lowquality": "Aviso: esta aplicação pode funcionar mais não está bem integrada em Yunohost. Algumas funcionalidades como logon único e/ou cópia de segurança/restauro pode não ser disponível.",
"confirm_install_app_inprogress": "CUIDADO! Esta aplicação é ainda experimental (pode nem funcionar) e é provável que vai quebrar seu sistema. Certamente NÃO deveria instalá-lo a menos que saiba o que está fazendo. Está pronto a tomar este risco?",
"confirm_migrations_skip": "No é recomendado pular as migrações. Tem certeza que o quer fazer?",
"confirm_restore": "Tem certeza que quer restaurar %s?",
"confirm_service_start": "Tem certeza que quer iniciar %s?",
"confirm_service_stop": "Tem certeza que quer parar %s?",
"confirm_service_enable": "Tem certeza que quer ativar %s?",
"confirm_service_disable": "Tem certeza que quer desativar %s?",
"confirm_restore": "Tem certeza que quer restaurar {name}?",
"confirm_service_start": "Tem certeza que quer iniciar {name}?",
"confirm_service_stop": "Tem certeza que quer parar {name}?",
"confirm_update_apps": "Tem certeza que quer atualizar todas as aplicações?",
"confirm_update_system": "Tem certeza que quer atualizar todos os pacotes do sistema?",
"confirm_update_specific_app": "Tem certeza que quer atualizar %s?",
"confirm_update_specific_app": "Tem certeza que quer atualizar {app}?",
"confirm_upnp_enable": "Tem certeza que quer ativar UPnP?",
"confirm_upnp_disable": "Tem certeza que quer desativar UPnP?",
"confirm_reboot_action_reboot": "Tem certeza que quer reiniciar seu servidor?",
"confirm_reboot_action_shutdown": "Tem certeza que quer desligar seu servidor?",
"copy": "Copiar",
"created_at": "Criado em",
"current_maintainer_title": "Mantenedor atual deste pacote",
"domain_dns_conf_is_just_a_recommendation": "Esta página mostra a configuração *recomendada*. *Não* configura o DNS para você. Você é responsável pela configuração da sua zona DNS com seu registrador DNS de acordo com esta recomendação.",
"diagnosis": "Diagnóstico",
"diagnosis_hide_private": "Mostrar o diagnóstico sem os dados privados",
"diagnosis_view_private": "Mostrar o diagnóstico com os dados privados",
"diagnosis_with_private": "Diagnóstico com os dados privados",
"disabled": "Desativado",
"dns": "DNS",
"domain_default_longdesc": "Este é seu domínio predefinido.",
"domain_delete_longdesc": "Apagar este domínio",
"domain_dns_config": "Configuração DNS",
"domain_dns_longdesc": "Ver a configuração DNS",
"domain_visit": "Visitar",
"domain_visit_url": "Visitar %s",
"domain_visit_url": "Visitar {url}",
"download": "Baixar",
"enabled": "Ativado",
"hook_conf_ynh_mysql": "Senha MySQL",
"hook_conf_ynh_firewall": "Firewall",
"hook_conf_ynh_certs": "Certificados SSL",
@ -311,13 +173,13 @@
"hook_adminjs_group_configuration": "Configurações do sistema",
"home": "Início",
"permissions": "Permissões",
"app_state_low_quality_explanation": "Esta aplicação deve funcionar, mas ainda pode conter problemas, ou não está completamente integrada com YunoHost, ou não está de acordo com boas práticas.",
"app_state_low_quality": "baixa qualidade",
"app_state_lowquality_explanation": "Esta aplicação deve funcionar, mas ainda pode conter problemas, ou não está completamente integrada com YunoHost, ou não está de acordo com boas práticas.",
"app_state_lowquality": "baixa qualidade",
"all": "Todos",
"error_server_unexpected": "Erro inesperado no servidor (%s)",
"error_server_unexpected": "Erro inesperado no servidor",
"diagnosis_experimental_disclaimer": "Esteja ciente de que a ferramenta de diagnóstico ainda é experimental e está em fase de aperfeiçoamento, e pode não ser totalmente confiável.",
"details": "Detalhes",
"catalog": "Catálogo",
"configuration": "Configuração",
"confirm_service_restart": "Tem certeza que deseja reiniciar %s?"
"confirm_service_restart": "Tem certeza que deseja reiniciar {name}?"
}

View file

@ -2,145 +2,82 @@
"action": "Действие",
"add": "Добавить",
"administration_password": "Пароль администратора",
"allowed_users": "Разрешенные пользователи",
"api_not_responding": "API не отвечает",
"app_access": "Доступ",
"app_access_addall_btn": "Включить доступ ко всем",
"app_access_addall_desc": "Все существующие пользователи будут иметь доступ к %s.",
"app_access_clearall_btn": "Очистить доступы",
"app_access_clearall_desc": "Каждый пользователь будет иметь доступ к %s.",
"app_access_removeall_btn": "Удалить все доступы",
"app_access_removeall_desc": "Пользователи не получат доступа к %s.",
"app_access_title": "%s доступ",
"app_debug_no_logs": "Журналы приложений недоступны",
"app_debug_tab": "Отображать отладочную информацию",
"app_info_access_desc": "Управление доступом пользователей. Разрешенные пользователи: %s",
"remove": "Удалить",
"app_info_default_desc": "Перенаправить домен root в это приложение (%s).",
"app_info_default_desc": "Перенаправить домен root в это приложение ({domain}).",
"app_info_uninstall_desc": "Удалите это приложение.",
"app_install_cancel": "Установка отменена.",
"app_install_custom_no_manifest": "Нет файла manifest.json",
"app_list": "Список приложений",
"app_make_default": "Использовать по умолчанию",
"app_repository": "Происхождение приложения: ",
"app_state": "Состояние приложения: ",
"app_state_inprogress": "Выполняется",
"app_state_validated": "Проверенный",
"app_state_working": "Работает",
"password": "Пароль",
"app_info_debug_desc": "Отображать отладочную информацию для этого приложения.",
"cancel": "Отменить",
"login": "Логин",
"logout": "Выйти",
"ok": "ОК",
"app_info_changelabel_desc": "",
"app_info_changeurl_desc": "Изменить url доступа к этому приложению (домен и/ли путь).",
"app_info_change_url_disabled_tooltip": "Эта опция ещё не реализована в этом приложении",
"app_no_actions": "Это приложение не осуществляет никаких действий",
"app_state_notworking": "Не работает",
"application": "Приложение",
"applications": "Приложения",
"archive_empty": "Пустой архив",
"available": "Доступный",
"available_apps": "Доступные приложения",
"backup": "Резервное копирование",
"backup_action": "Резервное копирование",
"backup_archive_copy": "Скопируйте этот архив в другое хранилище",
"backup_archive_delete": "Удалите этот архив",
"backup_archive_download": "Загрузите этот архив",
"backup_content": "Содержание резервного копирования",
"backup_create": "Сделайте резервное копирование",
"backup_encryption_warning": "Не забудьте этот пароль, он понадобится вам, если вы решите восстановить архив",
"backup_new": "Новое резервное копирование",
"backup_optional_encryption": "Шифрование опционально",
"backup_type": "Тип",
"backups_no": "Без резервного сохранения",
"begin": "Начать",
"both": "Оба",
"check": "Проверить",
"check_stmp": "доступ к порту 25",
"close": "Закрыть",
"confirm_access_add": "Вы хотите предоставить права доступа к %s всем пользователям?",
"confirm_access_clear": "Вы хотите удалить все права доступа к %s ?",
"logged_out": "Вы вышли из системы",
"app_change_url": "Сменить URL",
"confirm_access_remove_user": "Вы хотите удалить права доступа к %s1 для %s2?",
"confirm_app_change_url": "Вы хотите изменить URL доступа к приложению?",
"confirm_app_default": "Вы хотите сделать это приложение приложением по умолчанию?",
"confirm_change_maindomain": "Вы хотите изменить главный домен?",
"confirm_delete": "Вы хотите удалить %s1 ?",
"confirm_firewall_open": "Вы хотите открыть порт %s1 ? (протокол %s2, соединение %s3)",
"confirm_firewall_close": "Вы хотите закрыть порт %s1 ? (протокол %s2, соединение %s3)",
"confirm_delete": "Вы хотите удалить {name}1 ?",
"confirm_firewall_open": "Вы хотите открыть порт {port}1 ? (протокол {protocol}2, соединение {connection}3)",
"confirm_firewall_close": "Вы хотите закрыть порт {port}1 ? (протокол {protocol}2, соединение {connection}3)",
"confirm_install_custom_app": "Установка сторонних приложений может повредить безопасности вашей системы. Установка на вашу ответственность.",
"confirm_install_domain_root": "Вы больше не сможете устанавливать приложения на %s1. Продолжить?",
"confirm_restore": "Вы хотите восстановить %s1 ?",
"confirm_service_start": "Вы хотите начать %s1 ?",
"confirm_service_stop": "Вы уверены, что хотите остановить %s1 ?",
"confirm_service_enable": "Вы уверены, что хотите активировать %s1 ?",
"confirm_service_disable": "Вы уверены, что хотите отключить %s1 ?",
"confirm_uninstall": "Вы уверены, что хотите удалить %s1 ?",
"confirm_install_domain_root": "Вы больше не сможете устанавливать приложения на {domain}1. Продолжить?",
"confirm_restore": "Вы хотите восстановить {name}1 ?",
"confirm_service_start": "Вы хотите начать {name}1 ?",
"confirm_service_stop": "Вы уверены, что хотите остановить {name}1 ?",
"confirm_uninstall": "Вы уверены, что хотите удалить {name}1 ?",
"confirm_update_apps": "Вы уверены, что хотите обновить все приложения?",
"confirm_update_packages": "Вы уверены, что хотите обновить все пакеты?",
"confirm_update_specific_app": "Вы уверены, что хотите обновить %s1 ?",
"confirm_update_specific_app": "Вы уверены, что хотите обновить {app}1 ?",
"confirm_upnp_enable": "Вы уверены, что хотите включить UPnP?",
"confirm_upnp_disable": "Вы уверены, что хотите отключить UPnP?",
"confirm_reboot_action_reboot": "Вы уверены, что хотите перезагрузить ваш сервер?",
"confirm_reboot_action_shutdown": "Вы уверены, что хотите выключить ваш сервер?",
"connection": "Соединение",
"copy": "Копировать",
"count_min": "%s1 мин",
"cpu_load": "Загрузка процессора",
"created_at": "Создано в",
"cumulative_usage": "Общее потребление",
"custom_app_install": "Установка пользовательских приложений",
"custom_app_url_only_github": "В настоящее время только из GitHub",
"default": "По умолчанию",
"delete": "Удалить",
"description": "Описание",
"backup_optional_password": "Пароль опционально",
"confirm_access_remove_all": "Вы уверены, что хотите удалить все доступы к %s 1 ?",
"domain_dns_conf_is_just_a_recommendation": "Эта страница показывает вам *рекомендуемую* конфигурацию. Она *не* создаёт для вас конфигурацию DNS. Вы должны сами конфигурировать зону вашего DNS у вашего регистратора в соответствии с этой рекомендацией.",
"diagnosis": "Диагноз",
"diagnosis_hide_private": "Покажите диагноз без личных данных",
"diagnosis_view_private": "Покажите диагноз с личными данными",
"diagnosis_with_private": "Диагноз с личными данными",
"disable": "Отключить",
"disabled": "Отключено",
"disk": "Диск",
"dns": "DNS",
"domain": "Домен",
"domain_add": "Добавить домен",
"domain_add_dyndns_doc": "... и я хочу использовать сервис для динамического DNS.",
"domain_add_panel_with_domain": "У меня уже есть доменное имя…",
"domain_add_panel_without_domain": "У меня нет доменного имени…",
"domain_default": "Домен по умолчанию",
"install_custom_app_appslists_info": "Вы можете использовать альтернативный список приложений, чтобы установить другие приложения, созданные сообществом YonoHost.",
"domain_default_desc": "Домен по умолчанию — это домен, где пользователи вводят логин и пароль.",
"domain_default_longdesc": "Это ваш домен по умолчанию.",
"domain_delete_longdesc": "Удалить этот домен",
"domain_dns_config": "Конфигурация DNS",
"domain_dns_longdesc": "Посмотреть конфигурацию DNS",
"domain_list": "Список доменов",
"domain_name": "Имя домена",
"domain_select": "Выбрать домен",
"domain_visit": "Посетить",
"domain_visit_url": "Посетить %s1",
"domain_visit_url": "Посетить {url}1",
"domains": "Домены",
"download": "Загрузить",
"enable": "Включить",
"enabled": "Включено",
"error_modify_something": "Вы должны что-то изменить",
"error_occured": "Произошла ошибка, попробуйте снова",
"error_server": "Ошибка сервера",
"error_server_unexpected": "Неожиданная ошибка сервера (%s1)",
"everyone_has_access": "Все имеют доступ.",
"error_server_unexpected": "Неожиданная ошибка сервера",
"experimental_warning": "Внимание: это экспериментальное приложение работает нестабильно, вы можете использовать его, только если понимаете, что делаете.",
"filesystem": "Файловая система",
"firewall": "Файрволл",
"footer_version": "Создано<a href='https://yunohost.org'></a> %s (%s).",
"form_input_example": "Например: %s",
"free": "Свободный",
"fs_type": "Тип файловой системы",
"footer_version": "Создано<a href='https://yunohost.org'></a> {version} ({repo}).",
"form_input_example": "Например: {example}",
"home": "Дом",
"hook_adminjs_group_configuration": "Конфигурация",
"hook_conf_cron": "Постоянные задачи",
@ -156,53 +93,29 @@
"hook_data_home_desc": "Пользовательские данные находятся в /home/USER",
"hook_data_mail": "Почта",
"hook_data_mail_desc": "Почта на сервере",
"hostname": "Имя хоста",
"id": "ID",
"inactive": "Неактивен",
"infos": "Информация",
"install": "Установить",
"install_name": "Установить %s",
"install_name": "Установить {id}",
"install_time": "Время установки",
"installation_complete": "Установка завершена",
"installed": "Установлено",
"installed_apps": "Установленные приложения",
"installing": "Устанавливаю",
"interface": "Интерфейс",
"io": "I/O",
"ipv4": "IPv4",
"ipv6": "IPv6",
"loading": "Загружается…",
"log": "Лог",
"logged_in": "Вы вошли",
"mailbox_quota_description": "Например, 700M это CD, 4700M это DVD.",
"mailbox_quota_placeholder": "Оставьте пустым или поставьте 0, чтобы отключить.",
"manage_apps": "Управление приложениями",
"manage_domains": "Управление доменами",
"manage_users": "Управление пользователями",
"memory": "Память",
"menu": "Меню",
"migrations": "Миграция",
"migrations_done": "Предыдущие миграции",
"migrations_no_done": "Нет предыдущих миграций",
"monitoring": "Мониторинг",
"monitoring_disabled": "Мониторинг не включён.",
"myserver": "мой сервер",
"myserver_org": "myserver.org",
"network": "Сеть",
"next": "Следующий",
"no": "Нет",
"no_installed_apps": "Нет установленных приложений.",
"no_log": "Лог отсутствует.",
"no_user_to_add": "Нет больше пользователей, которых можно добавить.",
"open": "Открыть",
"operations": "Действия",
"os": "ОС",
"password_confirmation": "Подтвердите пароль",
"password_description": "Пароль должен иметь минимум %s1 символов.",
"password_empty": "Поле для ввода пароля пусто",
"password_new": "Новый пароль",
"passwords_dont_match": "Пароли не совпадают",
"passwords_too_short": "Пароль слишком короткий",
"logs": "Логи",
"logs_history": "История команд, выполненных в системе",
"logs_package": "История действий с пакетами Debian",
@ -210,51 +123,26 @@
"logs_access": "Список доступов и банов",
"logs_app": "Списки приложений",
"logs_no_logs_registered": "Нет зарегистрированных логов для этой категории",
"logs_end_with_error": "Лог закончился ошибкой :",
"logs_error": "Ошибка",
"logs_ended_at": "Конец",
"logs_started_at": "Старт",
"logs_context": "Контекст",
"logs_share_with_yunopaste": "Расшарить с YunoPaste",
"logs_more": "Отразить больше линий",
"active": "Активный",
"port": "Порт",
"ports": "Порты",
"meltdown": "Вы в опасности <a target=\"_blank\" href=\"https://meltdownattack.com/\">meltdown</a> из-за критической аппаратной уязвимости. Чтобы устранить уязвимость, вы должны <a href=\"#/update\">обновить вашу систему, <a> потом <a href=\"#/tools/reboot\">перезагрузить ее, </a> чтобы загрузить новое ядро Linux.",
"appslists": "Списки приложений",
"appslists_no_lists": "Нет списков приложений",
"appslists_custom": "Пользовательский список приложений",
"appslists_manage": "Управлять списками приложений",
"appslists_confirm_remove": "Вы уверены, что хотите удалить этот список приложений?",
"appslists_info_refresh_desc": "Обновите статус приложений из этого списка.",
"appslists_info_remove_desc": "Приложения из этого списка больше не будут доступны.",
"appslists_last_update": "Последнее обновление",
"appslists_unknown_list": "Неизвестный список приложений: %s",
"appslists_community_list": "Список приложений сообщества",
"name": "Имя",
"install_community_appslists_info": "Список приложений сообщества даёт вам возможность установить приложения, созданные сообществом. <br />Полный список смотри на<a href='https://yunohost.org/apps'>yunohost.org/apps</a>.",
"install_community_appslists_warning": "Внимание! Пакеты этих приложений не являются <strong>not</strong> официальными и не созданы командой YonoHost. <br />Устанавливая эти приложения, вы сами отвечаете за последствия и рискуете крахом вашей системы.",
"validity": "",
"domain_is_eligible_for_ACME": "Для установки сертификата Lets Encrypt домен должен быть правильно сконфигурирован !",
"domain_not_eligible_for_ACME": "Этот домен не готов к установке сертификата Lets Encrypt. Пожалуйста, проверьте конфигурацию DNS и доступность HTTP сервера.",
"install_letsencrypt_cert": "Установить сертификат Let's Encrypt",
"manually_renew_letsencrypt_message": "Сертификат будет автоматически обновлён в последние 15 дней своего действия. Вы может вручную обновить его, если хотите. (Не рекомендуется).",
"manually_renew_letsencrypt": "Теперь обновить вручную",
"bit_rate": "скорость передачи данных",
"confirm_postinstall": "Вы начинаете процесс конфигурации домена %s. Это займёт несколько минут, *не прерывайте процесс*.",
"confirm_postinstall": "Вы начинаете процесс конфигурации домена {domain}. Это займёт несколько минут, *не прерывайте процесс*.",
"domain_add_dns_doc": "… я <a href='//yunohost.org/dns'>set my DNS установил мой DNS правильно</a>.",
"gateway": "Шлюз: ",
"internal_exception": "<strong>Yunohost сообщает о внутренней ошибке :/</strong><br><em>Нам очень жаль.<br>Ищите помощь на<a href=\"https://forum.yunohost.org/\">форуме</a> или <a href=\"https://chat.yunohost.org/\">в чате, </a> чтобы обсудить ситуацию, или сообщите об ошибке <a href=\"https://github.com/YunoHost/issues\">тут</a>.</em><br>Следующая информация может быть полезной для человека, помогающего вам :<h3>Action</h3><pre>%s%s</pre><h3>Traceback</h3><pre>%s</pre>",
"tools": "Инструменты",
"tools_adminpw": "Смените пароль администратора",
"tools_adminpw_confirm_placeholder": "Подтвердите новый пароль",
"tools_adminpw_current": "Действующий пароль",
"tools_adminpw_current_placeholder": "Введите действующий пароль",
"tools_adminpw_new_placeholder": "Введите новый пароль",
"tools_security_feed": "Предупреждения безопасности",
"tools_security_feed_no_items": "Нет предупреждений безопасности",
"tools_security_feed_subscribe_rss": "Подпишитесь на RSS предупреждений безопасности",
"tools_security_feed_view_items": "Посмотрите все предупреждения безопасности",
"tools_reboot": "Перезагрузите сервер",
"tools_reboot_btn": "Перезагрузить",
"tools_reboot_done": "Перезагрузка...",
@ -264,21 +152,13 @@
"tools_shutdown_done": "Выключается...",
"tools_shuttingdown": "Ваш сервер выключен. Пока ваш сервер выключен, вы не можете использовать панель управления.",
"tools_shutdown_reboot": "Выключить/Перезагрузить",
"total": "Все вместе",
"transmission": "Передача",
"udp": "UDP",
"unauthorized": "Неавторизованный",
"uninstall": "Удалить",
"unknown_action": "Неизвестное действие %s",
"unknown_argument": "Неизвестный аргумент : %s",
"upload": "",
"upload_archive": "Сгрузить архив",
"upnp": "UPnP",
"upnp_disabled": "UPnP отключён.",
"upnp_enabled": "UPnP включён.",
"uptime": "Время действия",
"url": "URL",
"used": "Использовано",
"user_email": "Email",
"user_emailaliases": "Почтовый алиас",
"user_emailforward": "Пересылка почты",
@ -286,17 +166,14 @@
"user_interface_link": "Интерфейс пользователя",
"user_mailbox_use": "Пространство, используемое почтовым ящиком",
"user_new_forward": "newforward@myforeigndomain.org",
"user_new_mail": "newmail@mydomain.org",
"user_username": "Имя пользователя",
"user_username_edit": "Редактировать аккаунт %ss",
"user_username_edit": "Редактировать аккаунт {name}s",
"users": "Пользователи",
"users_list": "Список пользователей",
"users_new": "Новый пользователь",
"users_no": "Нет пользователей.",
"versions": "Версия",
"view_user_profile": "Смотрите профиль %s's",
"warning_first_user": "Сначала вы должны <a href='#/users/create' class='alert-link'>создать пользователя</a> first.",
"write": "Писать",
"words": {
"default": "По умолчанию"
},
"wrong_password": "Неправильный пароль",
"yes": "Да",
"certificate_alert_not_valid": "ОПАСНО: установленный сертификат не действителен! HTTPS не будет работать!",
@ -306,67 +183,41 @@
"certificate_alert_great": "Прекрасно! Вы используете действующий сертификат Lets Encrypt !",
"certificate_alert_unknown": "Неизвестный статус",
"certificate_manage": "Управлять сертификатом SSL",
"certificate_old_letsencrypt_app_conflict": "Приложение letsencrypt сейчас установлено и конфликтует с этой функцией. Пожалуйста, удалите приложение и используйте новый интерфейс управления сертификатом.",
"ssl_certificate": "Сертификат SSL",
"confirm_cert_install_LE": "Вы уверены, что хотите установить сертификат Lets Encrypt для этого домена ?",
"confirm_cert_manual_renew_LE": "Вы уверены, что хотите вручную обновить сертификат Lets Encrypt для этого домена?",
"certificate": "Сертификат",
"certificate_status": "Статус сертификата",
"mount_point": "Точка монтирования",
"no_allowed_users": "Нет разрешённых пользователей.",
"non_compatible_api": "Несовместимый API",
"path": "Путь",
"logs_operation": "Действие в системе выполнено YonoHost",
"logs_service": "Журналы сервисов",
"logs_path": "Путь",
"path_url": "Путь",
"postinstall_domain": "Это первое доменное имя, связанное с сервером YonoHost, то есть имя, которым будут пользоваться пользователи вашего сервера, чтобы попасть на портал аутентификации. Оно будет видно каждому, выбирайте его тщательно.",
"postinstall_intro_1": "Поздравляем! YunoHost успешно установлен.",
"postinstall_intro_2": "Осталось сделать две настройки конфигурации, чтобы активировать службы вашего сервера.",
"postinstall_intro_3": "Вы можете получить больше информации, <a href='//yunohost.org/postinstall' target='_blank'>посетив страницу документации</a>",
"postinstall_password": "Этот пароль нужен для того, чтобы управлять вашим сервером. Не торопитесь, проявите мудрость, создавая его.",
"previous": "Предыдущий",
"process": "Процесс",
"protocol": "Протокол",
"ram": "RAM",
"read": "Читать",
"read_more": "Читать еще",
"reception": "Приём",
"refresh_app_list": "Обновить список",
"remove_access": "Удалить доступ",
"restore": "Восстановить",
"run": "Включить",
"running": "Выполняется",
"save": "Сохранить",
"select_user": "Выбрать пользователя",
"service_start_on_boot": "Запуск при загрузке ",
"service_status": "Статус: ",
"services": "Службы",
"services_list": "Список служб",
"set_default": "Установить по умолчанию",
"size": "Размер",
"skip": "Пропустить",
"start": "Начать",
"started_at": "Начало на:",
"status": "Статус",
"stop": "Стоп",
"storage_create": "Добавить удаленное хранилище",
"storages_new": "Новое удаленное хранилище",
"storages_no": "Нет хранилищ.",
"swap": "Подкачка",
"system": "Система",
"system_apps": "Приложения",
"system_apps_nothing": "Нет приложений для обновления.",
"system_delayed_upgrade_warning": "<b>%s</b> будет обновлён автоматически в течение часа.",
"system_packages": "Пакеты",
"system_packages_nothing": "Нет пакетов, нуждающихся в обновлении.",
"system_update": "Обновление системы",
"system_upgrade": "Обновление системы",
"system_upgrade_btn": "Обновление",
"system_upgrade_all_applications_btn": "Обновление всех приложений",
"system_upgrade_all_packages_btn": "Обновление всех пакетов",
"tcp": "TCP",
"time_since_update": "Время после обновления: ",
"usage": "Использование",
"certificate_authority": "Центр сертификации"
}

View file

@ -1,170 +1,103 @@
{
"action": "Åtgärd",
"active": "Aktiv",
"services": "Tjänster",
"protocol": "Protokoll",
"license": "Licens",
"hook_conf_ssowat": "SSOwat",
"advanced": "Avancerat",
"from_to": "mellan %s och %s",
"from_to": "mellan {0} och {1}",
"hook_conf_ynh_currenthost": "Nuvarande huvuddomän",
"only_highquality_apps": "Endast högkvalitativa applikationer",
"only_decent_quality_apps": "Endast applikationer av god kvalitet",
"request_help": "behöver hjälp",
"domain_select": "Välj domän",
"installed": "Installerad",
"domain_add_dyndns_doc": "… och jag vill använda en dynamisk DNS-tjänst.",
"myserver_org": "minserver.org",
"ipv4": "IPv4",
"ram": "Arbetsminne",
"inactive": "Inaktiv",
"only_working_apps": "Endast fungerande applikationer",
"restore": "Återskapa",
"gateway": "Gateway: ",
"installing": "Installerar",
"migrations": "Förflyttningar",
"services_list": "Lista över tjänster",
"logs_ended_at": "Slut",
"firewall": "Brandvägg",
"manage_users": "Hantera användare",
"mailbox_quota_description": "Som jämförelse är 700 MB en CD-skiva och 4700 MB en DVD.",
"app_info_access_desc": "Hantera användaråtkomst. Tillåtna användare: %s",
"domain_add": "Lägg till domän",
"app_access_addall_btn": "Ge alla åtkomst",
"logs_share_with_yunopaste": "Dela med YunoPaste",
"logout": "Logga ut",
"enable": "Aktivera",
"logged_in": "Inloggad",
"domain_default_longdesc": "Detta är din standarddomän.",
"next": "Nästa",
"app_change_label": "Redigera etikett",
"select_all": "Markera alla",
"no": "Nej",
"domain_visit_url": "Besök %s",
"footer_version": "Drivs av <a href='https://yunohost.org'>YunoHost</a> %s (%s).",
"domain_visit_url": "Besök {url}",
"footer_version": "Drivs av <a href='https://yunohost.org'>YunoHost</a> {version} ({repo}).",
"domains": "Domäner",
"app_access_clearall_btn": "Neka alla åtkomst",
"domain_list": "Lista över domäner",
"hook_conf_ynh_mysql": "MySQL-lösenord",
"administration_password": "Administratörslösenord",
"remove": "Ta bort",
"hook_adminjs_group_configuration": "Systeminställningar",
"hook_data_home": "Användardata",
"app_info_debug_desc": "Visa felsökningsinformation för den här applikationen.",
"select_user": "Välj användare",
"cancel": "Avbryt",
"memory": "Minne",
"mailbox_quota_placeholder": "Lämna tomt eller skriv 0 för att avaktivera.",
"select_none": "Avmarkera alla",
"search_for_apps": "Sök efter applikationer …",
"running": "Körs",
"service_log": "Logg för %s",
"postinstall_intro_1": "Grattis! YunoHost har installerats korrekt.",
"password_empty": "Lösenordsfältet är tomt",
"app_info_changelabel_desc": "Redigera applikationsetikett i portalen.",
"domain_dns_config": "DNS-inställningar",
"installation_complete": "Installation färdig",
"logs_app": "Applikationsloggar",
"port": "Port",
"app_debug_no_logs": "Det går inte att komma åt applikationens loggar",
"label_for_manifestname": "Etikett för %s",
"app_change_url": "Redigera länk",
"label_for_manifestname": "Etikett för {name}",
"migrations_pending": "Kommande förflyttningar",
"infos": "Information",
"app_access_addall_desc": "Alla existerande användare kommer kunna komma åt %s.",
"domain_add_panel_with_domain": "Jag har redan ett domännamn …",
"domain_delete_longdesc": "Radera den här domänen",
"everyone_has_access": "Alla har åtkomst.",
"run": "Kör",
"hook_conf_ynh_certs": "SSL-certifikat",
"hook_conf_ynh_firewall": "Brandvägg",
"logged_out": "Utloggad",
"no_installed_apps": "Inga installerade applikationer.",
"fs_type": "Filsystem",
"mode": "Läge",
"password": "Lösenord",
"install_time": "Tidpunkt för installation",
"label": "Etikett",
"password_new": "Nytt lösenord",
"level": "nivå",
"passwords_too_short": "Lösenordet är för kort",
"hook_conf_nginx": "Nginx",
"logs_service": "Tjänstloggar",
"ipv6": "IPv6",
"manage_apps": "Hantera applikationer",
"service_description": "Beskrivning:",
"local_archives": "Lokala arkiv",
"install": "Installera",
"download": "Ladda ner",
"public_ip": "Offentlig IP-adress: ",
"no_user_to_add": "Inga fler användare att lägga till.",
"log": "Logg",
"open": "Öppen",
"hook_data_home_desc": "Användardata i /home/ANVÄNDARE",
"service_start_on_boot": "Kör vid uppstart: ",
"migrations_no_pending": "Inga kommande förflyttningar",
"read_more": "Läs mer",
"hook_conf_ssh": "SSH",
"domain_default_desc": "Standarddomänen är den domän du vill att användare loggar in på.",
"non_compatible_api": "Icke-kompatibelt API",
"loading": "Hämtar …",
"app_access": "Åtkomst",
"logs_context": "Sammanhang",
"hook_conf_xmpp": "XMPP",
"logs_error": "Fel",
"home": "Hem",
"logs_path": "Sökväg",
"add": "Lägg till",
"install_name": "Installera %s",
"install_name": "Installera {id}",
"domain_add_dns_doc": "… och jag har <a href='//yunohost.org/dns'>konfigurerat min DNS korrekt</a>.",
"interface": "Gränssnitt",
"error_server_unexpected": "Oväntat serverfel (%s)",
"error_server_unexpected": "Oväntat serverfel",
"previous": "Föregående",
"no_allowed_users": "Inga tillåtna användare.",
"read": "Läs",
"save": "Spara",
"hook_data_mail": "E-post",
"app_access_clearall_desc": "Alla användare kommer kunna komma åt %s.",
"hook_conf_ldap": "LDAP-databas",
"service_status": "Status: ",
"ok": "Ok",
"no_log": "Ingen logg.",
"migrations_done": "Tidigare förflyttningar",
"id": "ID",
"domain_name": "Domännamn",
"network": "Nätverk",
"logs_more": "Visa fler rader",
"domain_dns_longdesc": "Visa DNS-inställningar",
"domain_default": "Standarddomän",
"installed_apps": "Installerade applikationer",
"monitoring": "Övervakning",
"domain_add_panel_without_domain": "Jag har inte något domännamn …",
"monitoring_disabled": "Övervakning är inte aktiverad.",
"migrations_no_done": "Inga tidigare förflyttningar",
"logs": "Loggar",
"hostname": "Värdnamn",
"local_ip": "Lokal IP-adress",
"login": "Logga in",
"all_apps": "Alla applikationer",
"ports": "Portar",
"domain": "Domän",
"io": "I/O",
"path": "Sökväg",
"passwords_dont_match": "Lösenorden stämmer inte överens",
"path_url": "Sökväg",
"password_confirmation": "Lösenordsbekräftelse",
"app_debug_tab": "Visa information för felsökning",
"domain_visit": "Besök",
"logs_started_at": "Start",
"enabled": "Aktiverad",
"filesystem": "Filsystem",
"myserver": "minserver",
"menu": "Meny",
"manage_domains": "Hantera domäner",
"operations": "Handlingar",
"os": "Operativsystem",
"error_server": "Serverfel",
"refresh_app_list": "Uppdatera lista",
"form_input_example": "Exempel: %s",
"form_input_example": "Exempel: {example}",
"dns": "DNS"
}

View file

@ -0,0 +1,69 @@
{
"add": "Ekle",
"administration_password": "Yönetici parolası",
"api_not_responding": "YunoHost API'si yanıt vermiyor. Belki 'yunohost-api' çalışmıyor veya yeniden başlatıldı?",
"both": "İkisi birden",
"close": "Kapat",
"confirm_change_maindomain": "Ana domain'ininizi değiştirmek istediğinizden emin misiniz ?",
"confirm_delete": "{name}'i silmek istediğinize emin misiniz ?",
"confirm_uninstall": "{name}'i kaldırmak istediğinizden emin misiniz ?",
"delete": "Sil",
"description": "Açıklama",
"disable": "Devredışı bırak",
"domain_name": "Domain ismi",
"domains": "Domainler",
"enable": "Devreye al",
"error_modify_something": "Bir şeyleri değiştirmelisiniz",
"home": "Başlangıç",
"id": "ID",
"infos": "Bilgiler",
"installation_complete": "Yükleme başarılı",
"installed": "Yüklendi",
"ipv4": "IPv4",
"ipv6": "IPv6",
"login": "Giriş",
"logout": ıkış",
"myserver": "sunucum",
"no": "Hayır",
"open": "Aç",
"operations": "İşlemler",
"password": "Parola",
"password_confirmation": "Parola onaylandı",
"save": "Kaydet",
"set_default": "Varsayılanı ayarla",
"start": "Başlat",
"status": "Durum",
"stop": "Durdur",
"tcp": "TCP",
"udp": "UDP",
"unauthorized": "Yetkisiz",
"upnp": "UPnP",
"url": "URL",
"words": {
"default": "Varsayılan"
},
"wrong_password": "Yanlış parola",
"yes": "Evet",
"ok": "Tamam",
"app_info_access_desc": "Bu uygulamaya şuan erişimi olan gruplara / kullanıcılar:",
"all_apps": "Tüm uygulamalar",
"all": "Tümü",
"action": "Eylem",
"app_state_notworking_explanation": "Bu uygulamanın bu geliştiricisi 'çalışmıyor' olarak ilan etti. SİSTEMİNİZİ KIRACAK!",
"app_install_custom_no_manifest": "Manifest.json dosyası yok",
"app_state_inprogress_explanation": "Bu uygulamanın bu sürdürücü, bu uygulamanın henüz üretim kullanımına hazır olmadığınııkladı. DİKKATLİ OL!",
"app_state_highquality_explanation": "Bu uygulama YunoHost ile iyi entegre edilmiştir. YunoHost uygulama ekibi tarafından hakemli bir incelemedir. Güvenli olması ve uzun vadede korunması beklenebilir.",
"last_ran": "Son sefer:",
"app_state_highquality": "yüksek kalite",
"app_info_uninstall_desc": "Bu uygulamayı kaldırın.",
"app_state_lowquality": "Düşük kalite",
"app_state_lowquality_explanation": "Bu uygulama işlevsel olabilir, ancak yine de sorunlar içerebilir veya YunoHost ile tamamen entegre değildir veya iyi uygulamalara uymaz.",
"purge_user_data_checkbox": "{name} verileri temizlensin mi? (Bu işlem ana ve posta dizinlerinin içeriğini silecektir.)",
"app_info_change_url_disabled_tooltip": "Bu özellik bu uygulamada henüz uygulanmadı",
"app_state_notworking": "çalışmıyor",
"app_info_default_desc": "Alan adı kökünü bu uygulamaya yönlendirin (% s).",
"app_state_inprogress": "Henüz çalışmıyor",
"app_info_changeurl_desc": "Bu uygulamanın erişim URL'sini değiştirin (alan adı ve / veya yol).",
"app_make_default": "Varsayılan yap",
"app_no_actions": "Bu uygulamanın herhangi bir eylemi yok"
}

View file

@ -1,27 +1,17 @@
{
"administration_password": "管理密码",
"advanced": "高级",
"all": "全部",
"active": "活跃",
"all_apps": "全部应用",
"app_change_url": "更改URL",
"app_change_label": "更改标签",
"add": "添加",
"action": "动作",
"logged_out": "登出",
"cancel": "取消",
"ok": "好",
"password": "密码",
"logged_in": "登录",
"configuration": "配置",
"close": "关闭",
"check": "检查",
"catalog": "目录",
"both": "同时",
"begin": "开始",
"backups_no": "无备份",
"backup_optional_password": "可选密码",
"backup_optional_encryption": "可选加密",
"backup_new": "新备份",
"backup_create": "创建一个备份",
"backup_content": "备份内容",
@ -29,19 +19,16 @@
"backup": "备份",
"applications": "应用程序",
"app_state_working": "工作",
"app_state_high-quality": "高质量",
"app_state_highquality": "高质量",
"app_state_notworking": "不工作",
"app_make_default": "设为默认",
"app_install_custom_no_manifest": "manifest.json文件不存在",
"app_install_cancel": "安装已取消。",
"app_info_uninstall_desc": "删除此应用程序。",
"app_info_default_desc": "重定向域根到这个应用(%s。",
"app_info_changelabel_desc": "在门户中修改应用标签。",
"app_info_default_desc": "重定向域根到这个应用({domain})。",
"unignore": "取消忽略",
"last_ran": "最近一次运行:",
"app_info_change_url_disabled_tooltip": "此应用尚未实现该功能",
"archive_empty": "空存档",
"backup_archive_delete": "删除这个存档",
"app_state_low_quality": "低质量",
"app_state_lowquality": "低质量",
"app_state_inprogress": "暂不工作"
}

View file

@ -0,0 +1,86 @@
// date-fns locales can be found here : https://github.com/date-fns/date-fns/tree/master/src/locale
export default {
ar: {
name: 'عربي'
},
bn_BD: {
name: 'বাংলা',
dateFnsLocale: 'bn'
},
br: {
name: 'Brezhoneg',
dateFnsLocale: 'fr'
},
ca: {
name: 'Català'
},
cs: {
name: 'Čeština'
},
de: {
name: 'Deutsch'
},
el: {
name: 'Eλληνικά'
},
en: {
name: 'English',
dateFnsLocale: 'en-GB'
},
eo: {
name: 'Esperanto'
},
es: {
name: 'Español'
},
eu: {
name: 'Euskara'
},
fr: {
name: 'Français'
},
hi: {
name: 'हिन्दी'
},
hu: {
name: 'Magyar'
},
it: {
name: 'Italiano'
},
nb_NO: {
name: 'Norsk bokmål',
dateFnsLocale: 'nb'
},
ne: {
name: 'नेपाली',
dateFnsLocale: 'en-GB'
},
nl: {
name: 'Nederlands'
},
oc: {
name: 'Occitan',
dateFnsLocale: 'ca'
},
pl: {
name: 'Polski'
},
pt: {
name: 'Português'
},
ru: {
name: 'Русский'
},
sv: {
name: 'Svenska'
},
tr: {
name: 'Türkçe'
},
zh_Hans: {
name: '简化字',
dateFnsLocale: 'zh-CN'
}
}

48
app/src/main.js Normal file
View file

@ -0,0 +1,48 @@
import Vue from 'vue'
import App from './App.vue'
import BootstrapVue from 'bootstrap-vue'
import i18n from './i18n'
import router from './router'
import store from './store'
Vue.config.productionTip = false
// Styles are imported in `src/App.vue` <style>
Vue.use(BootstrapVue, {
BSkeleton: { animation: 'none' },
BAlert: { show: true },
BBadge: { pill: true },
BModal: {
bodyBgVariant: 'warning',
centered: true,
bodyClass: ['font-weight-bold', 'rounded-top']
}
})
// Ugly wrapper for `$bvModal.msgBoxConfirm` to set default i18n button titles
// FIXME find or wait for a better way
Vue.prototype.$askConfirmation = function (message, props) {
return this.$bvModal.msgBoxConfirm(message, {
okTitle: this.$i18n.t('yes'),
cancelTitle: this.$i18n.t('cancel'),
...props
})
}
// Register global components
const requireComponent = require.context('@/components/globals', true, /\.(js|vue)$/i)
// For each matching file name...
requireComponent.keys().forEach((fileName) => {
// Get the component
const component = requireComponent(fileName).default
// Globally register the component
Vue.component(component.name, component)
})
new Vue({
i18n,
router,
store,
render: h => h(App)
}).$mount('#app')

39
app/src/router/index.js Normal file
View file

@ -0,0 +1,39 @@
import Vue from 'vue'
import VueRouter from 'vue-router'
import routes from './routes'
import store from '@/store'
Vue.use(VueRouter)
const router = new VueRouter({
// mode: 'history', // this allow all routes to be real ones (without '#')
base: process.env.BASE_URL,
routes,
scrollBehavior (to, from, savedPosition) {
// Mimics the native scroll behavior of the browser.
// This allows the user to find his way back to the scroll level of the previous/next route.
// if animations are enabled, we need to delay a bit the returned value of the saved
// scroll state because the component probably hasn't updated the window height yet.
// Note: this will only work with routes that use stored data or that has static content
if (store.getters.transitions && savedPosition) {
return new Promise(resolve => {
setTimeout(() => resolve(savedPosition), 0)
})
} else {
return savedPosition || { x: 0, y: 0 }
}
}
})
router.beforeEach((to, from, next) => {
// Allow if connected or route is not protected
if (store.getters.connected || to.meta.noAuth) {
next()
} else {
store.dispatch('DISCONNECT', to)
}
})
export default router

413
app/src/router/routes.js Normal file
View file

@ -0,0 +1,413 @@
/**
* routes module.
* @module router/routes
*/
// Simple views are normally imported and will be included into the main webpack entry.
// Others will be chunked by webpack so they can be lazy loaded.
// Webpack chunk syntax is:
// `() => import(/* webpackChunkName: "views/:nameOfWantedFile" */ '@/views/:ViewComponent')`
import Home from '@/views/Home'
import Login from '@/views/Login'
import ErrorPage from '@/views/ErrorPage'
import ToolList from '@/views/tool/ToolList'
const routes = [
{
name: 'home',
path: '/',
component: Home,
// Leave the empty breadcrumb as it is used by the animated transition to know which way to go
meta: { breadcrumb: [] }
},
{
name: 'login',
path: '/login',
component: Login,
meta: { noAuth: true, breadcrumb: [] }
},
/*
ERROR
*/
{
name: 'error',
path: '/error/:type',
component: ErrorPage,
props: true,
// Leave the breadcrumb
meta: { noAuth: true, breadcrumb: [] }
},
/*
POST INSTALL
*/
{
name: 'post-install',
path: '/postinstall',
component: () => import(/* webpackChunkName: "views/post-install" */ '@/views/PostInstall'),
// Leave the breadcrumb
meta: { noAuth: true, breadcrumb: [] }
},
/*
USER
*/
{
name: 'user-list',
path: '/users',
component: () => import(/* webpackChunkName: "views/user/list" */ '@/views/user/UserList'),
meta: {
args: { trad: 'users' },
breadcrumb: ['user-list']
}
},
{
name: 'user-create',
path: '/users/create',
component: () => import(/* webpackChunkName: "views/user/create" */ '@/views/user/UserCreate'),
meta: {
args: { trad: 'users_new' },
breadcrumb: ['user-list', 'user-create']
}
},
{
name: 'user-info',
path: '/users/:name',
component: () => import(/* webpackChunkName: "views/user/info" */ '@/views/user/UserInfo'),
props: true,
meta: {
args: { param: 'name' },
breadcrumb: ['user-list', 'user-info']
}
},
{
name: 'user-edit',
path: '/users/:name/edit',
component: () => import(/* webpackChunkName: "views/user/edit" */ '@/views/user/UserEdit'),
props: true,
meta: {
args: { param: 'name', trad: 'user_username_edit' },
breadcrumb: ['user-list', 'user-info', 'user-edit']
}
},
/*
GROUP
*/
{
name: 'group-list',
path: '/groups',
component: () => import(/* webpackChunkName: "views/group/list" */ '@/views/group/GroupList'),
meta: {
args: { trad: 'groups_and_permissions' },
breadcrumb: ['user-list', 'group-list']
}
},
{
name: 'group-create',
path: '/groups/create',
component: () => import(/* webpackChunkName: "views/group/create" */ '@/views/group/GroupCreate'),
meta: {
args: { trad: 'group_new' },
breadcrumb: ['user-list', 'group-list', 'group-create']
}
},
/*
DOMAIN
*/
{
name: 'domain-list',
path: '/domains',
component: () => import(/* webpackChunkName: "views/domain/list" */ '@/views/domain/DomainList'),
meta: {
args: { trad: 'domains' },
breadcrumb: ['domain-list']
}
},
{
name: 'domain-add',
path: '/domains/add',
component: () => import(/* webpackChunkName: "views/domain/add" */ '@/views/domain/DomainAdd'),
meta: {
args: { trad: 'domain_add' },
breadcrumb: ['domain-list', 'domain-add']
}
},
{
name: 'domain-info',
path: '/domains/:name',
component: () => import(/* webpackChunkName: "views/domain/info" */ '@/views/domain/DomainInfo'),
props: true,
meta: {
args: { param: 'name' },
breadcrumb: ['domain-list', 'domain-info']
}
},
{
name: 'domain-dns',
path: '/domains/:name/dns',
component: () => import(/* webpackChunkName: "views/domain/dns" */ '@/views/domain/DomainDns'),
props: true,
meta: {
args: { trad: 'dns' },
breadcrumb: ['domain-list', 'domain-info', 'domain-dns']
}
},
{
name: 'domain-cert',
path: '/domains/:name/cert-management',
component: () => import(/* webpackChunkName: "views/domain/cert" */ '@/views/domain/DomainCert'),
props: true,
meta: {
args: { trad: 'certificate' },
breadcrumb: ['domain-list', 'domain-info', 'domain-cert']
}
},
/*
APPS
*/
{
name: 'app-list',
path: '/apps',
component: () => import(/* webpackChunkName: "views/apps/list" */ '@/views/app/AppList'),
meta: {
args: { trad: 'applications' },
breadcrumb: ['app-list']
}
},
{
name: 'app-catalog',
path: '/apps/catalog',
component: () => import(/* webpackChunkName: "views/apps/catalog" */ '@/views/app/AppCatalog'),
meta: {
args: { trad: 'catalog' },
breadcrumb: ['app-list', 'app-catalog']
}
},
{
name: 'app-install',
path: '/apps/install/:id',
component: () => import(/* webpackChunkName: "views/apps/install" */ '@/views/app/AppInstall'),
props: true,
meta: {
args: { trad: 'install_name', param: 'id' },
breadcrumb: ['app-list', 'app-catalog', 'app-install']
}
},
{
name: 'app-install-custom',
path: '/apps/install-custom/:id',
component: () => import(/* webpackChunkName: "views/apps/install" */ '@/views/app/AppInstall'),
props: true,
meta: {
args: { trad: 'install_name', param: 'id' },
breadcrumb: ['app-list', 'app-catalog', 'app-install-custom']
}
},
{
name: 'app-info',
path: '/apps/:id',
component: () => import(/* webpackChunkName: "views/apps/info" */ '@/views/app/AppInfo'),
props: true,
meta: {
args: { param: 'id' },
breadcrumb: ['app-list', 'app-info']
}
},
{
name: 'app-actions',
path: '/apps/:id/actions',
component: () => import(/* webpackChunkName: "views/apps/actions" */ '@/views/app/AppActions'),
props: true,
meta: {
args: { trad: 'app_actions' },
breadcrumb: ['app-list', 'app-info', 'app-actions']
}
},
{
name: 'app-config-panel',
path: '/apps/:id/config-panel',
component: () => import(/* webpackChunkName: "views/apps/config" */ '@/views/app/AppConfigPanel'),
props: true,
meta: {
args: { trad: 'app_config_panel' },
breadcrumb: ['app-list', 'app-info', 'app-config-panel']
}
},
/*
SYSTEM UPDATE
*/
{
name: 'update',
path: '/update',
component: () => import(/* webpackChunkName: "views/update" */ '@/views/update/SystemUpdate'),
meta: {
args: { trad: 'system_update' },
breadcrumb: ['update']
}
},
/*
SERVICE
*/
{
name: 'service-list',
path: '/services',
component: () => import(/* webpackChunkName: "views/service/list" */ '@/views/service/ServiceList'),
meta: {
args: { trad: 'services' },
breadcrumb: ['service-list']
}
},
{
name: 'service-info',
path: '/services/:name',
component: () => import(/* webpackChunkName: "views/service/info" */ '@/views/service/ServiceInfo'),
props: true,
meta: {
args: { param: 'name' },
breadcrumb: ['service-list', 'service-info']
}
},
/*
TOOLS
*/
{
name: 'tool-list',
path: '/tools',
component: ToolList,
meta: {
args: { trad: 'tools' },
breadcrumb: ['tool-list']
}
},
{
name: 'tool-logs',
path: '/tools/logs',
component: () => import(/* webpackChunkName: "views/tools/logs" */ '@/views/tool/ToolLogs'),
meta: {
args: { trad: 'logs' },
breadcrumb: ['tool-list', 'tool-logs']
}
},
{
name: 'tool-log',
path: '/tools/logs/:name',
component: () => import(/* webpackChunkName: "views/tools/log" */ '@/views/tool/ToolLog'),
props: true,
meta: {
args: { param: 'name' },
breadcrumb: ['tool-list', 'tool-logs', 'tool-log']
}
},
{
name: 'tool-migrations',
path: '/tools/migrations',
component: () => import(/* webpackChunkName: "views/tools/migrations" */ '@/views/tool/ToolMigrations'),
meta: {
args: { trad: 'migrations' },
breadcrumb: ['tool-list', 'tool-migrations']
}
},
{
name: 'tool-firewall',
path: '/tools/firewall',
component: () => import(/* webpackChunkName: "views/tools/firewall" */ '@/views/tool/ToolFirewall'),
meta: {
args: { trad: 'firewall' },
breadcrumb: ['tool-list', 'tool-firewall']
}
},
{
name: 'tool-adminpw',
path: '/tools/adminpw',
component: () => import(/* webpackChunkName: "views/tools/adminpw" */ '@/views/tool/ToolAdminpw'),
meta: {
args: { trad: 'tools_adminpw' },
breadcrumb: ['tool-list', 'tool-adminpw']
}
},
{
name: 'tool-webadmin',
path: '/tools/webadmin',
component: () => import(/* webpackChunkName: "views/tools/webadmin" */ '@/views/tool/ToolWebadmin'),
meta: {
args: { trad: 'tools_webadmin_settings' },
breadcrumb: ['tool-list', 'tool-webadmin']
}
},
{
name: 'tool-power',
path: '/tools/power',
component: () => import(/* webpackChunkName: "views/tools/power" */ '@/views/tool/ToolPower'),
meta: {
args: { trad: 'tools_shutdown_reboot' },
breadcrumb: ['tool-list', 'tool-power']
}
},
/*
DIAGNOSIS
*/
{
name: 'diagnosis',
path: '/diagnosis',
component: () => import(/* webpackChunkName: "views/diagnosis" */ '@/views/diagnosis/Diagnosis'),
meta: {
args: { trad: 'diagnosis' },
breadcrumb: ['diagnosis']
}
},
/*
BACKUP
*/
{
name: 'backup',
path: '/backup',
component: () => import(/* webpackChunkName: "views/backup/backup" */ '@/views/backup/Backup'),
meta: {
args: { trad: 'backup' },
breadcrumb: ['backup']
}
},
{
name: 'backup-list',
path: '/backup/:id',
component: () => import(/* webpackChunkName: "views/backup/list" */ '@/views/backup/BackupList'),
props: true,
meta: {
args: { param: 'id' },
breadcrumb: ['backup', 'backup-list']
}
},
{
name: 'backup-info',
path: '/backup/:id/info/:name',
component: () => import(/* webpackChunkName: "views/backup/info" */ '@/views/backup/BackupInfo'),
props: true,
meta: {
args: { param: 'name' },
breadcrumb: ['backup', 'backup-list', 'backup-info']
}
},
{
name: 'backup-create',
path: '/backup/:id/create',
component: () => import(/* webpackChunkName: "views/backup/create" */ '@/views/backup/BackupCreate'),
props: true,
meta: {
args: { trad: 'backup_create' },
breadcrumb: ['backup', 'backup-list', 'backup-create']
}
}
]
export default routes

View file

@ -0,0 +1,82 @@
/*
Bootstrap and BootstrapVue overrides.
Bootstrap default: `app/node_modules/bootstrap/scss/_variables.scss`
BootstrapVue default: `app/node_modules/bootstrap-vue/src/_variables.scss`
*/
// TODO: add a feature so the user can set some css variables to change the global aspects ?
// For exemple, turning rounding of elements off, the bases colors, etc.
// $enable-rounded: false;
$alert-padding-x: 1rem;
$blue: #2f7ed2;
$purple: #9932cc;
$yellow: #ffd452;
$theme-colors: (
'best': $purple
);
// Replace font-weight 300 with 200
$font-weight-light: 200;
$display1-weight: 200;
$display2-weight: 200;
$display3-weight: 200;
$display4-weight: 200;
$lead-font-weight: 200;
// Set fonts
$font-family-sans-serif: 'FiraGO', 'Fira Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji' !default;
$font-family-monospace: 'Fira Code', SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace !default;
@import '~bootstrap/scss/functions.scss';
@import '~bootstrap/scss/variables';
@import '~bootstrap/scss/mixins.scss';
// Overwrite list-group-item variants to lighter ones (used in diagnosis for example)
@each $color, $value in $theme-colors {
@include list-group-item-variant($color, theme-color-level($color, -11), theme-color-level($color, 6));
}
// Add breakpoints for w-*
@each $breakpoint in map-keys($grid-breakpoints) {
@each $size, $length in $sizes {
@include media-breakpoint-up($breakpoint) {
.w-#{$breakpoint}-#{$size} {
width: $length !important;
}
}
}
}
/*
Fork-awesome variable overrides.
default: `app/node_modules/fork-awesome/scss/_variables.scss`
*/
$fa-font-path: '~fork-awesome/fonts';
$fa-font-size-base: 1rem;
$thin-border: 1px solid #eee;
$skeleton-color: #eaeaea;

114
app/src/scss/font.scss Normal file
View file

@ -0,0 +1,114 @@
/*
*/
/* firago-all-300-italic*/
@font-face {
font-family: 'FiraGO';
src:
local('FiraGO ExtraLight Italic'),
url('~fontsource-firago/files/firago-all-200-italic.woff2') format('woff2'),
url('~fontsource-firago/files/firago-all-200-italic.woff') format('woff');
font-weight: 200;
font-style: italic;
font-display: swap;
}
/* firago-all-300-normal*/
@font-face {
font-family: 'FiraGO';
src:
local('FiraGO ExtraLight'),
url('~fontsource-firago/files/firago-all-200-normal.woff2') format('woff2'),
url('~fontsource-firago/files/firago-all-200-normal.woff') format('woff');
font-weight: 200;
font-style: normal;
font-display: swap;
}
/* firago-all-400-italic*/
@font-face {
font-family: 'FiraGO';
src:
local('FiraGO Italic'),
url('~fontsource-firago/files/firago-all-400-italic.woff2') format('woff2'),
url('~fontsource-firago/files/firago-all-400-italic.woff') format('woff');
font-weight: 400;
font-style: italic;
font-display: swap;
}
/* firago-all-400-normal*/
@font-face {
font-family: 'FiraGO';
src:
local('FiraGO Regular'),
url('~fontsource-firago/files/firago-all-400-normal.woff2') format('woff2'),
url('~fontsource-firago/files/firago-all-400-normal.woff') format('woff');
font-weight: 400;
font-style: normal;
font-display: swap;
}
/* firago-all-500-italic*/
@font-face {
font-family: 'FiraGO';
src:
local('FiraGO Medium Italic'),
url('~fontsource-firago/files/firago-all-500-italic.woff2') format('woff2'),
url('~fontsource-firago/files/firago-all-500-italic.woff') format('woff');
font-weight: 500;
font-style: italic;
font-display: swap;
}
/* firago-all-500-normal*/
@font-face {
font-family: 'FiraGO';
src:
local('FiraGO Medium'),
url('~fontsource-firago/files/firago-all-500-normal.woff2') format('woff2'),
url('~fontsource-firago/files/firago-all-500-normal.woff') format('woff');
font-weight: 500;
font-style: normal;
font-display: swap;
}
/* firago-all-700-italic*/
@font-face {
font-family: 'FiraGO';
src:
local('FiraGO Bold Italic'),
url('~fontsource-firago/files/firago-all-700-italic.woff2') format('woff2'),
url('~fontsource-firago/files/firago-all-700-italic.woff') format('woff');
font-weight: 700;
font-style: italic;
font-display: swap;
}
/* firago-all-700-normal*/
@font-face {
font-family: 'FiraGO';
src:
local('FiraGO Bold'),
url('~fontsource-firago/files/firago-all-700-normal.woff2') format('woff2'),
url('~fontsource-firago/files/firago-all-700-normal.woff') format('woff');
font-weight: 700;
font-style: normal;
font-display: swap;
}
/*
*/
@font-face {
font-family: 'Fira Code';
src:
local('Fira Code Regular'),
url('~firacode/distr/woff2/FiraCode-Regular.woff2') format('woff2'),
url('~firacode/distr/woff/FiraCode-Regular.woff') format('woff');
font-weight: 400;
font-style: normal;
}

25
app/src/scss/globals.scss Normal file
View file

@ -0,0 +1,25 @@
/*
/!\ DO NOT IMPORT OR DEFINE ACTUAL RULES INTO THIS FILE /!\
Only things that disappear after scss compilation is allowed.
This file is magically imported into every components so that scss variables and
mixins can be accessed.
But if some rules are defined here, they will be copied into the final build as many
times as there are components
*/
@import 'variables';
@import '~bootstrap/scss/functions';
@import '~bootstrap/scss/variables';
@import '~bootstrap/scss/mixins';
@import '~bootstrap-vue/src/variables';
@import '~fork-awesome/scss/variables';

131
app/src/scss/main.scss Normal file
View file

@ -0,0 +1,131 @@
// This is the default scss file, more specific styling is defined directly into components.
// It it imported in `scr/App.vue` style tag.
// Dependencies variables overrides and custom variables
// Variables overrides are defined before actual SCSS imports
@import 'variables';
// Dependencies SCSS imports
// `~` allow to import a node_modules folder (resolved by Webpack)
@import '~bootstrap/scss/bootstrap.scss';
@import '~bootstrap-vue/src/index.scss';
// Import fonts
@import 'font';
@import '~fork-awesome/scss/fork-awesome.scss';
// Style overrides happens after dependencies imports
html {
min-height: 100vh;
}
body {
overflow-x: hidden;
min-height: 100vh;
margin: 0;
}
#app {
display: flex;
flex-direction: column;
min-height: 100vh
}
.menu-list {
.list-group-item {
padding: 0.75rem 0;
display: flex;
align-items: center;
}
h2 {
font-size: 1.25rem;
font-weight: 400;
margin: 0;
}
}
// Bootstrap overrides
.list-group-item {
padding: 0.75rem 1rem;
}
.list-group-item-action {
color: #333;
}
// Allow state of input group to be displayed under the group
.input-group .is-invalid ~ .invalid-feedback {
display: block;
}
// Descriptive list (<b-row /> elems with <b-col> inside)
.row-line {
@include media-breakpoint-up(md) {
&:hover {
background-color: rgba(0, 0, 0, 0.05);
border-radius: 0.2rem;
}
}
@include media-breakpoint-down(sm) {
flex-direction: column;
&:not(:last-of-type) {
margin-bottom: 0.5rem;
padding-bottom: 0.5rem;
border-bottom: $border-width solid $card-border-color;
}
}
}
.card + .card {
margin-top: 2rem;
}
.card-deck .card + .card {
margin-top: 0;
}
.card-header {
h1, h2, h3, h4, h5, h6 {
margin: 0;
}
h2 {
font-size: 1.75rem;
}
}
.card-body {
padding: 1rem;
}
// collapse icon
.not-collapsed > .icon {
transform: rotate(-90deg);
}
.collapsed > .icon {
transform: rotate(90deg);
position: relative;
top: 2px;
}
// Fork-awesome overrides
.fa-fw {
width: 1.25em !important;
}
// Do not display ligatures in invalid-feedback to avoid confusion.
.invalid-feedback {
code {
font-variant-ligatures: none;
}
}
.log {
margin-bottom: 0;
padding: 1rem;
background-color: $light;
}

181
app/src/store/data.js Normal file
View file

@ -0,0 +1,181 @@
import Vue from 'vue'
import api from '@/api'
export default {
state: () => ({
domains: undefined, // Array
main_domain: undefined,
users: undefined, // basic user data: Object {username: {data}}
users_details: {}, // precise user data: Object {username: {data}}
groups: undefined,
permissions: undefined
}),
mutations: {
'SET_DOMAINS' (state, domains) {
state.domains = domains
},
'ADD_DOMAINS' (state, { domain }) {
state.domains.push(domain)
},
'DEL_DOMAINS' (state, domain) {
state.domains.splice(state.domains.indexOf(domain), 1)
},
'SET_MAIN_DOMAIN' (state, response) {
state.main_domain = response.current_main_domain
},
'UPDATE_MAIN_DOMAIN' (state, domain) {
state.main_domain = domain
},
'SET_USERS' (state, users) {
state.users = Object.keys(users).length === 0 ? null : users
},
'ADD_USERS' (state, user) {
if (!state.users) state.users = {}
Vue.set(state.users, user.username, user)
},
'SET_USERS_DETAILS' (state, [username, userData]) {
Vue.set(state.users_details, username, userData)
if (!state.users) return
const user = state.users[username]
for (const key of ['firstname', 'lastname', 'mail']) {
if (user[key] !== userData[key]) {
Vue.set(user, key, userData[key])
}
}
Vue.set(user, 'fullname', `${userData.firstname} ${userData.lastname}`)
},
'UPDATE_USERS_DETAILS' (state, payload) {
// FIXME use a common function to execute the same code ?
this.commit('SET_USERS_DETAILS', payload)
},
'DEL_USERS_DETAILS' (state, username) {
Vue.delete(state.users_details, username)
if (state.users) {
Vue.delete(state.users, username)
if (Object.keys(state.users).length === 0) {
state.users = null
}
}
},
'SET_GROUPS' (state, groups) {
state.groups = groups
},
'ADD_GROUPS' (state, { name }) {
if (state.groups !== undefined) {
Vue.set(state.groups, name, { members: [], permissions: [] })
}
},
'DEL_GROUPS' (state, groupname) {
Vue.delete(state.groups, groupname)
},
'SET_PERMISSIONS' (state, permissions) {
state.permissions = permissions
}
},
actions: {
'FETCH' ({ state, commit, rootState }, { uri, param, storeKey = uri, cache = rootState.cache }) {
const currentState = param ? state[storeKey][param] : state[storeKey]
// if data has already been queried, simply return
if (currentState !== undefined && cache) return currentState
return api.get(param ? `${uri}/${param}` : uri).then(responseData => {
const data = responseData[storeKey] ? responseData[storeKey] : responseData
commit('SET_' + storeKey.toUpperCase(), param ? [param, data] : data)
return param ? state[storeKey][param] : state[storeKey]
})
},
'FETCH_ALL' ({ state, commit, rootState }, queries) {
return Promise.all(queries.map(({ uri, param, storeKey = uri, cache = rootState.cache }) => {
const currentState = param ? state[storeKey][param] : state[storeKey]
// if data has already been queried, simply return the state as cached
if (currentState !== undefined && cache) {
return { cached: currentState }
}
return api.get(param ? `${uri}/${param}` : uri).then(responseData => {
return { storeKey, param, responseData }
})
})).then(responsesData => {
return responsesData.map(({ storeKey, param, responseData, cached = undefined }) => {
if (cached !== undefined) return cached
const data = responseData[storeKey] ? responseData[storeKey] : responseData
commit('SET_' + storeKey.toUpperCase(), param ? [param, data] : data)
return param ? state[storeKey][param] : state[storeKey]
})
})
},
'POST' ({ state, commit }, { uri, data, storeKey = uri }) {
return api.post(uri, data).then(responseData => {
// FIXME api/domains returns null
if (responseData === null) responseData = data
responseData = responseData[storeKey] ? responseData[storeKey] : responseData
commit('ADD_' + storeKey.toUpperCase(), responseData)
return state[storeKey]
})
},
'PUT' ({ state, commit }, { uri, param, data, storeKey = uri }) {
return api.put(param ? `${uri}/${param}` : uri, data).then(responseData => {
const data = responseData[storeKey] ? responseData[storeKey] : responseData
commit('UPDATE_' + storeKey.toUpperCase(), param ? [param, data] : data)
return param ? state[storeKey][param] : state[storeKey]
})
},
'DELETE' ({ commit }, { uri, param, data = {}, storeKey = uri }) {
return api.delete(param ? `${uri}/${param}` : uri, data).then(() => {
commit('DEL_' + storeKey.toUpperCase(), param)
})
}
},
getters: {
users: state => {
if (state.users) return Object.values(state.users)
return state.users
},
userNames: state => {
if (state.users) return Object.keys(state.users)
return []
},
usersAsChoices: state => {
return Object.values(state.users).map(({ username, fullname, mail }) => {
return { text: `${fullname} (${mail})`, value: username }
})
},
// not cached
user: state => name => state.users_details[name],
domains: state => state.domains,
mainDomain: state => state.main_domain,
domainsAsChoices: state => {
const mainDomain = state.main_domain
return state.domains.map(domain => {
return { value: domain, text: domain === mainDomain ? domain + ' ★' : domain }
})
}
}
}

19
app/src/store/index.js Normal file
View file

@ -0,0 +1,19 @@
import Vue from 'vue'
import Vuex from 'vuex'
import info from './info'
import settings from './settings'
import data from './data'
Vue.use(Vuex)
export default new Vuex.Store({
state: settings.state,
mutations: settings.mutations,
actions: settings.actions,
getters: settings.getters,
modules: {
info,
data
}
})

160
app/src/store/info.js Normal file
View file

@ -0,0 +1,160 @@
import Vue from 'vue'
import api from '@/api'
import router from '@/router'
import { timeout } from '@/helpers/commons'
export default {
state: {
host: window.location.host,
connected: localStorage.getItem('connected') === 'true',
yunohost: null, // yunohost app infos: Object {version, repo}
error: null,
waiting: false,
history: []
},
mutations: {
'SET_CONNECTED' (state, connected) {
localStorage.setItem('connected', connected)
state.connected = connected
},
'SET_YUNOHOST_INFOS' (state, yunohost) {
state.yunohost = yunohost
},
'UPDATE_WAITING' (state, boolean) {
state.waiting = boolean
},
'ADD_HISTORY_ENTRY' (state, [uri, method, date]) {
state.history.push({ uri, method, date, messages: [] })
},
'ADD_MESSAGE' (state, message) {
state.history[state.history.length - 1].messages.push(message)
},
'UPDATE_PROGRESS' (state, progress) {
Vue.set(state.history[state.history.length - 1], 'progress', progress)
},
'SET_ERROR' (state, error) {
state.error = error
}
},
actions: {
'LOGIN' ({ dispatch }, password) {
// Entering a wrong password will trigger a 401 api response.
// action `DISCONNECT` will then be triggered by the response handler but will not
// redirect to `/login` so the view can display the catched error.
return api.post('login', { password }).then(() => {
dispatch('CONNECT')
})
},
'LOGOUT' ({ dispatch }) {
return api.get('logout').then(() => {
dispatch('DISCONNECT')
})
},
'RESET_CONNECTED' ({ commit }) {
commit('SET_CONNECTED', false)
commit('SET_YUNOHOST_INFOS', null)
},
'DISCONNECT' ({ dispatch, commit }, route) {
dispatch('RESET_CONNECTED')
commit('UPDATE_WAITING', false)
if (router.currentRoute.name === 'login') return
router.push({
name: 'login',
// Add a redirect query if next route is not unknown (like `logout`) or `login`
query: route && !['login', null].includes(route.name)
? { redirect: route.path }
: {}
})
},
'CONNECT' ({ commit, dispatch }) {
commit('SET_CONNECTED', true)
dispatch('GET_YUNOHOST_INFOS')
router.push(router.currentRoute.query.redirect || { name: 'home' })
},
'GET_YUNOHOST_INFOS' ({ commit }) {
return api.get('versions').then(versions => {
commit('SET_YUNOHOST_INFOS', versions.yunohost)
})
},
'CHECK_INSTALL' ({ dispatch }, retry = 2) {
// this action will try to query the `/installed` route 3 times every 5 s with
// a timeout of the same delay.
// FIXME need testing with api not responding
return timeout(api.get('installed'), 5000).then(({ installed }) => {
return installed
}).catch(err => {
if (retry > 0) {
return dispatch('CHECK_INSTALL', --retry)
}
throw err
})
},
'WAITING_FOR_RESPONSE' ({ commit }, [uri, method]) {
commit('UPDATE_WAITING', true)
commit('ADD_HISTORY_ENTRY', [uri, method, Date.now()])
},
'SERVER_RESPONDED' ({ state, dispatch, commit }, responseIsOk) {
if (responseIsOk) {
commit('UPDATE_WAITING', false)
commit('SET_ERROR', '')
}
},
'DISPATCH_MESSAGE' ({ commit }, messages) {
const typeToColor = { error: 'danger' }
for (const type in messages) {
const message = {
text: messages[type],
type: type in typeToColor ? typeToColor[type] : type
}
let progressBar = message.text.match(/^\[#*\+*\.*\] > /)
if (progressBar) {
progressBar = progressBar[0]
message.text = message.text.replace(progressBar, '')
const progress = { '#': 0, '+': 0, '.': 0 }
for (const char of progressBar) {
if (char in progress) progress[char] += 1
}
commit('UPDATE_PROGRESS', Object.values(progress))
}
if (message.text) {
commit('ADD_MESSAGE', message)
}
}
},
'DISPATCH_ERROR' ({ state, commit }, error) {
commit('SET_ERROR', error)
if (error.method === 'GET') {
router.push({ name: 'error', params: { type: error.code } })
}
// else the waiting screen will display the error
}
},
getters: {
host: state => state.host,
connected: state => (state.connected),
yunohost: state => (state.yunohost),
error: state => state.error,
waiting: state => state.waiting,
history: state => state.history,
lastAction: state => state.history[state.history.length - 1]
}
}

85
app/src/store/settings.js Normal file
View file

@ -0,0 +1,85 @@
/**
* Settings module store.
* @module store/settings
*/
import i18n from '@/i18n'
import { loadLocaleMessages, updateDocumentLocale, loadDateFnsLocale } from '@/i18n/helpers'
import supportedLocales from '@/i18n/supportedLocales'
export default {
state: {
locale: localStorage.getItem('locale'),
fallbackLocale: localStorage.getItem('fallbackLocale'),
cache: localStorage.getItem('cache') !== 'false',
transitions: localStorage.getItem('transitions') !== 'false',
experimental: localStorage.getItem('experimental') === 'true',
spinner: 'pacman',
supportedLocales: supportedLocales
},
mutations: {
'SET_LOCALE' (state, locale) {
localStorage.setItem('locale', locale)
state.locale = locale
},
'SET_FALLBACKLOCALE' (state, locale) {
localStorage.setItem('fallbackLocale', locale)
state.fallbackLocale = locale
},
'SET_CACHE' (state, boolean) {
localStorage.setItem('cache', boolean)
state.cache = boolean
},
'SET_TRANSITIONS' (state, boolean) {
localStorage.setItem('transitions', boolean)
state.transitions = boolean
},
'SET_EXPERIMENTAL' (state, boolean) {
localStorage.setItem('experimental', boolean)
state.experimental = boolean
},
'SET_SPINNER' (state, spinner) {
state.spinner = spinner
}
},
actions: {
'UPDATE_LOCALE' ({ commit }, locale) {
loadLocaleMessages(locale).then(() => {
updateDocumentLocale(locale)
commit('SET_LOCALE', locale)
i18n.locale = locale
})
// also query the date-fns locale object for filters
loadDateFnsLocale(locale)
},
'UPDATE_FALLBACKLOCALE' ({ commit }, locale) {
loadLocaleMessages(locale).then(() => {
commit('SET_FALLBACKLOCALE', locale)
i18n.fallbackLocale = [locale, 'en']
})
}
},
getters: {
locale: state => (state.locale),
fallbackLocale: state => (state.fallbackLocale),
cache: state => (state.cache),
transitions: state => (state.transitions),
experimental: state => state.experimental,
spinner: state => state.spinner,
availableLocales: state => {
return Object.entries(state.supportedLocales).map(([locale, { name }]) => {
return { value: locale, text: name }
})
}
}
}

View file

@ -0,0 +1,38 @@
<template>
<div class="error mt-4 mb-5" v-if="error">
<h2>{{ $t('api_errors_titles.' + error.name) }} :/</h2>
<em v-t="'api_error.sorry'" />
<div class="alert alert-info mt-4">
<span v-html="$t('api_error.help')" />
<br>{{ $t('api_error.info') }}
</div>
<h5 v-t="'error'" />
<pre><code>"{{ error.code }}" {{ error.status }}</code></pre>
<h5 v-t="'action'" />
<pre><code>"{{ error.method }}" {{ error.uri }}</code></pre>
<h5>Message</h5>
<p v-html="error.message" />
<template v-if="error.traceback">
<h5 v-t="'traceback'" />
<pre><code class="text-dark">{{ error.traceback }}</code></pre>
</template>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
name: 'ErrorPage',
computed: mapGetters(['error'])
// FIXME add redirect if they're no error (if reload or route entered by hand)
}
</script>

42
app/src/views/Home.vue Normal file
View file

@ -0,0 +1,42 @@
<template>
<div class="home">
<b-list-group class="menu-list">
<b-list-group-item
v-for="item in menu"
:key="item.routeName"
:to="{ name: item.routeName }"
>
<icon :iname="item.icon" class="lg" />
<h2>{{ $t(item.translation) }}</h2>
<icon iname="chevron-right" class="lg fs-sm ml-auto" />
</b-list-group-item>
</b-list-group>
</div>
</template>
<script>
export default {
name: 'Home',
data () {
return {
menu: [
{ routeName: 'user-list', icon: 'users', translation: 'users' },
{ routeName: 'domain-list', icon: 'globe', translation: 'domains' },
{ routeName: 'app-list', icon: 'cubes', translation: 'applications' },
{ routeName: 'update', icon: 'refresh', translation: 'system_update' },
{ routeName: 'service-list', icon: 'cog', translation: 'services' },
{ routeName: 'tool-list', icon: 'wrench', translation: 'tools' },
{ routeName: 'diagnosis', icon: 'stethoscope', translation: 'diagnosis' },
{ routeName: 'backup', icon: 'archive', translation: 'backup' }
]
}
}
}
</script>
<style lang="scss" scoped>
.home {
margin-top: 2rem;
}
</style>

68
app/src/views/Login.vue Normal file
View file

@ -0,0 +1,68 @@
<template>
<div class="login">
<b-alert v-if="apiError" variant="danger">
<icon iname="exclamation-triangle" /> {{ $t(apiError) }}
</b-alert>
<b-form @submit.prevent="login">
<!-- FIXME add hidden domain input ? -->
<b-input-group>
<template v-slot:prepend>
<b-input-group-text>
<label class="sr-only" for="input-password">{{ $t('password') }}</label>
<icon iname="lock" class="sm" />
</b-input-group-text>
</template>
<b-form-input
id="input-password"
required type="password"
v-model="password" :disabled="disabled"
:placeholder="$t('administration_password')" :state="isValid"
/>
<template v-slot:append>
<b-button type="submit" variant="success" :disabled="disabled">
{{ $t('login') }}
</b-button>
</template>
</b-input-group>
<b-form-invalid-feedback :state="isValid">
{{ $t('wrong_password') }}
</b-form-invalid-feedback>
</b-form>
</div>
</template>
<script>
export default {
name: 'Login',
data () {
return {
disabled: false,
password: '',
isValid: null,
apiError: undefined
}
},
methods: {
login () {
this.$store.dispatch('LOGIN', this.password).catch(() => {
this.isValid = false
})
}
},
created () {
this.$store.dispatch('CHECK_INSTALL').then(installed => {
if (installed) {
this.disabled = false
} else {
this.$router.push({ name: 'post-install' })
}
}).catch(err => {
this.apiError = err.message
})
}
}
</script>

View file

@ -0,0 +1,115 @@
<template>
<div class="post-install">
<!-- START STEP -->
<template v-if="step === 'start'">
<p class="alert alert-success">
<icon iname="thumbs-up" /> {{ $t('postinstall_intro_1') }}
</p>
<p class="alert alert-info">
<span v-t="'postinstall_intro_2'" />
<br>
<span v-html="$t('postinstall_intro_3')" />
</p>
<b-button size="lg" variant="primary" @click="step = 'domain'">
{{ $t('begin') }}
</b-button>
</template>
<!-- DOMAIN SETUP STEP -->
<template v-else-if="step === 'domain'">
<domain-form @submit="setDomain" :title="$t('postinstall_set_domain')" :submit-text="$t('next')">
<template #disclaimer>
<p class="alert alert-warning" v-t="'postinstall_domain'" />
</template>
</domain-form>
<b-button variant="primary" @click="step = 'start'" class="mt-3">
<icon iname="chevron-left" /> {{ $t('previous') }}
</b-button>
</template>
<!-- PASSWORD SETUP STEP -->
<template v-else-if="step === 'password'">
<password-form :title="$t('postinstall_set_password')" :submit-text="$t('next')" @submit="setPassword">
<template #disclaimer>
<p class="alert alert-warning" v-t="'postinstall_password'" />
</template>
</password-form>
<b-button variant="primary" @click="step = 'domain'" class="mt-3">
<icon iname="chevron-left" /> {{ $t('previous') }}
</b-button>
</template>
<!-- POST-INSTALL SUCCESS STEP -->
<template v-else-if="step === 'login'">
<p class="alert alert-success">
<icon iname="thumbs-up" /> {{ $t('installation_complete') }}
</p>
<login-view />
</template>
<!-- CONFIRM POST-INSTALL MODAL -->
<b-modal
ref="post-install-modal" id="post-install-modal" centered
body-bg-variant="danger" body-text-variant="light"
@ok="performPostInstall" hide-header
>
{{ $t('confirm_postinstall', { domain }) }}
</b-modal>
</div>
</template>
<script>
import api from '@/api'
import { DomainForm, PasswordForm } from '@/components/reusableForms'
import LoginView from '@/views/Login'
export default {
name: 'PostInstall',
data () {
return {
step: 'start',
domain: undefined,
password: undefined
}
},
methods: {
setDomain ({ domain }) {
this.domain = domain
this.step = 'password'
},
setPassword ({ password }) {
this.password = password
this.$refs['post-install-modal'].show()
},
performPostInstall () {
// FIXME does the api will throw an error for bad passwords ?
api.post('postinstall', { domain: this.domain, password: this.password }).then(data => {
// Display success message and allow the user to login
this.step = 'login'
})
}
},
created () {
this.$store.dispatch('CHECK_INSTALL').then(installed => {
if (installed) {
this.$router.push({ name: 'home' })
}
})
},
components: {
DomainForm,
PasswordForm,
LoginView
}
}
</script>

View file

@ -0,0 +1,111 @@
<template>
<view-base
:queries="queries" @queries-response="formatAppActions"
ref="view" skeleton="card-form-skeleton"
>
<template v-if="actions" #default>
<b-alert variant="warning" class="mb-4">
<icon iname="exclamation-triangle" /> {{ $t('experimental_warning') }}
</b-alert>
<!-- ACTIONS FORMS -->
<card-form
v-for="(action, i) in actions" :key="i"
:title="action.name" icon="wrench" title-tag="h4"
:validation="$v.actions[i]" :id="action.id + '-form'" :server-error="action.serverError"
@submit.prevent="performAction(action)" :submit-text="$t('perform')"
>
<template #disclaimer>
<div
v-if="action.formDisclaimer"
class="alert alert-info" v-html="action.formDisclaimer"
/>
<b-card-text v-if="action.description" v-html="action.description" />
</template>
<form-field
v-for="(field, fname) in action.fields" :key="fname" label-cols="0"
v-bind="field" v-model="action.form[fname]" :validation="$v.actions[i][fname]"
/>
</card-form>
</template>
<!-- In case of a custom url with no manifest found -->
<b-alert v-else-if="actions === null" variant="warning">
<icon iname="exclamation-triangle" /> {{ $t('app_no_actions') }}
</b-alert>
</view-base>
</template>
<script>
import api from '@/api'
import { validationMixin } from 'vuelidate'
import { formatI18nField, formatYunoHostArguments, formatFormData } from '@/helpers/yunohostArguments'
import { objectToParams } from '@/helpers/commons'
export default {
name: 'AppActions',
props: {
id: { type: String, required: true }
},
data () {
return {
queries: [
`apps/${this.id}/actions`,
{ uri: 'domains' },
{ uri: 'domains/main', storeKey: 'main_domain' },
{ uri: 'users' }
],
actions: undefined
}
},
validations () {
const validations = {}
for (const [i, action] of this.actions.entries()) {
if (action.validations) {
validations[i] = { form: action.validations }
}
}
return { actions: validations }
},
methods: {
formatAppActions (data) {
if (!data.actions) {
this.actions = null
return
}
this.actions = data.actions.map(({ name, id, description, arguments: arguments_ }) => {
const action = { name, id, serverError: '' }
if (description) action.description = formatI18nField(description)
if (arguments_ && arguments_.length) {
const { form, fields, validations, disclaimer } = formatYunoHostArguments(arguments_)
action.form = form
action.fields = fields
if (validations) action.validations = validations
if (disclaimer) action.formDisclaimer = disclaimer
}
return action
})
},
performAction (action) {
// FIXME api expects at least one argument ?! (fake one given with { wut } )
const args = objectToParams(action.form ? formatFormData(action.form) : { wut: undefined })
api.put(`apps/${this.id}/actions/${action.id}`, { args }).then(response => {
this.$refs.view.fetchQueries()
}).catch(error => {
action.serverError = error.message
})
}
},
mixins: [validationMixin]
}
</script>

View file

@ -0,0 +1,430 @@
<template>
<view-search
:items="apps" :filtered-items="filteredApps" items-name="apps"
:queries="queries" @queries-response="formatAppData"
>
<template #top-bar>
<div id="view-top-bar">
<!-- APP SEARCH -->
<b-input-group>
<b-input-group-prepend is-text>
<icon iname="search" />
</b-input-group-prepend>
<b-form-input
id="search-input" :placeholder="$t('search.for', { items: $tc('items.apps', 2) })"
v-model="search" @input="setCategory"
/>
<b-input-group-append>
<b-select v-model="quality" :options="qualityOptions" @change="setCategory" />
</b-input-group-append>
</b-input-group>
<!-- CATEGORY SELECT -->
<b-input-group class="mt-3">
<b-input-group-prepend is-text>
<icon iname="filter" />
</b-input-group-prepend>
<b-select v-model="category" :options="categories" />
<b-input-group-append>
<b-button variant="primary" :disabled="category === null" @click="category = null">
{{ $t('app_show_categories') }}
</b-button>
</b-input-group-append>
</b-input-group>
<!-- CATEGORIES SUBTAGS -->
<b-input-group v-if="subtags" class="mt-3 subtags">
<b-input-group-prepend is-text>
Subtags
</b-input-group-prepend>
<b-form-radio-group
id="subtags-radio" name="subtags"
v-model="subtag" :options="subtags"
buttons button-variant="outline-secondary"
/>
<b-select id="subtags-select" v-model="subtag" :options="subtags" />
</b-input-group>
</div>
</template>
<!-- CATEGORIES CARDS -->
<b-card-group v-if="category === null" deck>
<b-card
v-for="cat in categories.slice(1)" :key="cat.value"
class="category-card" no-body
>
<b-button variant="outline-dark" @click="category = cat.value">
<b-card-title>
<icon :iname="cat.icon" /> {{ cat.text }}
</b-card-title>
<b-card-text>{{ cat.description }}</b-card-text>
</b-button>
</b-card>
</b-card-group>
<!-- APPS CARDS -->
<b-card-group v-else deck>
<b-card no-body v-for="app in filteredApps" :key="app.id">
<b-card-body class="d-flex flex-column">
<b-card-title class="d-flex">
{{ app.manifest.name }}
<small v-if="app.state !== 'working'" class="ml-2">
<b-badge
:variant="(app.color === 'danger' && app.state === 'lowquality') ? 'warning' : app.color"
v-b-popover.hover.bottom="$t(`app_state_${app.state}_explanation`)"
>
{{ $t('app_state_' + app.state) }}
</b-badge>
</small>
</b-card-title>
<b-card-text>{{ app.manifest.description }}</b-card-text>
<b-card-text v-if="app.maintained === 'orphaned'" class="align-self-end mt-auto">
<span class="alert-warning p-1" v-b-popover.hover.top="$t('orphaned_details')">
<icon iname="warning" /> {{ $t(app.maintained) }}
</span>
</b-card-text>
</b-card-body>
<!-- APP BUTTONS -->
<b-button-group>
<b-button :href="app.git.url" variant="outline-dark" target="_blank">
<icon iname="code" /> {{ $t('code') }}
</b-button>
<b-button :href="app.git.url + '/blob/master/README.md'" variant="outline-dark" target="_blank">
<icon iname="book" /> {{ $t('readme') }}
</b-button>
<b-button v-if="app.isInstallable" :variant="app.color" @click="onInstallClick(app)">
<icon iname="plus" /> {{ $t('install') }} <icon v-if="app.color === 'danger'" class="ml-1" iname="warning" />
</b-button>
<b-button v-else :variant="app.color" disabled>
{{ $t('installed') }}
</b-button>
</b-button-group>
</b-card>
</b-card-group>
<template #bot>
<!-- INSTALL CUSTOM APP -->
<card-form
:title="$t('custom_app_install')" icon="download"
@submit.prevent="onCustomInstallClick" :submit-text="$t('install')"
:validation="$v" class="mt-5"
>
<template #disclaimer>
<div class="alert alert-warning">
<icon iname="exclamation-triangle" /> {{ $t('confirm_install_custom_app') }}
</div>
</template>
<!-- URL -->
<form-field v-bind="customInstall.field" v-model="customInstall.url" :validation="$v.customInstall.url" />
</card-form>
</template>
<!-- CUSTOM SKELETON -->
<template #skeleton>
<b-card-group deck>
<b-card
v-for="i in 15" :key="i"
no-body style="min-height: 10rem;"
>
<div class="d-flex w-100 mt-auto">
<b-skeleton width="30px" height="30px" class="mr-2 ml-auto" />
<b-skeleton :width="randint(30, 70) + '%'" height="30px" class="mr-auto" />
</div>
<b-skeleton
v-if="randint(0, 1)"
:width="randint(30, 85) + '%'" height="24px" class="mx-auto"
/>
<b-skeleton :width="randint(30, 85) + '%'" height="24px" class="mx-auto mb-auto" />
</b-card>
</b-card-group>
</template>
</view-search>
</template>
<script>
import { validationMixin } from 'vuelidate'
import { required, githubLink } from '@/helpers/validators'
import { randint } from '@/helpers/commons'
export default {
name: 'AppCatalog',
data () {
return {
queries: ['appscatalog?full&with_categories'],
// Data
apps: undefined,
// Filtering options
qualityOptions: [
{ value: 'isHighQuality', text: this.$i18n.t('only_highquality_apps') },
{ value: 'isDecentQuality', text: this.$i18n.t('only_decent_quality_apps') },
{ value: 'isWorking', text: this.$i18n.t('only_working_apps') },
{ value: 'all', text: this.$i18n.t('all_apps') }
],
categories: [
{ text: this.$i18n.t('app_choose_category'), value: null },
{ text: this.$i18n.t('all_apps'), value: 'all', icon: 'search' }
// The rest is filled from api data
],
// Set by user inputs
search: '',
category: null,
subtag: 'all',
quality: 'isDecentQuality',
// Custom install form
customInstall: {
field: {
label: this.$i18n.t('url'),
description: this.$i18n.t('custom_app_url_only_github'),
props: {
id: 'custom-install',
placeholder: 'https://github.com/USER/REPOSITORY'
}
},
url: ''
}
}
},
computed: {
filteredApps () {
if (!this.apps || this.category === null) return
const search = this.search.toLowerCase()
if (this.quality === 'all' && this.category === 'all' && search === '') {
return this.apps
}
const filtered = this.apps.filter(app => {
// app doesn't match quality filter
if (this.quality !== 'all' && !app[this.quality]) return false
// app doesn't match category filter
if (this.category !== 'all' && app.category !== this.category) return false
if (this.subtag !== 'all') {
const appMatchSubtag = this.subtag === 'others'
? app.subtags.length === 0
: app.subtags.includes(this.subtag)
// app doesn't match subtag filter
if (!appMatchSubtag) return false
}
if (search === '') return true
if (app.searchValues.includes(search)) return true
return false
})
return filtered.length ? filtered : null
},
subtags () {
// build an options array for subtags v-model/options
if (this.category) {
const category = this.categories.find(cat => cat.value === this.category)
if (category.subtags) {
const subtags = [{ text: this.$i18n.t('all'), value: 'all' }]
category.subtags.forEach(subtag => {
subtags.push({ text: subtag.title, value: subtag.id })
})
subtags.push({ text: this.$i18n.t('others'), value: 'others' })
return subtags
}
}
return null
}
},
validations: {
customInstall: {
url: { required, githubLink }
}
},
methods: {
formatQuality (app) {
const filters = {
isHighQuality: false,
isDecentQuality: false,
isWorking: false,
state: 'inprogress'
}
if (app.state === 'inprogress') return filters
if (app.state === 'working' && app.level > 0) {
filters.state = 'working'
filters.isWorking = true
}
if (app.level <= 4 || app.level === '?') {
filters.state = 'lowquality'
return filters
} else {
filters.isDecentQuality = true
}
if (app.high_quality && app.level > 7) {
filters.state = 'highquality'
filters.isHighQuality = true
}
return filters
},
formatColor (app) {
if (app.isHighQuality) return 'best'
if (app.isDecentQuality) return 'success'
if (app.isWorking) return 'warning'
return 'danger'
},
formatAppData (data) {
// APPS
const apps = []
for (const key in data.apps) {
const app = data.apps[key]
if (app.state === 'notworking') continue
Object.assign(app, this.formatQuality(app))
app.isInstallable = !app.installed || app.manifest.multi_instance
if (app.maintained !== 'request_adoption') {
app.maintained = app.maintained ? 'maintained' : 'orphaned'
}
app.color = this.formatColor(app)
app.searchValues = [app.id, app.state, app.manifest.name.toLowerCase(), app.manifest.description.toLowerCase()].join(' ')
apps.push(app)
}
this.apps = apps.sort((a, b) => a.id > b.id ? 1 : -1)
// CATEGORIES
data.categories.forEach(({ title, id, icon, subtags, description }) => {
this.categories.push({ text: title, value: id, icon, subtags, description })
})
},
setCategory () {
// allow search without selecting a category
if (this.category === null) {
this.category = 'all'
}
},
// INSTALL APP
async onInstallClick (app) {
if (!app.isDecentQuality) {
// Ask for confirmation
const state = app.color === 'danger' ? 'inprogress' : app.state
const confirmed = await this.$askConfirmation(this.$i18n.t('confirm_install_app_' + state))
if (!confirmed) return
}
this.$router.push({ name: 'app-install', params: { id: app.id } })
},
// INSTALL CUSTOM APP
async onCustomInstallClick () {
const confirmed = await this.$askConfirmation(this.$i18n.t('confirm_install_custom_app'))
if (!confirmed) return
const url = this.customInstall.url
this.$router.push({
name: 'app-install-custom',
params: { id: url.endsWith('/') ? url : url + '/' }
})
},
randint
},
mixins: [validationMixin]
}
</script>
<style lang="scss" scoped>
#view-top-bar {
margin-bottom: 2rem;
#search-input {
min-width: 8rem;
}
select {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.subtags {
#subtags-radio {
display: none
}
@include media-breakpoint-up(md) {
#subtags-radio {
display: inline-flex;
}
#subtags-select {
display: none;
}
}
}
}
.card-deck {
.card {
border-color: $gray-400;
margin-bottom: 2rem;
flex-basis: 90%;
@include media-breakpoint-up(md) {
flex-basis: 50%;
max-width: calc(50% - 30px);
}
@include media-breakpoint-up(lg) {
flex-basis: 33%;
max-width: calc(33.3% - 30px);
}
// not maintained info
.alert-warning {
font-size: .75em;
}
}
.category-card {
@include media-breakpoint-up(sm) {
min-height: 10rem;
}
border: 0;
.btn {
padding: 1rem;
width: 100%;
height: 100%;
}
}
.btn-group {
.btn {
border-top-left-radius: 0;
border-top-right-radius: 0;
border-bottom: 0;
flex-basis: 0;
padding-left: 0;
padding-right: 0;
}
.btn:first-of-type {
border-left: 0;
}
.btn:last-of-type {
border-right: 0;
}
}
.btn-outline-dark {
border-color: $gray-400;
&:hover {
border-color: $dark;
}
}
}
</style>

View file

@ -0,0 +1,119 @@
<template>
<view-base :queries="queries" @queries-response="formatAppConfig" skeleton="card-form-skeleton">
<template v-if="panels" #default>
<b-alert variant="warning" class="mb-4">
<icon iname="exclamation-triangle" /> {{ $t('experimental_warning') }}
</b-alert>
<!-- FIXME Rework with components -->
<b-form id="config-form" @submit.prevent="applyConfig">
<b-card no-body v-for="panel in panels" :key="panel.id">
<b-card-header class="d-flex align-items-center">
<h2>{{ panel.name }} <small v-if="panel.help">{{ panel.help }}</small></h2>
<div class="ml-auto">
<b-button v-b-toggle="[panel.id + '-collapse', panel.id + '-collapse-footer']" size="sm" variant="outline-secondary">
<icon iname="chevron-right" /><span class="sr-only">{{ $t('words.collapse') }}</span>
</b-button>
</div>
</b-card-header>
<b-collapse :id="panel.id + '-collapse'" visible>
<b-card-body v-for="section in panel.sections" :key="section.id">
<b-card-title>{{ section.name }} <small v-if="section.help">{{ section.help }}</small></b-card-title>
<form-item-helper v-for="arg in section.args" :key="arg.name" v-bind="arg" />
</b-card-body>
</b-collapse>
<b-collapse :id="panel.id + '-collapse-footer'" visible>
<b-card-footer>
<b-button
type="submit" form="config-form"
variant="success" class="ml-auto" v-t="'save'"
/>
</b-card-footer>
</b-collapse>
</b-card>
</b-form>
</template>
<!-- if no config panel -->
<b-alert v-else-if="panels === null" variant="warning">
<icon iname="exclamation-triangle" /> {{ $t('app_config_panel_no_panel') }}
</b-alert>
</view-base>
</template>
<script>
// FIXME needs test and rework
import api from '@/api'
import { formatI18nField, formatYunoHostArgument } from '@/helpers/yunohostArguments'
import { objectToParams } from '@/helpers/commons'
export default {
name: 'AppConfigPanel',
props: {
id: { type: String, required: true }
},
data () {
return {
queries: [
`apps/${this.id}/config-panel`,
{ uri: 'domains' },
{ uri: 'domains/main', storeKey: 'main_domain' },
{ uri: 'users' }
],
panels: undefined
}
},
methods: {
formatAppConfig (data) {
if (!data.config_panel || data.config_panel.length === 0) {
this.panels = null
return
}
const panels_ = []
for (const { id, name, help, sections } of data.config_panel.panel) {
const panel_ = { id, name, sections: [] }
if (help) panel_.help = formatI18nField(help)
for (const { name, help, options } of sections) {
const section_ = { name }
if (help) section_.help = formatI18nField(help)
section_.args = options.map(option => formatYunoHostArgument(option))
panel_.sections.push(section_)
}
panels_.push(panel_)
}
this.panels = panels_
},
applyConfig () {
// FIXME not tested
const args = {}
for (const panel of this.panels) {
for (const section of panel.sections) {
for (const arg of section.args) {
if (arg.component === 'CheckboxItem') {
args[arg.props.id] = arg.props.value ? 1 : 0
} else {
args[arg.props.id] = arg.props.value
}
}
}
}
// FIXME not tested at all, route is currently broken
api.post(`apps/${this.id}/config`, { args: objectToParams(args) }).then(response => {
console.log('SUCCESS', response)
}).catch(err => {
console.log('ERROR', err)
})
}
}
}
</script>

View file

@ -0,0 +1,302 @@
<template>
<view-base :queries="queries" @queries-response="formatAppData" ref="view">
<!-- BASIC INFOS -->
<card v-if="infos" :title="`${$t('infos')} — ${infos.label}`" icon="info-circle">
<b-row
v-for="(value, prop) in infos" :key="prop"
no-gutters class="row-line"
>
<b-col cols="auto" md="3">
<strong>{{ $t(prop) }}</strong>
</b-col>
<b-col>
<a v-if="prop === 'url'" :href="value" target="_blank">{{ value }}</a>
<span v-else>{{ value }}</span>
</b-col>
</b-row>
<b-row no-gutters class="row-line">
<b-col cols="auto" md="3">
<strong>{{ $t('app_info_access_desc') }}</strong>
<span class="sep" />
</b-col>
<b-col>
{{ allowedGroups.length > 0 ? allowedGroups.join(', ') + '.' : $t('nobody') }}
<b-button
size="sm" :to="{ name: 'group-list'}" variant="info"
class="ml-2"
>
<icon iname="key-modern" /> {{ $t('groups_and_permissions_manage') }}
</b-button>
</b-col>
</b-row>
</card>
<!-- OPERATIONS -->
<card v-if="app" :title="$t('operations')" icon="wrench">
<!-- CHANGE PERMISSIONS LABEL -->
<b-form-group :label="$t('app_manage_label_and_tiles')" label-class="font-weight-bold">
<form-field
v-for="(perm, i) in app.permissions" :key="i"
:label="perm.title" :label-for="'perm-' + i"
label-cols="0" label-class="" class="m-0"
:validation="$v.form.labels.$each[i] "
>
<template #default="{ self }">
<b-input-group>
<input-item
:state="self.state" v-model="form.labels[i].label"
:id="'perm' + i" :aria-describedby="'perm-' + i + '_group__BV_description_'"
/>
<b-input-group-append v-if="perm.tileAvailable" is-text>
<checkbox-item v-model="form.labels[i].show_tile" :label="$t('permission_show_tile_enabled')" />
</b-input-group-append>
<b-input-group-append>
<b-button
variant="info" v-t="'save'"
@click="changeLabel(perm.name, form.labels[i])"
/>
</b-input-group-append>
</b-input-group>
</template>
<template #description>
{{ $t('permission_corresponding_url') }}:
<b-link :href="'https:' + perm.url">
https://{{ perm.url }}
</b-link>
</template>
</form-field>
</b-form-group>
<hr>
<!-- CHANGE URL -->
<b-form-group
:label="$t('app_info_changeurl_desc')" label-for="input-url"
:label-cols-lg="app.supports_change_url ? 0 : 0" label-class="font-weight-bold"
>
<b-input-group v-if="app.supports_change_url">
<b-input-group-prepend is-text>
https://
</b-input-group-prepend>
<b-input-group-prepend class="flex-grow-1">
<b-select v-model="form.url.domain" :options="domains" />
</b-input-group-prepend>
<b-input-group-prepend is-text>
/
</b-input-group-prepend>
<b-input id="input-url" v-model="form.url.path" class="flex-grow-3" />
<b-input-group-append>
<b-button @click="changeUrl" variant="info" v-t="'save'" />
</b-input-group-append>
</b-input-group>
<div v-else class="alert alert-warning">
<icon iname="exclamation" /> {{ $t('app_info_change_url_disabled_tooltip') }}
</div>
</b-form-group>
<hr>
<!-- CHANGE DOMAIN -->
<b-form-group
:label="$t('app_info_default_desc', { domain: app.domain })" label-for="main-domain"
label-class="font-weight-bold" label-cols-md="4"
>
<b-button @click="setAsDefaultDomain" id="main-domain" variant="success">
<icon iname="star" /> {{ $t('app_make_default') }}
</b-button>
</b-form-group>
<hr>
<!-- UNINSTALL -->
<b-form-group
:label="$t('app_info_uninstall_desc')" label-for="uninstall"
label-class="font-weight-bold" label-cols-md="4"
>
<b-button @click="uninstall" id="uninstall" variant="danger">
<icon iname="trash-o" /> {{ $t('uninstall') }}
</b-button>
</b-form-group>
</card>
<!-- EXPERIMENTAL (displayed if experimental feature has been enabled in web-admin options)-->
<card v-if="experimental" :title="$t('experimental')" icon="flask">
<!-- APP ACTIONS -->
<b-form-group
:label="$t('app_actions_label')" label-for="actions"
label-cols-md="4" label-class="font-weight-bold"
>
<b-button id="actions" variant="warning" :to="{ name: 'app-actions', params: { id } }">
<icon iname="flask" /> {{ $t('app_actions') }}
</b-button>
</b-form-group>
<hr>
<!-- APP CONFIG PANEL -->
<b-form-group
:label="$t('app_config_panel_label')" label-for="config"
label-cols-md="4" label-class="font-weight-bold"
>
<b-button id="config" variant="warning" :to="{ name: 'app-config-panel', params: { id } }">
<icon iname="flask" /> {{ $t('app_config_panel') }}
</b-button>
</b-form-group>
</card>
<template #skeleton>
<card-info-skeleton :item-count="8" />
<card-form-skeleton />
</template>
</view-base>
</template>
<script>
import { mapGetters } from 'vuex'
import { validationMixin } from 'vuelidate'
import api from '@/api'
import { readableDate } from '@/helpers/filters/date'
import { humanPermissionName } from '@/helpers/filters/human'
import { required } from '@/helpers/validators'
export default {
name: 'AppInfo',
props: {
id: { type: String, required: true }
},
data () {
return {
queries: [
`apps/${this.id}?full`,
{ uri: 'users/permissions?full', storeKey: 'permissions' },
{ uri: 'domains' }
],
infos: undefined,
app: undefined,
form: undefined
}
},
computed: {
...mapGetters(['domains', 'experimental']),
allowedGroups () {
if (!this.app) return
return this.app.permissions[0].allowed
}
},
validations () {
return {
form: {
labels: {
$each: { label: { required } }
},
url: { path: { required } }
}
}
},
methods: {
formatAppData (app) {
const form = { labels: [] }
const mainPermission = app.permissions[this.id + '.main']
mainPermission.name = this.id + '.main'
mainPermission.title = this.$i18n.t('permission_main')
mainPermission.tileAvailable = mainPermission.url !== null && !mainPermission.url.startsWith('re:')
form.labels.push({ label: mainPermission.label, show_tile: mainPermission.show_tile })
const permissions = [mainPermission]
for (const [name, perm] of Object.entries(app.permissions)) {
if (!name.endsWith('.main')) {
permissions.push({
...perm,
name,
label: perm.sublabel,
title: humanPermissionName(name),
tileAvailable: perm.url !== null && !perm.url.startsWith('re:')
})
form.labels.push({ label: perm.sublabel, show_tile: perm.show_tile })
}
}
this.infos = {
id: this.id,
label: mainPermission.label,
description: app.description,
version: app.version,
multi_instance: this.$i18n.t(app.manifest.multi_instance ? 'yes' : 'no'),
install_time: readableDate(app.settings.install_time, true, true)
}
if (app.settings.domain) {
this.infos.url = 'https://' + app.settings.domain + app.settings.path
form.url = {
domain: app.settings.domain,
path: app.settings.path.slice(1)
}
}
this.form = form
this.app = {
domain: app.settings.domain,
supports_change_url: app.supports_change_url,
permissions
}
},
changeLabel (permName, data) {
data.show_tile = data.show_tile ? 'True' : 'False'
api.put('users/permissions/' + permName, data).then(this.$refs.view.fetchQueries)
},
async changeUrl () {
const confirmed = await this.$askConfirmation(this.$i18n.t('confirm_app_change_url'))
if (!confirmed) return
const { domain, path } = this.form.url
api.put(
`apps/${this.id}/changeurl`,
{ domain, path: '/' + path }
).then(this.fetchData)
},
async setAsDefaultDomain () {
const confirmed = await this.$askConfirmation(this.$i18n.t('confirm_app_default'))
if (!confirmed) return
api.put(`apps/${this.id}/default`).then(this.$refs.view.fetchQueries)
},
async uninstall () {
const confirmed = await this.$askConfirmation(
this.$i18n.t('confirm_uninstall', { name: this.id })
)
if (!confirmed) return
api.delete('apps/' + this.id).then(() => {
this.$router.push({ name: 'app-list' })
})
}
},
filters: { readableDate },
mixins: [validationMixin]
}
</script>
<style lang="scss" scoped>
select {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.input-group input {
min-width: 5rem;
}
</style>

View file

@ -0,0 +1,152 @@
<template>
<view-base :loading="loading">
<template v-if="infos">
<!-- BASIC INFOS -->
<card :title="`${$t('infos')} — ${name}`" icon="info-circle">
<b-row
v-for="(info, key) in infos" :key="key"
no-gutters class="row-line"
>
<b-col cols="5" md="3" xl="3">
<strong>{{ $t(key) }}</strong>
<span class="sep" />
</b-col>
<b-col>
<span>{{ info }}</span>
</b-col>
</b-row>
</card>
<!-- INSTALL FORM -->
<card-form
:title="$t('operations')" icon="wrench" :submit-text="$t('install')"
:validation="$v" :server-error="serverError"
@submit.prevent="performInstall"
>
<template v-if="formDisclaimer" #disclaimer>
<div class="alert alert-info" v-html="formDisclaimer" />
</template>
<form-field
v-for="(field, fname) in fields" :key="fname" label-cols="0"
v-bind="field" v-model="form[fname]" :validation="$v.form[fname]"
/>
</card-form>
</template>
<!-- In case of a custom url with no manifest found -->
<b-alert v-else-if="infos === null" variant="warning">
<icon iname="exclamation-triangle" /> {{ $t('app_install_custom_no_manifest') }}
</b-alert>
<template #skeleton>
<card-info-skeleton />
<card-form-skeleton :cols="null" />
</template>
</view-base>
</template>
<script>
import { validationMixin } from 'vuelidate'
import api from '@/api'
import { objectToParams } from '@/helpers/commons'
import { formatYunoHostArguments, formatI18nField, formatFormData } from '@/helpers/yunohostArguments'
export default {
name: 'AppInstall',
mixins: [validationMixin],
props: {
id: { type: String, required: true }
},
data () {
return {
loading: true,
name: undefined,
infos: undefined,
formDisclaimer: null,
form: undefined,
fields: undefined,
validations: null,
serverError: ''
}
},
validations () {
return this.validations
},
methods: {
getExternalManifest () {
const url = this.id.replace('github.com', 'raw.githubusercontent.com') + 'master/manifest.json'
return fetch(url).then(response => {
if (response.ok) return response.json()
else {
throw Error('No manifest found at ' + url)
}
}).catch(() => {
this.infos = null
})
},
getApiManifest () {
return api.get('appscatalog?full').then(response => response.apps[this.id].manifest)
},
formatManifestData (manifest) {
this.name = manifest.name
const infosKeys = ['id', 'description', 'license', 'version', 'multi_instance']
if (manifest.license === undefined || manifest.license === 'free') {
infosKeys.splice(2, 1)
}
manifest.description = formatI18nField(manifest.description)
manifest.multi_instance = this.$i18n.t(manifest.multi_instance ? 'yes' : 'no')
this.infos = Object.fromEntries(infosKeys.map(key => [key, manifest[key]]))
const { form, fields, validations, disclaimer } = formatYunoHostArguments(
manifest.arguments.install,
manifest.name
)
this.formDisclaimer = disclaimer
this.fields = fields
this.form = form
this.validations = { form: validations }
this.loading = false
},
async performInstall () {
if ('path' in this.form && this.form.path === '/') {
const confirmed = await this.$askConfirmation(
this.$i18n.t('confirm_install_domain_root', { domain: this.form.domain })
)
if (!confirmed) return
}
const { data: args, label } = formatFormData(this.form, { extract: ['label'] })
const data = { app: this.id, label, args: objectToParams(args) }
api.post('apps', data).then(response => {
this.$router.push({ name: 'app-list' })
}).catch(err => {
this.serverError = err.message
})
}
},
created () {
const isCustom = this.$route.name === 'app-install-custom'
Promise.all([
isCustom ? this.getExternalManifest() : this.getApiManifest(),
this.$store.dispatch('FETCH_ALL', [
{ uri: 'domains' },
{ uri: 'domains/main', storeKey: 'main_domain' },
{ uri: 'users' }
])
]).then((responses) => this.formatManifestData(responses[0]))
}
}
</script>

View file

@ -0,0 +1,94 @@
<template>
<view-search
:search.sync="search"
items-name="installed_apps"
:items="apps"
:filtered-items="filteredApps"
:queries="queries"
@queries-response="formatAppData"
>
<template #top-bar-buttons>
<b-button variant="success" :to="{ name: 'app-catalog' }">
<icon iname="plus" />
{{ $t('install') }}
</b-button>
</template>
<b-list-group>
<b-list-group-item
v-for="{ id, name, description, label } in filteredApps" :key="id"
:to="{ name: 'app-info', params: { id }}"
class="d-flex justify-content-between align-items-center pr-0"
>
<div>
<h5 class="font-weight-bold">
{{ label }}
<small v-if="name" class="text-secondary">{{ name }}</small>
</h5>
<p class="m-0">
{{ description }}
</p>
</div>
<icon iname="chevron-right" class="lg fs-sm ml-auto" />
</b-list-group-item>
</b-list-group>
</view-search>
</template>
<script>
export default {
name: 'AppList',
data () {
return {
queries: ['apps?full'],
search: '',
apps: undefined
}
},
computed: {
filteredApps () {
if (!this.apps) return
const search = this.search.toLowerCase()
const match = (item) => item && item.toLowerCase().includes(search)
// Check if any value in apps (label, id, name, description) match the search query.
const filtered = this.apps.filter(app => Object.values(app).some(match))
return filtered.length ? filtered : null
}
},
methods: {
formatAppData ({ apps }) {
if (apps.length === 0) {
this.apps = null
return
}
const multiInstances = {}
this.apps = apps.map(({ id, name, description, permissions, manifest }) => {
// FIXME seems like some apps may no have a label (replace with id)
const label = permissions[id + '.main'].label
// Display the `id` of the instead of its `name` if multiple apps share the same name
if (manifest.multi_instance) {
if (!(name in multiInstances)) {
multiInstances[name] = []
}
const labels = multiInstances[name]
if (labels.includes(label)) {
name = id
}
labels.push(label)
}
if (label === name) {
name = null
}
return { id, name, description, label }
}).sort((prev, app) => {
return prev.label > app.label ? 1 : -1
})
}
}
}
</script>

View file

@ -0,0 +1,40 @@
<template>
<div>
<b-list-group>
<b-list-group-item
v-for="{ id, name, uri } in storages" :key="id"
:to="{ name: 'backup-list', params: { id }}"
class="d-flex justify-content-between align-items-center pr-0"
>
<div>
<h5 class="font-weight-bold">
{{ name }}
<small class="text-secondary">{{ id }}</small>
</h5>
<p class="m-0">
{{ uri }}
</p>
</div>
<icon iname="chevron-right" class="lg fs-sm ml-auto" />
</b-list-group-item>
</b-list-group>
</div>
</template>
<script>
export default {
name: 'Backup',
data () {
return {
storages: [
{
id: 'local',
name: this.$i18n.t('local_archives'),
uri: '/home/yunohost.backup/'
}
]
}
}
}
</script>

View file

@ -0,0 +1,170 @@
<template>
<view-base :queries="queries" @queries-response="formatData" skeleton="card-list-skeleton">
<!-- FIXME switch to <card-form> ? -->
<card :title="$t('backup_create')" icon="archive" no-body>
<b-form-checkbox-group
v-model="selected"
id="backup-select" name="backup-select" size="lg"
>
<b-list-group flush>
<!-- SYSTEM HEADER -->
<b-list-group-item class="d-flex align-items-sm-center flex-column flex-sm-row" variant="light">
<h4 class="m-0">
<icon iname="cube" /> {{ $t('system') }}
</h4>
<div class="ml-sm-auto mt-2 mt-sm-0">
<b-button
@click="toggleSelected(true, 'system')" v-t="'select_all'"
size="sm" variant="outline-dark"
/>
<b-button
@click="toggleSelected(false, 'system')" v-t="'select_none'"
size="sm" variant="outline-dark" class="ml-2"
/>
</div>
</b-list-group-item>
<!-- SYSTEM ITEMS -->
<b-list-group-item
v-for="(item, partName) in system" :key="partName"
class="d-flex justify-content-between align-items-center pr-0"
>
<div class="mr-2">
<h5 class="font-weight-bold">
{{ item.name }}
</h5>
<p class="m-0">
{{ item.description }}
</p>
</div>
<b-form-checkbox :value="partName" :aria-label="$t('check')" class="d-inline" />
</b-list-group-item>
<!-- APPS HEADER -->
<b-list-group-item class="d-flex align-items-sm-center flex-column flex-sm-row" variant="light">
<h4 class="m-0">
<icon iname="cubes" /> {{ $t('applications') }}
</h4>
<div class="ml-sm-auto mt-2 mt-sm-0">
<b-button
@click="toggleSelected(true, 'apps')" v-t="'select_all'"
size="sm" variant="outline-dark"
/>
<b-button
@click="toggleSelected(false, 'apps')" v-t="'select_none'"
size="sm" variant="outline-dark" class="ml-2"
/>
</div>
</b-list-group-item>
<!-- APPS ITEMS -->
<b-list-group-item
v-for="(item, appName) in apps" :key="appName"
class="d-flex justify-content-between align-items-center pr-0"
>
<div class="mr-2">
<h5 class="font-weight-bold">
{{ item.name }} <small class="text-secondary">{{ item.id }}</small>
</h5>
<p class="m-0">
{{ item.description }}
</p>
</div>
<b-form-checkbox :value="appName" :aria-label="$t('check')" class="d-inline" />
</b-list-group-item>
</b-list-group>
</b-form-checkbox-group>
<!-- SUBMIT -->
<template #buttons>
<b-button
@click="createBackup" v-t="'backup_action'"
variant="success" :disabled="selected.length === 0"
/>
</template>
</card>
</view-base>
</template>
<script>
import api from '@/api'
export default {
name: 'BackupCreate',
props: {
id: { type: String, required: true }
},
data () {
return {
queries: ['hooks/backup', 'apps?with_backup'],
selected: [],
// api data
system: undefined,
apps: undefined
}
},
methods: {
formatHooks (hooks) {
const data = {}
hooks.forEach(hook => {
const groupId = hook.startsWith('conf_') ? 'adminjs_group_configuration' : hook
if (groupId in data) {
data[groupId].value.push(hook)
data[groupId].description += ', ' + this.$i18n.t('hook_' + hook)
} else {
data[groupId] = {
name: this.$i18n.t('hook_' + groupId),
value: [hook],
description: this.$i18n.t(groupId === hook ? `hook_${hook}_desc` : 'hook_' + hook)
}
}
})
return data
},
formatData ({ hooks }, { apps }) {
this.system = this.formatHooks(hooks)
// transform app array into literal object to match hooks data structure
this.apps = apps.reduce((obj, app) => {
obj[app.id] = app
return obj
}, {})
this.selected = [...Object.keys(this.system), ...Object.keys(this.apps)]
},
toggleSelected (select, type) {
if (select) {
const toSelect = Object.keys(this[type]).filter(item => !this.selected.includes(item))
this.selected = [...this.selected, ...toSelect]
} else {
const toUnselect = Object.keys(this[type])
this.selected = this.selected.filter(selected => !toUnselect.includes(selected))
}
},
createBackup () {
const data = { apps: [], system: [] }
for (const item of this.selected) {
if (item in this.system) {
data.system = [...data.system, ...this.system[item].value]
} else {
data.apps.push(item)
}
}
api.post('backup', data).then(response => {
this.$router.push({ name: 'backup-list', params: { id: this.id } })
})
}
}
}
</script>

View file

@ -0,0 +1,239 @@
<template>
<view-base :queries="queries" @queries-response="formatBackupData">
<!-- BACKUP INFO -->
<card :title="$t('infos')" icon="info-circle" button-unbreak="sm">
<template #header-buttons>
<!-- DOWNLOAD ARCHIVE -->
<b-button @click="downloadBackup" size="sm" variant="success">
<icon iname="download" /> {{ $t('download') }}
</b-button>
<!-- DELETE ARCHIVE -->
<b-button @click="deleteBackup" size="sm" variant="danger">
<icon iname="trash-o" /> {{ $t('delete') }}
</b-button>
</template>
<b-row
v-for="(value, prop) in infos" :key="prop"
no-gutters class="row-line"
>
<b-col md="3" xl="2">
<strong>{{ $t(prop === 'name' ? 'id' : prop) }}</strong>
</b-col>
<b-col>
<span v-if="prop === 'created_at'">{{ value | readableDate }}</span>
<span v-else-if="prop === 'size'">{{ value | humanSize }}</span>
<span v-else>{{ value }}</span>
</b-col>
</b-row>
</card>
<!-- BACKUP CONTENT -->
<!-- FIXME switch to <card-form> ? -->
<card
:title="$t('backup_content')" icon="archive"
no-body button-unbreak="sm"
>
<template #header-buttons>
<b-button
size="sm" variant="outline-secondary"
@click="toggleSelected()" v-t="'select_all'"
/>
<b-button
size="sm" variant="outline-secondary"
@click="toggleSelected(false)" v-t="'select_none'"
/>
</template>
<b-form-checkbox-group
v-if="hasBackupData" v-model="selected"
id="backup-select" name="backup-select" size="lg"
aria-describedby="backup-restore-feedback"
>
<b-list-group flush>
<!-- SYSTEM PARTS -->
<b-list-group-item
v-for="(item, partName) in system" :key="partName"
class="d-flex justify-content-between align-items-center pr-0"
>
<div class="mr-2">
<h5 class="font-weight-bold">
{{ item.name }} <small class="text-secondary" v-if="item.size">({{ item.size | humanSize }})</small>
</h5>
<p class="m-0">
{{ item.description }}
</p>
</div>
<b-form-checkbox :value="partName" :aria-label="$t('check')" />
</b-list-group-item>
<!-- APPS -->
<b-list-group-item
v-for="(item, appName) in apps" :key="appName"
class="d-flex justify-content-between align-items-center pr-0"
>
<div class="mr-2">
<h5 class="font-weight-bold">
{{ item.name }} <small class="text-secondary">{{ appName }} ({{ item.size | humanSize }})</small>
</h5>
<p class="m-0">
{{ $t('version') }} {{ item.version }}
</p>
</div>
<b-form-checkbox :value="appName" :aria-label="$t('check')" />
</b-list-group-item>
</b-list-group>
<b-form-invalid-feedback id="backup-restore-feedback" :state="isValid">
<b-alert variant="danger" class="mb-0">
{{ error }}
</b-alert>
</b-form-invalid-feedback>
</b-form-checkbox-group>
<div v-else class="alert alert-warning mb-0">
<icon iname="exclamation-triangle" /> {{ $t('archive_empty') }}
</div>
<!-- SUBMIT -->
<template v-if="hasBackupData" #buttons>
<b-button
@click="restoreBackup" form="backup-restore" variant="success"
v-t="'restore'" :disabled="selected.length === 0"
/>
</template>
</card>
<template #skeleton>
<card-info-skeleton :item-count="4" />
<card-list-skeleton />
</template>
</view-base>
</template>
<script>
import api from '@/api'
import { readableDate } from '@/helpers/filters/date'
import { humanSize } from '@/helpers/filters/human'
import { isEmptyValue } from '@/helpers/commons'
export default {
name: 'BackupInfo',
props: {
id: { type: String, required: true },
name: { type: String, required: true }
},
data () {
return {
queries: [`backup/archives/${this.name}?with_details`],
selected: [],
error: '',
isValid: null,
// api data
infos: undefined,
apps: undefined,
system: undefined
}
},
computed: {
hasBackupData () {
return !isEmptyValue(this.system) || !isEmptyValue(this.apps)
}
},
methods: {
formatHooks (hooks) {
const data = {}
Object.entries(hooks).forEach(([hook, { size }]) => {
const groupId = hook.startsWith('conf_') ? 'adminjs_group_configuration' : hook
if (groupId in data) {
data[groupId].value.push(hook)
data[groupId].description += ', ' + this.$i18n.t('hook_' + hook)
data[groupId].size += size
} else {
data[groupId] = {
name: this.$i18n.t('hook_' + groupId),
value: [hook],
description: this.$i18n.t(groupId === hook ? `hook_${hook}_desc` : 'hook_' + hook),
size
}
}
})
return data
},
formatBackupData (data) {
this.infos = {
name: this.name,
created_at: data.created_at,
size: data.size,
path: data.path
}
this.system = this.formatHooks(data.system)
this.apps = data.apps
this.toggleSelected()
},
toggleSelected (select = true) {
if (select) {
this.selected = [
...Object.keys(this.apps),
...Object.keys(this.system)
]
} else {
this.selected = []
}
},
async restoreBackup () {
const confirmed = await this.$askConfirmation(
this.$i18n.t('confirm_restore', { name: this.name })
)
if (!confirmed) return
const data = { apps: [], system: [], force: '' }
for (const item of this.selected) {
if (item in this.system) {
data.system = [...data.system, ...this.system[item].value]
} else {
data.apps.push(item)
}
}
api.post('backup/restore/' + this.name, data).then(response => {
this.isValid = null
}).catch(err => {
this.error = err.message
this.isValid = false
})
},
async deleteBackup () {
const confirmed = await this.$askConfirmation(this.$i18n.t('confirm_delete', { name: this.name }))
if (!confirmed) return
api.delete('backup/archives/' + this.name).then(() => {
this.$router.push({ name: 'backup-list', params: { id: this.id } })
})
},
downloadBackup () {
const host = this.$store.getters.host
window.open(`https://${host}/yunohost/api/backup/download/${this.name}`, '_blank')
}
},
filters: {
readableDate,
humanSize
}
}
</script>

Some files were not shown because too many files have changed in this diff Show more