Skip to content

Commit

Permalink
Merge pull request #39106 from nextcloud/fix/update-notification--rem…
Browse files Browse the repository at this point in the history
…ove-deprecated-ncpopupmenu
  • Loading branch information
skjnldsv authored Jul 13, 2023
2 parents b6e73c8 + 8e58c34 commit c35c42f
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 131 deletions.
252 changes: 127 additions & 125 deletions apps/updatenotification/src/components/UpdateNotification.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@
</NcNoteCard>

<p>
<!-- eslint-disable-next-line vue/no-v-html -->
<span v-html="newVersionAvailableString" /><br>
<span v-if="!isListFetched" class="icon icon-loading-small" />
<!-- eslint-disable-next-line vue/no-v-html -->
<span v-html="statusText" />
</p>

<template v-if="missingAppUpdates.length">
<h3 @click="toggleHideMissingUpdates">
<h3 class="clickable" @click="toggleHideMissingUpdates">
{{ t('updatenotification', 'Apps missing compatible version') }}
<span v-if="!hideMissingUpdates" class="icon icon-triangle-n" />
<span v-if="hideMissingUpdates" class="icon icon-triangle-s" />
Expand All @@ -26,7 +28,7 @@
</template>

<template v-if="availableAppUpdates.length">
<h3 @click="toggleHideAvailableUpdates">
<h3 class="clickable" @click="toggleHideAvailableUpdates">
{{ t('updatenotification', 'Apps with compatible version') }}
<span v-if="!hideAvailableUpdates" class="icon icon-triangle-n" />
<span v-if="hideAvailableUpdates" class="icon icon-triangle-s" />
Expand Down Expand Up @@ -56,14 +58,26 @@
<span v-if="updaterEnabled && !webUpdaterEnabled">
{{ t('updatenotification', 'Please use the command line updater to update.') }}
</span>
<div v-if="whatsNew" class="whatsNew">
<div class="toggleWhatsNew">
<a v-click-outside="hideMenu" class="button" @click="toggleMenu">{{ t('updatenotification', 'What\'s new?') }}</a>
<div class="popovermenu" :class="{ 'menu-center': true, open: openedWhatsNew }">
<NcPopoverMenu :menu="whatsNew" />
</div>
</div>
</div>
<NcActions v-if="whatsNewData || changelogURL"
:force-menu="true"
:menu-title="t('updatenotification', 'What\'s new?')"
type="tertiary">
<template #icon>
<IconNewBox :size="20" />
</template>
<template #default>
<NcActionCaption v-for="changes,index in whatsNewData" :key="index" :title="changes" />
<NcActionLink v-if="changelogURL"
:href="changelogURL"
close-after-click
target="_blank">
{{ t('updatenotification', 'View changelog') }}
<template #icon>
<IconLink :size="20" />
</template>
</NcActionLink>
</template>
</NcActions>
</div>
</template>
<template v-else-if="!isUpdateChecked">
Expand All @@ -81,61 +95,80 @@
</template>
</div>

<div>
{{ t('updatenotification', 'You can change the update channel below which also affects the apps management page. E.g. after switching to the beta channel, beta app updates will be offered to you in the apps management page.') }}
<h3>{{ t('updatenotification', 'Update channel') }}</h3>
<p class="inlineblock">
{{ t('updatenotification', 'Changing the update channel also affects the apps management page. E.g. after switching to the beta channel, beta app updates will be offered to you in the apps management page.') }}
</p>
<div class="update-channel-selector">
<span>{{ t('updatenotification', 'Current update channel:') }}</span>
<NcActions :force-menu="true"
:menu-title="localizedChannelName"
type="tertiary">
<template #icon>
<IconChevronDown :size="20" />
</template>
<template #default>
<!-- TODO use NcActionRadio if it provides long text, e.g. subtitle -->
<NcActionButton v-for="channel,index in channelList"
:key="index"
:aria-checked="channel.active ? 'true' : 'false'"
:aria-label="channel.text"
:disabled="!!channel.disabled"
:icon="channel.icon"
:name="channel.text"
class="update-channel-action"
close-after-click
role="menuitemradio"
@click="channel.action">
{{ channel.longtext }}
</NcActionButton>
</template>
</NcActions>
</div>

<h3 class="update-channel-selector">
{{ t('updatenotification', 'Update channel:') }}
<div v-click-outside="closeUpdateChannelMenu" class="update-menu">
<span class="icon-update-menu" @click="toggleUpdateChannelMenu">
{{ localizedChannelName }}
<span class="icon-triangle-s" />
</span>
<div class="popovermenu menu menu-center" :class="{ 'show-menu': openedUpdateChannelMenu}">
<NcPopoverMenu :menu="channelList" />
</div>
</div>
</h3>
<span id="channel_save_msg" class="msg" /><br>
<p>
<em>{{ t('updatenotification', 'You can always update to a newer version. But you can never downgrade to a more stable version.') }}</em><br>
<!-- eslint-disable-next-line vue/no-v-html -->
<em v-html="noteDelayedStableString" />
</p>

<p id="oca_updatenotification_groups">
{{ t('updatenotification', 'Notify members of the following groups about available updates:') }}
<NcSelect v-model="notifyGroups"
:options="groups"
:multiple="true"
label="displayname"
:loading="loadingGroups"
:close-on-select="false"
@search="searchGroup">
<template #no-options>
{{ t('updatenotification', 'No groups') }}
</template>
</NcSelect>
<br>
<h4>{{ t('updatenotification', 'Notify members of the following groups about available updates:') }}</h4>
<NcSelect v-model="notifyGroups"
:options="groups"
:multiple="true"
label="displayname"
:loading="loadingGroups"
:close-on-select="false"
@search="searchGroup">
<template #no-options>
{{ t('updatenotification', 'No groups') }}
</template>
</NcSelect>
<p>
<em v-if="currentChannel === 'daily' || currentChannel === 'git'">{{ t('updatenotification', 'Only notifications for app updates are available.') }}</em>
<em v-if="currentChannel === 'daily'">{{ t('updatenotification', 'The selected update channel makes dedicated notifications for the server obsolete.') }}</em>
<em v-if="currentChannel === 'git'">{{ t('updatenotification', 'The selected update channel does not support updates of the server.') }}</em>
<em v-else-if="currentChannel === 'git'">{{ t('updatenotification', 'The selected update channel does not support updates of the server.') }}</em>
</p>
</NcSettingsSection>
</template>

<script>
import { showSuccess } from '@nextcloud/dialogs'
import { loadState } from '@nextcloud/initial-state'
import { getLoggerBuilder } from '@nextcloud/logger'
import { generateUrl, getRootUrl, generateOcsUrl } from '@nextcloud/router'
import NcPopoverMenu from '@nextcloud/vue/dist/Components/NcPopoverMenu.js'
import axios from '@nextcloud/axios'
import NcActions from '@nextcloud/vue/dist/Components/NcActions.js'
import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
import NcActionCaption from '@nextcloud/vue/dist/Components/NcActionCaption.js'
import NcActionLink from '@nextcloud/vue/dist/Components/NcActionLink.js'
import NcNoteCard from '@nextcloud/vue/dist/Components/NcNoteCard.js'
import NcSelect from '@nextcloud/vue/dist/Components/NcSelect.js'
import NcSettingsSection from '@nextcloud/vue/dist/Components/NcSettingsSection.js'
import NcNoteCard from '@nextcloud/vue/dist/Components/NcNoteCard.js'
import ClickOutside from 'vue-click-outside'
import axios from '@nextcloud/axios'
import { loadState } from '@nextcloud/initial-state'
import { showSuccess } from '@nextcloud/dialogs'
import IconChevronDown from 'vue-material-design-icons/ChevronDown.vue'
import IconLink from 'vue-material-design-icons/Link.vue'
import IconNewBox from 'vue-material-design-icons/NewBox.vue'
import debounce from 'debounce'
import { getLoggerBuilder } from '@nextcloud/logger'
const logger = getLoggerBuilder()
.setApp('updatenotification')
Expand All @@ -145,13 +178,16 @@ const logger = getLoggerBuilder()
export default {
name: 'UpdateNotification',
components: {
IconChevronDown,
IconLink,
IconNewBox,
NcActions,
NcActionButton,
NcActionCaption,
NcActionLink,
NcNoteCard,
NcSelect,
NcPopoverMenu,
NcSettingsSection,
NcNoteCard,
},
directives: {
ClickOutside,
},
data() {
return {
Expand Down Expand Up @@ -224,26 +260,6 @@ export default {
: n('updatenotification', '<strong>%n</strong> app has no compatible version for this Nextcloud version available.', '<strong>%n</strong> apps have no compatible version for this Nextcloud version available.', this.missingAppUpdates.length)
},
whatsNew() {
if (this.whatsNewData.length === 0) {
return null
}
const whatsNew = []
for (const i in this.whatsNewData) {
whatsNew[i] = { icon: 'icon-checkmark', longtext: this.whatsNewData[i] }
}
if (this.changelogURL) {
whatsNew.push({
href: this.changelogURL,
text: t('updatenotification', 'View changelog'),
icon: 'icon-link',
target: '_blank',
action: '',
})
}
return whatsNew
},
channelList() {
const channelList = []
Expand Down Expand Up @@ -277,6 +293,7 @@ export default {
text: this.currentChannel,
icon: 'icon-rename',
active: true,
action: () => {},
})
}
Expand Down Expand Up @@ -431,24 +448,12 @@ export default {
this.openedUpdateChannelMenu = false
},
toggleUpdateChannelMenu() {
this.openedUpdateChannelMenu = !this.openedUpdateChannelMenu
},
toggleHideMissingUpdates() {
this.hideMissingUpdates = !this.hideMissingUpdates
},
toggleHideAvailableUpdates() {
this.hideAvailableUpdates = !this.hideAvailableUpdates
},
toggleMenu() {
this.openedWhatsNew = !this.openedWhatsNew
},
closeUpdateChannelMenu() {
this.openedUpdateChannelMenu = false
},
hideMenu() {
this.openedWhatsNew = false
},
},
}
</script>
Expand All @@ -459,6 +464,10 @@ export default {
max-width: 900px;
}
.topMargin {
margin-top: 15px;
}
div.update,
p:not(.inlineblock) {
margin-bottom: 25px;
Expand All @@ -467,17 +476,23 @@ export default {
margin-top: 25px;
}
h3 {
cursor: pointer;
.icon {
&.clickable {
cursor: pointer;
.icon {
cursor: pointer;
}
}
&:first-of-type {
margin-top: 0;
}
&.update-channel-selector {
display: inline-block;
cursor: inherit;
}
}
h4 {
margin-block-end: 0.7rem;
}
.update-channel-selector {
display: flex;
align-items: center;
gap: 12px;
}
.icon {
display: inline-block;
Expand All @@ -486,20 +501,6 @@ export default {
.icon-triangle-s, .icon-triangle-n {
opacity: 0.5;
}
.whatsNew {
display: inline-block;
}
.toggleWhatsNew {
position: relative;
}
.popovermenu {
p {
margin-bottom: 0;
width: 100%;
}
margin-top: 5px;
width: 300px;
}
.applist {
margin-bottom: 25px;
}
Expand All @@ -518,32 +519,33 @@ export default {
opacity: 1;
}
}
.popovermenu {
display: none;
top: 28px;
&.show-menu {
display: block;
}
}
}
}
</style>
<style lang="scss">
/* override needed to make menu wider */
#updatenotification .popovermenu {
p {
margin-top: 5px;
width: 100%;
}
margin-top: 5px;
width: 300px;
// Make current selected update channel visually visible, remove if NcActionRadio is used
.update-channel-action[aria-checked=true] {
border-inline-start: 4px solid var(--color-primary-element);
&:hover, &:focus-within {
background-color: var(--color-primary-element-light-hover);
}
button {
background-color: var(--color-primary-element-light);
color: var(--color-primary-element-light-text);
}
}
// Ensure outline for focus-visible works even with background color of selected channel
.update-channel-action[aria-checked] {
margin-block: 2px;
}
#updatenotification {
/* override needed to replace yellow hover state with a dark one */
#updatenotification .update-menu .icon-star:hover,
#updatenotification .update-menu .icon-star:focus {
.update-menu .icon-star:hover,
.update-menu .icon-star:focus {
background-image: var(--icon-starred);
}
#updatenotification .topMargin {
margin-top: 15px;
}
}
</style>
5 changes: 3 additions & 2 deletions apps/updatenotification/src/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,18 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
import { translate, translatePlural } from '@nextcloud/l10n'

import Vue from 'vue'
import Root from './components/UpdateNotification.vue'

Vue.mixin({
methods: {
t(app, text, vars, count, options) {
return OC.L10N.translate(app, text, vars, count, options)
return translate(app, text, vars, count, options)
},
n(app, textSingular, textPlural, count, vars, options) {
return OC.L10N.translatePlural(app, textSingular, textPlural, count, vars, options)
return translatePlural(app, textSingular, textPlural, count, vars, options)
},
},
})
Expand Down
Loading

0 comments on commit c35c42f

Please sign in to comment.