diff --git a/app/src/components/CardCollapse.vue b/app/src/components/CardCollapse.vue new file mode 100644 index 00000000..a9a9b4f8 --- /dev/null +++ b/app/src/components/CardCollapse.vue @@ -0,0 +1,82 @@ + + + + + diff --git a/app/src/components/CardDeckFeed.vue b/app/src/components/CardDeckFeed.vue new file mode 100644 index 00000000..23bd6898 --- /dev/null +++ b/app/src/components/CardDeckFeed.vue @@ -0,0 +1,81 @@ + diff --git a/app/src/components/globals/Icon.vue b/app/src/components/globals/Icon.vue index 077e7817..37e752d6 100644 --- a/app/src/components/globals/Icon.vue +++ b/app/src/components/globals/Icon.vue @@ -24,6 +24,12 @@ export default { min-width: 3rem; } + &.md { + width: 1.25rem; + font-size: 1.25rem; + min-width: 1.25rem; + } + &.fs-sm { font-size: 1rem; } diff --git a/app/src/components/globals/YunoAlert.vue b/app/src/components/globals/YunoAlert.vue new file mode 100644 index 00000000..421835f5 --- /dev/null +++ b/app/src/components/globals/YunoAlert.vue @@ -0,0 +1,35 @@ + + + diff --git a/app/src/helpers/yunohostArguments.js b/app/src/helpers/yunohostArguments.js index 74ad655d..f092ddea 100644 --- a/app/src/helpers/yunohostArguments.js +++ b/app/src/helpers/yunohostArguments.js @@ -262,8 +262,11 @@ export function formatYunoHostArgument (arg) { ] // Default type management if no one is filled + if (arg.choices && arg.choices.length) { + arg.type = 'select' + } if (arg.type === undefined) { - arg.type = arg.choices && arg.choices.length ? 'select' : 'string' + arg.type = 'string' } // Search the component bind to the type diff --git a/app/src/i18n/locales/en.json b/app/src/i18n/locales/en.json index beebded0..f1a5156c 100644 --- a/app/src/i18n/locales/en.json +++ b/app/src/i18n/locales/en.json @@ -54,10 +54,106 @@ "api_not_found": "Seems like the web-admin tried to query something that doesn't exist.", "api_not_responding": "The YunoHost API is not responding. Maybe 'yunohost-api' is down or got restarted?", "api_waiting": "Waiting for the server's response...", + "app": { + "installed_version": "Installed version: {version}", + "open_this_app": "Open this app", + "antifeatures": "This app has features you may not like:", + "doc": { + "about": { + "title": "About", + "description": "Description" + }, + "admin": { + "title": "Admin doc" + }, + "notifications": { + "dismiss": "Dismiss", + "title": "Notifications", + "post_upgrade": "Post-upgrade notes", + "post_install": "Post-install notes" + } + }, + "info": { + "forum": "Search or ask the forum!", + "problem": "A problem with this app?" + }, + "install": { + "license": "License: {license}", + "notifs": { + "post": { + "title": "Post-install notifications for '{name}'", + "alert": "It seems that the installation went well!\n Here is some notifications that the packager considers important to know.\nYou can read it again in the app info page." + }, + "pre": { + "warning": "Things to know before installation", + "danger": "The installation of the application will most likely lead to issues", + "critical": "The application cannot be installed" + } + }, + "problems": { + "arch": "This app can only be installed on specific architectures ({required}) but your server architecture is {current}.", + "broken": "This application is broken according to YunoHost's automatic tests and it is likely to break your system! You should probably NOT install it unless you know what you are doing.", + "thirdparty": "This application is not part of the official YunoHost catalog, 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.", + "ignore": "I understand that this installation may break my system but i still want to try.", + "inprogress": "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.", + "install": "It is already installed and can't be installed more than once.", + "lowquality": "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, or it does not respect the good practices.", + "ram": "This application requires {required} of RAM to install/upgrade but only {current} is available right now. Even if this app could run, its installation process requires a large amount of RAM so your server may freeze and fail miserably.", + "version": "This application requires YunoHost >= {required} but your current installed version is {current}, consider first upgrading YunoHost." + }, + "try_demo": "Try the demo", + "version": "Current version: {version}" + }, + "integration": { + "archs": "Supported architectures:", + "ldap": { + "false": "Does not use YunoHost accounts to login (LDAP)", + "true": "Use YunoHost accounts to login (LDAP)", + "?": "No information about LDAP integration" + }, + "multi_instance": { + "false": "Can be installed only once", + "true": "Can be installed several times" + }, + "resources": "Typical resource usage: {ram} RAM, {disk} disk", + "sso": { + "false": "Single sign-on is not available (SSO)", + "true": "Single sign-on is available (SSO)", + "?": "No information about SSO integration" + }, + "title": "YunoHost integration" + }, + "links": { + "admindoc": "Official Admin documentation", + "code": "Official code repository", + "forum": "Topics about this app on YunoHost's forum", + "package": "YunoHost package repository", + "title": "Links", + "userdoc": "Official User documentation", + "website": "Official Website", + "license": "License" + }, + "potential_alternative_to": "Potential alternative to:", + "upgrade": { + "confirm": { + "apps": "Apps that will be upgraded", + "title": "Confirm app upgrades" + }, + "continue": "Continue to next app", + "notifs": { + "pre": { + "alert": "You should check those notifications before upgrading, there might be important stuff to know.", + "title": "Be warned!" + }, + "post": { + "alert": "It seems that the upgrade went well!\n Here is some notifications that the packager considers important to know about this upgrade.\nYou can read it again in the app info page.", + "title": "Post-upgrade notifications for '{name}'" + } + }, + "stop": "Cancel next app upgrades" + } + }, "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_change_url_disabled_tooltip": "This feature hasn't been implemented in this app yet", "app_info_changeurl_desc": "Change the access URL of this application (domain and/or path).", @@ -118,6 +214,8 @@ "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_system": "Are you sure you want to update all system packages?", + "confirm_upnp_enable": "Are you sure you want to enable UPnP?", "confirm_update_apps": "Are you sure you want to update all applications?", "confirm_update_specific_app": "Are you sure you want to update {app}?", "confirm_update_system": "Are you sure you want to update all system packages?", @@ -292,6 +390,7 @@ "change_url": "Change access URL of '{name}'", "install": "Install app '{name}'", "set_default": "Redirect '{domain}' domain root to '{name}'", + "dismiss_notification": "Dismiss notification for '{name}'", "uninstall": "Uninstall app '{name}'", "update_config": "Update panel '{id}' of app '{name}' configuration" }, diff --git a/app/src/main.js b/app/src/main.js index e182a1d1..e883c4f9 100644 --- a/app/src/main.js +++ b/app/src/main.js @@ -39,6 +39,19 @@ Vue.prototype.$askConfirmation = function (message, props) { }) } +Vue.prototype.$askMdConfirmation = function (markdown, props, ok = false) { + const content = this.$createElement('vue-showdown', { + props: { markdown, flavor: 'github', options: { headerLevelStart: 4 } } + }) + return this.$bvModal['msgBox' + (ok ? 'Ok' : 'Confirm')](content, { + okTitle: this.$i18n.t('yes'), + cancelTitle: this.$i18n.t('cancel'), + headerBgVariant: 'warning', + headerClass: store.state.theme ? 'text-white' : 'text-black', + centered: true, + ...props + }) +} // Register global components const requireComponent = require.context('@/components/globals', true, /\.(js|vue)$/i) diff --git a/app/src/router/routes.js b/app/src/router/routes.js index 7d815851..a8429e05 100644 --- a/app/src/router/routes.js +++ b/app/src/router/routes.js @@ -175,6 +175,7 @@ const routes = [ name: 'app-catalog', path: '/apps/catalog', component: () => import(/* webpackChunkName: "views/apps/catalog" */ '@/views/app/AppCatalog'), + props: route => route.query, meta: { args: { trad: 'catalog' }, breadcrumb: ['app-list', 'app-catalog'] @@ -201,30 +202,19 @@ const routes = [ } }, { - 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'] - } - }, - { - // no need for name here, only children are visited - path: '/apps/:id/config-panel', - component: () => import(/* webpackChunkName: "views/apps/config" */ '@/views/app/AppConfigPanel'), - props: true, children: [ { - name: 'app-config-panel', + name: 'app-info', path: ':tabId?', component: () => import(/* webpackChunkName: "components/configPanel" */ '@/components/ConfigPanel'), props: true, meta: { - routerParams: ['id'], - args: { trad: 'app_config_panel' }, - breadcrumb: ['app-list', 'app-info', 'app-config-panel'] + routerParams: ['id'], // Override router key params to avoid view recreation at tab change. + args: { param: 'id' }, + breadcrumb: ['app-list', 'app-info'] } } ] diff --git a/app/src/scss/main.scss b/app/src/scss/main.scss index e26e8b24..d64bf15f 100644 --- a/app/src/scss/main.scss +++ b/app/src/scss/main.scss @@ -216,7 +216,7 @@ body { margin-top: 0; } -.card, .list-group-item { +.card-header, .list-group-item { h1, h2, h3, h4, h5, h6 { margin: 0; } diff --git a/app/src/views/app/AppCatalog.vue b/app/src/views/app/AppCatalog.vue index 66bdc39b..c0498bab 100644 --- a/app/src/views/app/AppCatalog.vue +++ b/app/src/views/app/AppCatalog.vue @@ -12,10 +12,10 @@ - + @@ -24,9 +24,9 @@ - + - + {{ $t('app_show_categories') }} @@ -39,83 +39,86 @@ - + - + - - + + {{ cat.text }} - - {{ cat.description }} - + + + {{ cat.description }} - - - - - + + + + - {{ app.manifest.description }} + + {{ app.manifest.description }} + - - - {{ $t('orphaned') }} - - - + + + {{ $t('orphaned') }} + + + + + - - - - {{ $t('code') }} - - - - {{ $t('readme') }} - - - - {{ $t('install') }} - - - {{ $t('installed') }} - - - - - +