Skip to content

Commit 87b05b0

Browse files
committed
Allow installation of incompatible packages (#867)
1 parent 36a33c1 commit 87b05b0

File tree

9 files changed

+64
-13
lines changed

9 files changed

+64
-13
lines changed

src/components/fragments/InstallButton.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
icon="add"
55
:small="small"
66
:inline="inline"
7-
:disabled="disabled || isRootInstalled || isAdded || isRequired || !canBeInstalled"
7+
:disabled="disabled || isRootInstalled || isAdded || isRequired || !canBeInstalled || !isCompatible"
88
@click="install"
99
v-if="isGranted(scopes.INSTALL)"
1010
>

src/components/fragments/PackageConstraint.vue

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,18 @@
66
:placeholder="inputPlaceholder"
77
:title="inputTitle"
88
v-model="inputValue"
9-
:class="{ disabled: !emit && (willBeRemoved || (!isInstalled && !willBeInstalled && !isRequired) || isUpload || !isGranted(scopes.INSTALL)), error: constraintError }"
9+
:class="{
10+
disabled: !emit && (willBeRemoved || (!isInstalled && !willBeInstalled && !isRequired) || isUpload || !isGranted(scopes.INSTALL)),
11+
incompatible: isIncompatible,
12+
error: constraintError,
13+
}"
1014
:disabled="!constraintEditable || willBeRemoved || (!emit && !isInstalled && !willBeInstalled && !isRequired) || isUpload || !isGranted(scopes.INSTALL)"
1115
@keypress.enter.prevent="saveConstraint"
1216
@keypress.esc.prevent="resetConstraint"
1317
@blur="saveConstraint"
1418
/>
1519
<button
16-
:class="{ 'widget-button widget-button--gear': true, rotate: constraintValidating }"
20+
:class="{ 'widget-button widget-button--gear': true, rotate: constraintValidating, incompatible: isIncompatible }"
1721
:title="buttonTitle"
1822
@click="editConstraint"
1923
:disabled="!emit && (willBeRemoved || (!isInstalled && !willBeInstalled && !isRequired) || isUpload || !isGranted(scopes.INSTALL))"
@@ -67,6 +71,8 @@ export default {
6771
? vm.$t('ui.package.latestConstraint')
6872
: '',
6973
74+
isIncompatible: (vm) => !vm.isCompatible && !vm.constraint,
75+
7076
inputValue: {
7177
get: (vm) => (vm.isUpload ? vm.$t('ui.package.private') : vm.constraint),
7278
set(value) {
@@ -221,6 +227,11 @@ export default {
221227
border-color: var(--border);
222228
}
223229
230+
&.incompatible {
231+
background: var(--btn-alert);
232+
border-color: var(--btn-alert);
233+
}
234+
224235
&.error {
225236
animation: input-error 0.15s linear 3;
226237
}
@@ -253,6 +264,10 @@ export default {
253264
margin: -10px 0 0 -10px;
254265
}
255266
267+
&.incompatible {
268+
background: var(--btn-alert);
269+
}
270+
256271
&.rotate:before {
257272
animation: release-validating 2s linear infinite;
258273
}

src/components/fragments/PackageDetails.vue

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<template v-else>{{ $t('ui.package.version', { version: installedVersion }) }}</template>
1313
</p>
1414
</template>
15-
<template v-else-if="canBeInstalled || isRequired">
15+
<template v-else-if="(canBeInstalled && isCompatible) || isAdded || isRequired">
1616
<install-button :data="data" />
1717
<package-constraint :data="data" v-if="isAdded || isRequired" />
1818
</template>
@@ -29,7 +29,17 @@
2929
</p>
3030
</template>
3131
<template #package-update v-else-if="!isCompatible">
32-
<p class="package-popup__incompatible">{{ $t('ui.package.incompatible', { package: data.name, constraint: packageConstraint('contao/manager-bundle') }) }}</p>
32+
<p class="package-popup__incompatible">
33+
{{ $t('ui.package.incompatible', { package: data.name, constraint: packageConstraint('contao/manager-bundle') }) }}
34+
<button
35+
type="button"
36+
class="widget-button widget-button--small widget-button--transparent widget-button--add"
37+
@click="install"
38+
v-if="canBeInstalled && !isRootInstalled && !isAdded && !isRequired"
39+
>
40+
{{ $t('ui.package.incompatibleButton') }}
41+
</button>
42+
</p>
3343
</template>
3444
<template #suggest-actions="{ name }">
3545
<install-button inline small :data="{ name }" v-if="packageSuggested(name)" />
@@ -125,12 +135,20 @@ export default {
125135
}
126136
127137
&__incompatible {
138+
display: flex;
139+
justify-content: space-between;
140+
align-items: center;
141+
gap: 10px;
128142
margin: 0 0 20px;
129-
padding: 10px 20px 10px 50px;
143+
padding: 10px 10px 10px 50px;
130144
color: var(--clr-btn);
131145
background: var(--contao) url('../../assets/images/button-incompatible.svg') 15px 50% no-repeat;
132146
background-size: 23px 23px;
133147
border-radius: var(--border-radius);
148+
149+
button {
150+
flex-shrink: 0;
151+
}
134152
}
135153
136154
&__funding + .package-popup__update {

src/components/routes/PackageListRoute.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@
2727
type="primary"
2828
icon="update"
2929
:loading="cloudLoading"
30-
:disabled="cloudError"
31-
:more-disabled="cloudLoading || cloudError"
30+
:disabled="cloudError || packageIncompatible"
31+
:more-disabled="cloudLoading || cloudError || packageIncompatible"
3232
:label="$t('ui.packages.changesApply')"
3333
@click="hasLockFile ? applyChanges() : applyChangesAll()"
3434
>
@@ -80,7 +80,7 @@ export default {
8080
requiredPackages: 'required',
8181
}),
8282
...mapState('packages/uploads', ['uploads', 'uploading', 'files', 'removing', 'confirmed']),
83-
...mapGetters('packages', ['totalChanges', 'packageMissing', 'canResetChanges', 'visibleRequired', 'visibleInstalled', 'visibleAdded']),
83+
...mapGetters('packages', ['totalChanges', 'packageMissing', 'packageIncompatible', 'canResetChanges', 'visibleRequired', 'visibleInstalled', 'visibleAdded']),
8484
...mapGetters('packages/uploads', ['hasUploads', 'totalUploads', 'canConfirmUploads']),
8585
scopes: () => scopes,
8686

src/components/routes/Packages/BasePackage.vue

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export default {
6464
</script>
6565

6666
<style rel="stylesheet/scss" lang="scss">
67-
@use "~contao-package-list/src/assets/styles/defaults";
67+
@use '~contao-package-list/src/assets/styles/defaults';
6868
6969
$package-padding: 16px;
7070
@@ -105,7 +105,7 @@ $package-padding: 16px;
105105
106106
&:not(:first-child):before {
107107
padding-right: 10px;
108-
content: "|";
108+
content: '|';
109109
}
110110
}
111111
}
@@ -125,7 +125,7 @@ $package-padding: 16px;
125125
&:after {
126126
display: table;
127127
clear: both;
128-
content: "";
128+
content: '';
129129
}
130130
}
131131
@@ -427,6 +427,7 @@ $package-padding: 16px;
427427
width: 180px;
428428
margin-left: 20px;
429429
}
430+
430431
&__details {
431432
display: flex;
432433
align-self: center;

src/components/routes/Packages/ComposerPackage.vue

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,10 @@ export default {
148148
return this.$t('ui.package.hintConstraint', { constraint: this.constraintAdded });
149149
}
150150
151+
if (!this.isCompatible) {
152+
return this.$t('ui.package.incompatibleConstraint', { constraint: this.packageConstraint('contao/manager-bundle') });
153+
}
154+
151155
return this.$t('ui.package.hintConstraintBest');
152156
}
153157

src/i18n/en.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,9 @@
469469
"ui.package.updateUnknown": "unknown version",
470470
"ui.package.updateConstraint": "A newer version outside your version constraint is available.",
471471
"ui.package.incompatible": "{package} does not work with Contao {constraint}.",
472+
"ui.package.incompatibleWarning": "{package} does not work with Contao {constraint} in any of its stable releases. Do you want to add the package and set a version constraint to try installing a development branch?",
473+
"ui.package.incompatibleConstraint": "This package does not have a stable release for Contao {constraint}. Set a version constraint to try installing a development branch.",
474+
"ui.package.incompatibleButton": "Install",
472475

473476
"ui.cloudStatus.headline": "Composer Resolver Cloud",
474477
"ui.cloudStatus.version": "Version {version}",

src/mixins/packageStatus.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export default {
2121
'packageFeature',
2222
'packageVisible',
2323
'packageSuggested',
24+
'packageConstraint',
2425
'packageConstraintAdded',
2526
'packageConstraintChanged',
2627
'packageConstraintInstalled',
@@ -60,7 +61,7 @@ export default {
6061
installedTime: (vm) => (vm.installed[vm.data.name] ? vm.installed[vm.data.name].time : null),
6162

6263
isCompatible: (vm) => vm.contaoSupported(vm.metadata.contaoConstraint),
63-
canBeInstalled: (vm) => (!vm.isPrivate || vm.isSuggested) && !vm.isTheme && (!vm.isDependency || vm.isSuggested) && vm.isCompatible,
64+
canBeInstalled: (vm) => (!vm.isPrivate || vm.isSuggested) && !vm.isTheme && (!vm.isDependency || vm.isSuggested),
6465

6566
constraintInstalled: (vm) => vm.packageConstraintInstalled(vm.data.name),
6667
constraintRequired: (vm) => vm.packageConstraintRequired(vm.data.name),
@@ -72,6 +73,13 @@ export default {
7273

7374
methods: {
7475
install() {
76+
if (
77+
!this.isCompatible &&
78+
!confirm(this.$t('ui.package.incompatibleWarning', { package: this.data.name, constraint: this.packageConstraint('contao/manager-bundle') }))
79+
) {
80+
return;
81+
}
82+
7583
this.$store.commit('packages/add', this.metadata || this.data);
7684
},
7785

src/store/packages.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ export default {
6969
Object.values(state.change).filter((pkg) => Object.keys(state.required).includes(pkg.name)).length -
7070
state.remove.filter((pkg) => Object.keys(state.required).includes(pkg)).length,
7171

72+
packageIncompatible: (state, get) => !!Object.values(state.add).find((p) => !p.constraint && !get.contaoSupported(p.contaoConstraint)),
73+
7274
canResetChanges: (s, get) => get.totalChanges > get.totalRequired,
7375

7476
visibleRequired: (s, g) => Object.values(s.required).filter((pkg) => isVisible(pkg.name, g)),

0 commit comments

Comments
 (0)