Skip to content

Commit 710a9f1

Browse files
feat(plugin): add nuonic extension card component and update plugin installer list
1 parent 3ae4472 commit 710a9f1

File tree

8 files changed

+280
-75
lines changed

8 files changed

+280
-75
lines changed

docker-compose.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,6 @@ services:
1111
- web
1212
environment:
1313
- XDEBUG_ENABLED=1
14-
- PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1
15-
- SHOPWARE_ADMIN_BUILD_ONLY_EXTENSIONS=1
16-
- DISABLE_ADMIN_COMPILATION_TYPECHECK=1
1714
networks:
1815
web:
1916
name: web
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import template from './nuonic-extension-card.html.twig';
2+
import './nuonic-extension-card.scss';
3+
4+
const { Component, Mixin } = Shopware;
5+
const { Criteria } = Shopware.Data;
6+
const { Utils, Filter } = Shopware;
7+
8+
Component.register('nuonic-extension-card', {
9+
template,
10+
11+
compatConfig: Shopware.compatConfig,
12+
13+
inheritAttrs: false,
14+
15+
inject: ['shopwareExtensionService', 'extensionStoreActionService', 'cacheApiService'],
16+
17+
emits: ['update-list'],
18+
19+
mixins: ['sw-extension-error'],
20+
21+
props: {
22+
extension: {
23+
type: Object,
24+
required: true,
25+
},
26+
},
27+
28+
data() {
29+
return {
30+
isLoading: false,
31+
showUninstallModal: false,
32+
showRemovalModal: false,
33+
showPermissionsModal: false,
34+
permissionsAccepted: false,
35+
showPrivacyModal: false,
36+
permissionModalActionLabel: null,
37+
openLink: null,
38+
showConsentAffirmationModal: false,
39+
consentAffirmationDeltas: null,
40+
};
41+
},
42+
43+
computed: {
44+
dateFilter() {
45+
return Shopware.Filter.getByName('date');
46+
},
47+
48+
defaultThemeAsset() {
49+
return this.assetFilter('administration/static/img/theme/default_theme_preview.jpg');
50+
},
51+
52+
imageUrl() {
53+
const location = window.location.origin;
54+
const path = '/api/_action/nuonic-plugin-installer/proxy';
55+
56+
if (!this.extension.icon) {
57+
return this.defaultThemeAsset;
58+
}
59+
60+
const query = new URLSearchParams({
61+
url: this.extension.icon,
62+
});
63+
64+
const url = `${location}${path}?${query}`;
65+
return url;
66+
},
67+
68+
isInstalled() {
69+
const installed = this.extension.pluginId !== null;
70+
71+
console.log('isInstalled', installed);
72+
73+
return installed;
74+
},
75+
76+
assetFilter() {
77+
return Filter.getByName('asset');
78+
},
79+
},
80+
81+
methods: {
82+
emitUpdateList() {
83+
this.$emit('update-list');
84+
},
85+
},
86+
});
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<sw-meteor-card class="nuonic-extension-card-base">
2+
<sw-loader v-if="isLoading" />
3+
4+
<sw-extension-icon :src="imageUrl" />
5+
6+
{% block nuonic_extension_card_base_activation_switch %}
7+
<div class="nuonic-extension-card-base__info">
8+
<section>
9+
<span class="nuonic-extension-card-base__info-name">
10+
{{ extension.name }}
11+
</span>
12+
<br/>
13+
<span class="nuonic-extension-card-base__info-description">
14+
{{ extension.description }}
15+
</span>
16+
17+
</section>
18+
</div>
19+
{% endblock %}
20+
21+
<div class="nuonic-extension-card-base__meta-info">
22+
{% block nuonic_extension_card_base_info_content %}
23+
<section>
24+
<span v-if="extension.availableVersion" class="nuonic-extension-card-base__meta-info-version">
25+
Version (TODO):
26+
{{ extension.availableVersion }}
27+
</span>
28+
<br/>
29+
<span v-if="extension.lastCommitTime" class="nuonic-extension-card-base__meta-info-last-commit">
30+
Last Commit (TODO):
31+
{{ dateFilter(extension.lastCommitTime, { month: 'numeric', year: 'numeric', hour: undefined, minute: undefined }) }}
32+
33+
</span>
34+
35+
</section>
36+
{% endblock %}
37+
38+
</div>
39+
40+
<div class="nuonic-extension-card-base__main-action">
41+
<span v-if="!isInstalled" class="nuonic-extension-card-base__open-extension" role="button" tabindex="0">
42+
Install (TODO)
43+
</span>
44+
</div>
45+
46+
</sw-meteor-card>
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
@import "~scss/variables";
2+
@import "~scss/mixins";
3+
4+
.nuonic-extension-card-base {
5+
6+
margin: 0 auto 1rem;
7+
8+
.sw-loader {
9+
border-radius: 8px;
10+
}
11+
12+
13+
14+
.sw-meteor-card__content .sw-meteor-card__content-wrapper {
15+
display: grid;
16+
grid-column-gap: 24px;
17+
grid-template-columns: 56px 5fr 2fr minmax(min-content, 1fr) auto;
18+
align-items: center;
19+
padding: 16px 32px;
20+
border: none;
21+
}
22+
23+
.nuonic-extension-card-base__info {
24+
margin-left: -8px;
25+
overflow: hidden;
26+
font-size: $font-size-xxs;
27+
28+
.nuonic-extension-card-base__info-name {
29+
@include truncate;
30+
31+
font-size: $font-size-xs;
32+
color: $color-darkgray-200;
33+
font-weight: $font-weight-semi-bold;
34+
}
35+
36+
.nuonic-extension-card-base__info-inactive {
37+
font-size: $font-size-xs;
38+
}
39+
}
40+
41+
.nuonic-extension-card-base__main-action {
42+
white-space: nowrap;
43+
text-align: center;
44+
}
45+
46+
.nuonic-extension-card-base__meta-info {
47+
font-size: $font-size-xxs;
48+
text-align: right;
49+
50+
a {
51+
color: $color-shopware-brand-500;
52+
margin-left: 4px;
53+
}
54+
55+
&-version {
56+
font-weight: $font-weight-semi-bold;
57+
}
58+
}
59+
60+
.nuonic-extension-card-base__open-extension {
61+
cursor: pointer;
62+
text-decoration: underline;
63+
color: $color-shopware-brand-500;
64+
transition: color 0.1s ease;
65+
font-weight: $font-weight-medium;
66+
67+
&:hover {
68+
color: $color-shopware-brand-800;
69+
}
70+
}
71+
}
72+
73+
.nuonic-extension-card-base__context-menu-privacy-link {
74+
display: flex;
75+
align-items: center;
76+
77+
.sw-icon {
78+
margin-left: 4px;
79+
}
80+
}

src/Resources/app/administration/src/main.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import './module/nuonic-plugin-installer';
22
import './component/nuonic-plugin-installer-index';
33
import './extension/sw-search-bar-item';
44
import './decorator/search-type.decorator';
5+
import './component/nuonic-extension-card';
56

67
import deDE from './snippet/de-DE';
78
import enGB from './snippet/en-GB';
Lines changed: 48 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,59 @@
11
import template from './nuonic-plugin-installer-list.html.twig';
2+
import './nuonic-plugin-installer-list.scss';
23

34
const { Component, Mixin } = Shopware;
45
const { Criteria } = Shopware.Data;
56

67
Component.register('nuonic-plugin-installer-list', {
7-
template,
8+
template,
89

9-
inject: ['repositoryFactory'],
10-
mixins: [Mixin.getByName('listing')],
10+
inject: ['repositoryFactory'],
11+
mixins: [Mixin.getByName('listing')],
1112

12-
data() {
13-
return {
14-
availablePlugins: [],
15-
page: 1,
16-
limit: 20,
17-
total: 0,
18-
term: null,
19-
sortBy: 'name',
20-
sortDirection: 'ASC',
21-
loading: false,
22-
};
23-
},
13+
data() {
14+
return {
15+
availablePlugins: [],
16+
page: 1,
17+
limit: 25,
18+
total: 0,
19+
term: null,
20+
sortBy: 'name',
21+
sortDirection: 'ASC',
22+
loading: false,
23+
};
24+
},
2425

25-
computed: {
26-
availablePluginsRepository() {
27-
return this.repositoryFactory.create('nuonic_available_opensource_plugin');
28-
},
29-
availablePluginsCriteria() {
30-
const criteria = new Criteria(this.page, this.limit);
31-
criteria.setTerm(this.term);
32-
criteria.addSorting(Criteria.sort(this.sortBy, this.sortDirection));
33-
return criteria;
34-
},
35-
},
26+
computed: {
27+
availablePluginsRepository() {
28+
return this.repositoryFactory.create('nuonic_available_opensource_plugin');
29+
},
30+
availablePluginsCriteria() {
31+
const criteria = new Criteria(this.page, this.limit);
32+
criteria.setTerm(this.term);
33+
criteria.addSorting(Criteria.sort(this.sortBy, this.sortDirection));
34+
criteria.addAssociation('plugin');
35+
criteria.addFilter(Criteria.range('lastSeenAt', { gte: new Date(Date.now() - 48 * 60 * 60 * 1000) }));
36+
return criteria;
37+
},
38+
},
3639

37-
methods: {
38-
getList() {
39-
this.loading = true;
40-
this.availablePluginsRepository.search(this.availablePluginsCriteria).then((result) => {
41-
this.availablePlugins = result;
42-
this.total = result.total;
43-
this.loading = false;
44-
});
45-
},
46-
changePage({ page = 1, limit = 10 }) {
47-
this.page = page;
48-
this.limit = limit;
49-
this.getList();
50-
},
51-
onSearch(value) {
52-
this.term = value;
53-
this.getList();
54-
},
55-
},
40+
methods: {
41+
getList() {
42+
this.loading = true;
43+
this.availablePluginsRepository.search(this.availablePluginsCriteria).then((result) => {
44+
this.availablePlugins = result;
45+
this.total = result.total;
46+
this.loading = false;
47+
});
48+
},
49+
changePage({ page = 1, limit = 10 }) {
50+
this.page = page;
51+
this.limit = limit;
52+
this.getList();
53+
},
54+
onSearch(value) {
55+
this.term = value;
56+
this.getList();
57+
},
58+
},
5659
});
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,21 @@
11
{% block nuonic_plugin_installer_index %}
2-
<sw-meteor-page hide-icon>
2+
<sw-page hide-icon>
33
<template #search-bar>
4-
{% block sw_extension_my_extensions_index_smart_bar_search_slot_search_bar %}
5-
<sw-search-bar
6-
initial-search-type="nuonic_available_opensource_plugin"
7-
:placeholder="$tc('nuonic-plugin-installer.extension.listing.placeholderSearchBar')"
8-
@search="onSearch"
9-
/>
10-
{% endblock %}
4+
<sw-search-bar initial-search-type="nuonic_available_opensource_plugin" :placeholder="$tc('nuonic-plugin-installer.extension.listing.placeholderSearchBar')" @search="onSearch" />
115
</template>
12-
13-
<div class="nuonic-plugin-installer-index">
14-
<sw-skeleton
15-
v-if="isLoading"
16-
:variant="skeletonVariant"
17-
/>
18-
<div v-else class="nuonic-plugin-installer-index__listing-grid">
19-
<template v-for="entry in availablePlugins" :key="entry.id">
20-
{{ entry.name }}
21-
</template>
22-
23-
<sw-pagination
24-
:total="total"
25-
:limit="limit"
26-
:page="page"
27-
@page-change="changePage"
28-
/>
6+
<template #smart-bar-header>
7+
{{ $tc('sw-extension.mainMenu.purchased') }}
8+
</template>
9+
<template #content>
10+
<div class="nuonic-plugin-installer-index">
11+
<sw-skeleton v-if="isLoading" :variant="skeletonVariant" />
12+
<div v-else class="nuonic-plugin-installer-index__listing-grid">
13+
<template v-for="entry in availablePlugins" :key="entry.id">
14+
<component :is="'nuonic-extension-card'" :extension="entry" />
15+
</template>
16+
<sw-pagination :total="total" :limit="limit" :page="page" @page-change="changePage" />
17+
</div>
2918
</div>
30-
</div>
31-
</sw-meteor-page>
19+
</template>
20+
</sw-page>
3221
{% endblock %}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.nuonic-plugin-installer-index {
2+
padding: 1rem 0;
3+
}

0 commit comments

Comments
 (0)