Skip to content

Commit

Permalink
fix: software center improvements ui (#660)
Browse files Browse the repository at this point in the history
  • Loading branch information
andre8244 authored Jul 10, 2024
1 parent f9ef2b9 commit bea3dea
Show file tree
Hide file tree
Showing 17 changed files with 608 additions and 237 deletions.
2 changes: 1 addition & 1 deletion core/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"@carbon/icons-vue": "^10.37.0",
"@carbon/themes": "^10.34.0",
"@carbon/vue": "^2.40.0",
"@nethserver/ns8-ui-lib": "^1.0.1",
"@nethserver/ns8-ui-lib": "^1.0.2",
"await-to-js": "^3.0.0",
"axios": "^0.21.2",
"carbon-components": "^10.41.0",
Expand Down
46 changes: 38 additions & 8 deletions core/ui/public/i18n/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,9 @@
"click_here_to_upload": "Click here to upload",
"not_active": "Inactive",
"active": "Active",
"configure": "Configure"
"configure": "Configure",
"terms_and_conditions": "Terms and Conditions",
"terms_required": "Please read and agree to @:common.terms_and_conditions"
},
"error": {
"error": "Error",
Expand Down Expand Up @@ -632,7 +634,8 @@
"unknown_token": "Unknown token",
"must_be_32_chars_but_less_than_128": "Must be between 32 and 128 characters",
"os_not_supported": "Operating system is not supported",
"subscription_cannot_be_enabled": "Subscription is not available"
"subscription_cannot_be_enabled": "Subscription is not available",
"agree_terms_before_register": "I have read and agree to subscription {terms}."
},
"settings_sw_repositories": {
"title": "Software repositories",
Expand All @@ -647,7 +650,17 @@
"repository_same_name_already_exists": "A repository with this name already exists",
"repository_same_url_already_exists": "A repository with this URL already exists",
"repository_not_accessible": "Repository not accessible",
"repository_is_going_to_be_deleted": "Repository {object} is going to be deleted..."
"repository_is_going_to_be_deleted": "Repository {object} is going to be deleted...",
"enable_repository": "Enable repository {name}",
"disable_repository": "Disable repository {name}",
"create_repository_warning_title": "Security risks",
"create_repository_warning_description_1": "Adding a third-party software repository can pose significant risks:",
"create_repository_warning_li_1": "Potential security threats",
"create_repository_warning_li_2": "Possible system instability",
"create_repository_warning_li_3": "Privacy concerns",
"create_repository_warning_li_4": "Uncertain update and support status",
"create_repository_warning_li_5": "Granting system access to unknown sources",
"create_repository_warning_description_2": "Only proceed if you trust the repository source and understand these risks. Research the repository's reputation before adding it to the cluster."
},
"settings_http_routes": {
"title": "HTTP routes",
Expand Down Expand Up @@ -798,7 +811,7 @@
"software_updates": "Updates",
"you_have_updates": "You have {numUpdates} app to update | You have {numUpdates} apps to update",
"testing_warning_title": "Testing repositories enabled",
"testing_warning_description": "Some software repositories include non-stable versions of applications",
"testing_warning_description": "{repos} software repository includes non-stable versions of applications | The following software repositories include non-stable versions of applications: {repos}",
"testing_warning_action_label": "Go to Software repositories",
"all": "All",
"installed": "Installed",
Expand Down Expand Up @@ -833,8 +846,8 @@
"source_package": "Source package",
"authors": "Author | Authors",
"app_installation": "Install {app}",
"choose_node_for_installation": "Select installation node for {app} {version}",
"about_to_install_app": "{app} {version} will be installed on {node}",
"choose_node_for_installation": "Select installation node for {app} {version}:",
"about_to_install_app": "{app} {version} will be installed on {node}.",
"installing_on_node": "Installing on {node}",
"instance_installed_on_node": "{module_id} installed on {node}",
"app_instances": "{app} instances",
Expand Down Expand Up @@ -868,7 +881,9 @@
"app_now_renamed": "{instance} (now {module_id})",
"uninstall_app": "Uninstall {name}? App data will be deleted too. This action is NOT reversible",
"update_app": "Update {app}",
"about_to_update_app": "{app} {version} will be updated to {newVersion}",
"about_to_update_app": "{app} {version} will be updated to {newVersion}.",
"about_to_update_app_to_testing_version": "{app} {version} will be updated to testing version {newVersion}.",
"update_to_testing_version_warning": "Testing versions may contain bugs and are not recommended for production use. Update only if you are aware of the risks.",
"updating_to_version": "Updating to version {version}",
"core_app_name": "{productName} core",
"core_app_description": "Collection of {productName} core apps",
Expand Down Expand Up @@ -901,7 +916,22 @@
"communication": "Communication",
"security": "Security"
},
"images_label": "Images"
"images_label": "Images",
"rootfull_app_warning_title": "Administrative privileges",
"rootfull_app_warning_description": "After installation {appName} will have full access to the cluster: this can pose significant security risks.",
"agree_terms_before_install": "I have read and agree to {appName} {terms}.",
"level_level": "Level {level}",
"certification": "Certification",
"level_0_description": "Unknown level",
"level_1_description": "App developed by third-parties, not certified",
"level_2_description": "App developed by third-parties, certified by NethServer 8 community",
"level_3_description": "App developed by third-parties, certified by Nethesis",
"level_4_description": "App developed and certified by Nethesis",
"level_5_description": "App developed, certified and supported by Nethesis",
"update_to_stable_version": "Update to stable version",
"update_to_testing_version": "Update to testing version",
"num_instances_installed": "{num} instance installed | {num} instances installed",
"reason_max_per_node_limit": "Limit of {param} instance reached | Limit of {param} instances reached"
},
"system_logs": {
"title": "System logs",
Expand Down
17 changes: 6 additions & 11 deletions core/ui/src/components/nodes/NodeSelector.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,13 @@
:disabled="disabledNodes.includes(node.id)"
>
<h6>
{{
node.ui_name ? node.ui_name : $t("common.node") + " " + node.id
}}
<span v-if="node.ui_name">
{{ node.ui_name }} ({{ $t("common.node") }} {{ node.id }})
</span>
<span v-else> {{ $t("common.node") }} {{ node.id }} </span>
</h6>
<div v-if="node.ui_name" class="mg-top-md">
{{ $t("common.node") }} {{ node.id }}
</div>
<div
v-if="extraInfoLabel && extraInfoNode == node.id"
class="mg-top-md"
>
{{ extraInfoLabel }}
<div v-if="$slots[`node-${node.id}`]" class="mg-top-md">
<slot :name="`node-${node.id}`"></slot>
</div>
</NsTile>
</cv-column>
Expand Down
44 changes: 41 additions & 3 deletions core/ui/src/components/software-center/AppInfoModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
/>
</div>
<div class="app-name">
<h3>{{ app.name }}</h3>
<h3 data-modal-primary-focus>{{ app.name }}</h3>
</div>
</div>
</div>
Expand All @@ -38,6 +38,26 @@
<div class="description">
{{ getApplicationDescription(app) }}
</div>
<!-- warning for rootfull app -->
<NsInlineNotification
v-if="app.rootfull && app.certification_level < 3"
kind="warning"
:title="$t('software_center.rootfull_app_warning_title')"
:description="
$t('software_center.rootfull_app_warning_description', {
appName: app.name,
})
"
:showCloseButton="false"
/>
<div class="key-value-setting">
<span class="label">
{{ $t("software_center.certification") }}
</span>
<span class="value">
<CertificationLevelBadge :level="app.certification_level" />
</span>
</div>
<div class="key-value-setting">
<div>
<span class="label">{{
Expand All @@ -54,7 +74,16 @@
{{ $t("software_center.latest_version") }}
</span>
<span class="value">
{{ app.versions.length ? app.versions[0].tag : "-" }}
{{ app.versions.length ? app.versions[0].tag : "latest" }}
<span v-if="app.upstream_name"> ({{ app.upstream_name }}) </span>
</span>
</div>
</div>
<div class="key-value-setting">
<div>
<span class="label">{{ $t("software_center.repository") }}</span>
<span class="value">
{{ app.repository || "-" }}
</span>
</div>
</div>
Expand Down Expand Up @@ -129,6 +158,14 @@
{{ $t("software_center.source_code") }}
</cv-link>
</span>
<template v-if="app.docs.terms_url">
&bull;
<span>
<cv-link :href="app.docs.terms_url" target="_blank">
{{ $t("common.terms_and_conditions") }}
</cv-link>
</span>
</template>
</div>
</div>
</template>
Expand All @@ -140,10 +177,11 @@
<script>
import { UtilService } from "@nethserver/ns8-ui-lib";
import ImageGallery from "./ImageGallery";
import CertificationLevelBadge from "./CertificationLevelBadge.vue";

export default {
name: "AppInfoModal",
components: { ImageGallery },
components: { ImageGallery, CertificationLevelBadge },
mixins: [UtilService],
props: {
isShown: Boolean,
Expand Down
38 changes: 23 additions & 15 deletions core/ui/src/components/software-center/AppList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,22 @@
}}</a>
<span v-else>{{ app.name }}</span>
</div>
<div class="app-description app-row">
{{ getApplicationDescription(app) }}
<div v-if="app.id !== 'core'" class="app-row">
<CertificationLevelBadge :level="app.certification_level" />
</div>
<div
v-if="app.categories && getApplicationCategories(app)"
v-if="app.categories && getApplicationCategories(app).length"
class="app-categories app-row"
>
{{ getApplicationCategories(app) }}
<span
v-for="(category, index) in getApplicationCategories(app)"
:key="category"
>
{{ category }}
<span v-if="index < getApplicationCategories(app).length - 1"
>&bull;</span
>
</span>
</div>
<div v-if="app.id == 'core'" class="app-row">
<NsButton
Expand Down Expand Up @@ -137,10 +145,11 @@
import { IconService, UtilService } from "@nethserver/ns8-ui-lib";
import AppInfoModal from "./AppInfoModal";
import CoreAppModal from "./CoreAppModal";
import CertificationLevelBadge from "./CertificationLevelBadge.vue";

export default {
name: "AppList",
components: { AppInfoModal, CoreAppModal },
components: { AppInfoModal, CoreAppModal, CertificationLevelBadge },
mixins: [IconService, UtilService],
props: {
apps: {
Expand Down Expand Up @@ -217,11 +226,16 @@ export default {
}
}
},
getApplicationDescription(app) {
return this.getAppDescription(app, this);
},
getApplicationCategories(app) {
return this.getAppCategories(app, this);
let categories = [];

for (const category of app.categories) {
if (category === "unknown") {
continue;
}
categories.push(this.$t("software_center.app_categories." + category));
}
return categories;
},
goToSoftwareCenterAppInstances(app) {
this.$router.push({
Expand Down Expand Up @@ -279,12 +293,6 @@ export default {
font-weight: bold;
}

.app-description {
color: $text-02;
text-align: center;
line-height: 1.5;
}

.app-categories {
color: $text-02;
font-style: italic;
Expand Down
94 changes: 94 additions & 0 deletions core/ui/src/components/software-center/CertificationLevelBadge.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<!--
Copyright (C) 2024 Nethesis S.r.l.
SPDX-License-Identifier: GPL-3.0-or-later
-->
<template>
<cv-interactive-tooltip alignment="center" direction="top">
<template slot="trigger">
<NsTag
:label="
$t('software_center.level_level', {
level: `${level}/5`,
})
"
:kind="getLevelColor()"
:icon="getLevelIcon()"
class="level-tooltip"
/>
</template>
<template slot="content">
<h6 class="mg-bottom-sm">
{{ $t("software_center.level_level", { level }) }}
</h6>
<p class="mg-bottom-sm">
{{ $t(`software_center.level_${level}_description`) }}
</p>
<cv-link
href="https://docs.nethserver.org/projects/ns8/en/latest/software_center.html#certification-levels"
target="_blank"
rel="noreferrer"
class="inline"
>
{{ $t("common.more_info") }}
</cv-link>
</template>
</cv-interactive-tooltip>
</template>

<script>
import Security16 from "@carbon/icons-vue/es/security/16";
import WarningAlt16 from "@carbon/icons-vue/es/warning--alt/16";
import Error16 from "@carbon/icons-vue/es/error/16";
import Rule16 from "@carbon/icons-vue/es/rule/16";

export default {
name: "CertificationLevelBadge",
props: {
level: {
type: Number,
required: true,
},
},
data() {
return {
Security16,
WarningAlt16,
Rule16,
Error16,
};
},
methods: {
getLevelColor() {
if (this.level > 0 && this.level < 5) {
return "blue";
} else if (this.level == 5) {
return "green";
} else {
return "gray";
}
},
getLevelIcon() {
switch (this.level) {
case 1:
return this.WarningAlt16;
case 2:
case 3:
case 4:
return this.Rule16;
case 5:
return this.Security16;
default:
return this.Error16;
}
},
},
};
</script>

<style scoped lang="scss">
@import "../../styles/carbon-utils";

.level-tooltip {
cursor: pointer;
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@
<NodeSelector
class="mg-top-xlg"
@selectNode="onSelectNode"
:extraInfoNode="installationNode"
:extraInfoLabel="$t('software_center.current_node')"
:disabledNodes="isClone ? [] : [installationNode]"
/>
>
<template :slot="`node-${installationNode}`">
<div>{{ $t("software_center.current_node") }}</div>
</template>
</NodeSelector>
<NsInlineNotification
v-if="error.cloneModule"
kind="error"
Expand Down
Loading

0 comments on commit bea3dea

Please sign in to comment.