Skip to content
2 changes: 1 addition & 1 deletion apps/comments/src/components/CommentEntry.vue
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
</NcActions>

<!-- Show loading if we're editing or deleting, not on new ones -->
<div v-if="id && loading" class="comment_loading icon-loading-small" />
<NcLoadingIcon v-if="id && loading" class="comment_loading" :size="16" />

<!-- Relative time to the comment creation -->
<NcDateTime
Expand Down
13 changes: 7 additions & 6 deletions apps/comments/src/views/CommentsApp.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@
-->

<template>
<div
v-element-visibility="onVisibilityChange"
class="comments"
:class="{ 'icon-loading': isFirstLoading }">
<div v-element-visibility="onVisibilityChange" class="comments">
<!-- Editor -->
<CommentEntry
v-bind="editorData"
Expand Down Expand Up @@ -45,7 +42,7 @@
</ul>

<!-- Loading more message -->
<div v-if="loading && !isFirstLoading" class="comments__info icon-loading" />
<NcLoadingIcon v-if="loading && !isFirstLoading" class="comments__info" :size="28" />

<div v-else-if="hasComments && done" class="comments__info">
{{ t('comments', 'No more messages') }}
Expand All @@ -66,6 +63,7 @@
</NcButton>
</template>
</template>
<NcLoadingIcon v-else class="comments__loading" :size="28" />
</div>
</template>

Expand All @@ -75,6 +73,7 @@ import { translate as t } from '@nextcloud/l10n'
import { vElementVisibility as elementVisibility } from '@vueuse/components'
import NcButton from '@nextcloud/vue/components/NcButton'
import NcEmptyContent from '@nextcloud/vue/components/NcEmptyContent'
import NcLoadingIcon from '@nextcloud/vue/components/NcLoadingIcon'
import IconAlertCircleOutline from 'vue-material-design-icons/AlertCircleOutline.vue'
import IconMessageReplyTextOutline from 'vue-material-design-icons/MessageReplyTextOutline.vue'
import IconRefresh from 'vue-material-design-icons/Refresh.vue'
Expand All @@ -92,6 +91,7 @@ export default {
CommentEntry,
NcEmptyContent,
NcButton,
NcLoadingIcon,
IconRefresh,
IconMessageReplyTextOutline,
IconAlertCircleOutline,
Expand Down Expand Up @@ -271,7 +271,8 @@ export default {
flex-direction: column;

&__empty,
&__error {
&__error,
&__loading {
flex: 1 0;
}

Expand Down
8 changes: 6 additions & 2 deletions apps/files/src/views/TemplatePicker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,10 @@
</div>
</form>

<NcEmptyContent v-if="loading" class="templates-picker__loading" icon="icon-loading">
{{ t('files', 'Creating file') }}
<NcEmptyContent v-if="loading" class="templates-picker__loading" :name="t('files', 'Creating file')">
<template #icon>
<NcLoadingIcon />
</template>
</NcEmptyContent>
</NcModal>
</template>
Expand All @@ -67,6 +69,7 @@ import { spawnDialog } from '@nextcloud/vue/functions/dialog'
import { extname, join, normalize } from 'path'
import { defineComponent } from 'vue'
import NcEmptyContent from '@nextcloud/vue/components/NcEmptyContent'
import NcLoadingIcon from '@nextcloud/vue/components/NcLoadingIcon'
import NcModal from '@nextcloud/vue/components/NcModal'
import TemplateFiller from '../components/TemplateFiller.vue'
import TemplatePreview from '../components/TemplatePreview.vue'
Expand All @@ -81,6 +84,7 @@ export default defineComponent({

components: {
NcEmptyContent,
NcLoadingIcon,
NcModal,
TemplatePreview,
},
Expand Down
18 changes: 13 additions & 5 deletions apps/settings/src/authtokens/components/AuthToken.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<script setup lang="ts">
import type { IToken } from '../store/authtoken.ts'

import { mdiAndroid, mdiAppleIos, mdiAppleSafari, mdiCellphone, mdiCheck, mdiFirefox, mdiGoogleChrome, mdiKeyOutline, mdiMicrosoftEdge, mdiMonitor, mdiTablet, mdiWeb } from '@mdi/js'
import { mdiAndroid, mdiAppleIos, mdiAppleSafari, mdiCellphone, mdiCheck, mdiFirefox, mdiGoogleChrome, mdiKeyOutline, mdiMicrosoftEdge, mdiMonitor, mdiPencilOutline, mdiTablet, mdiTrashCanOutline, mdiWeb } from '@mdi/js'
import { showConfirmation } from '@nextcloud/dialogs'
import { t } from '@nextcloud/l10n'
import { computed, nextTick, ref, useTemplateRef } from 'vue'
Expand Down Expand Up @@ -279,8 +279,10 @@ async function wipe() {
<!-- TODO: add text/longtext with some description -->
<NcActionButton
v-if="token.canRename"
icon="icon-rename"
@click.stop.prevent="startRename">
<template #icon>
<NcIconSvgWrapper :path="mdiPencilOutline" />
</template>
{{ t('settings', 'Rename') }}
</NcActionButton>

Expand All @@ -289,21 +291,27 @@ async function wipe() {
<template v-if="token.type !== TokenType.WIPING_TOKEN">
<!-- TODO: add text/longtext with some description -->
<NcActionButton
icon="icon-delete"
@click.stop.prevent="revoke">
<template #icon>
<NcIconSvgWrapper :path="mdiTrashCanOutline" />
</template>
{{ t('settings', 'Revoke') }}
</NcActionButton>
<NcActionButton
icon="icon-delete"
@click.stop.prevent="wipe">
<template #icon>
<NcIconSvgWrapper :path="mdiTrashCanOutline" />
</template>
{{ t('settings', 'Wipe device') }}
</NcActionButton>
</template>
<NcActionButton
v-else
icon="icon-delete"
:name="t('settings', 'Revoke')"
@click.stop.prevent="revoke">
<template #icon>
<NcIconSvgWrapper :path="mdiTrashCanOutline" />
</template>
{{ t('settings', 'Revoking this token might prevent the wiping of your device if it has not started the wipe yet.') }}
</NcActionButton>
</template>
Expand Down
26 changes: 18 additions & 8 deletions apps/updatenotification/src/views/AdminSettingsSection.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@
<p>
<!-- eslint-disable-next-line vue/no-v-html -->
<span v-html="newVersionAvailableString" /><br>
<span v-if="!isListFetched" class="icon icon-loading-small" />
<NcLoadingIcon v-if="!isListFetched" class="icon" :size="16" />
<!-- eslint-disable-next-line vue/no-v-html -->
<span v-html="statusText" />
</p>

<template v-if="missingAppUpdates.length">
<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" />
<IconMenuDown v-if="hideMissingUpdates" class="icon icon--toggle" :size="16" />
<IconMenuUp v-else class="icon icon--toggle" :size="16" />
</h3>
<ul v-if="!hideMissingUpdates" class="applist">
<li v-for="(app, index) in missingAppUpdates" :key="index">
Expand All @@ -34,8 +34,8 @@
<template v-if="availableAppUpdates.length">
<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" />
<IconMenuDown v-if="hideAvailableUpdates" class="icon icon--toggle" :size="16" />
<IconMenuUp v-else class="icon icon--toggle" :size="16" />
</h3>
<ul v-if="!hideAvailableUpdates" class="applist">
<li v-for="(app, index) in availableAppUpdates" :key="index">
Expand Down Expand Up @@ -97,8 +97,10 @@
:title="lastCheckedOnString"
:aria-label="lastCheckedOnString"
href="https://nextcloud.com/changelog/"
class="icon-info details"
target="_blank" />
class="details"
target="_blank">
<IconInformationOutline class="icon" :size="16" />
</a>
</template>

<template v-if="!isDefaultUpdateServerURL">
Expand Down Expand Up @@ -182,12 +184,16 @@ import NcActionButton from '@nextcloud/vue/components/NcActionButton'
import NcActionCaption from '@nextcloud/vue/components/NcActionCaption'
import NcActionLink from '@nextcloud/vue/components/NcActionLink'
import NcActions from '@nextcloud/vue/components/NcActions'
import NcLoadingIcon from '@nextcloud/vue/components/NcLoadingIcon'
import NcNoteCard from '@nextcloud/vue/components/NcNoteCard'
import NcSelect from '@nextcloud/vue/components/NcSelect'
import NcSettingsSection from '@nextcloud/vue/components/NcSettingsSection'
import IconChevronDown from 'vue-material-design-icons/ChevronDown.vue'
import IconCloudCheckVariant from 'vue-material-design-icons/CloudCheckVariant.vue'
import IconInformationOutline from 'vue-material-design-icons/InformationOutline.vue'
import IconLink from 'vue-material-design-icons/Link.vue'
import IconMenuDown from 'vue-material-design-icons/MenuDown.vue'
import IconMenuUp from 'vue-material-design-icons/MenuUp.vue'
import IconNewBox from 'vue-material-design-icons/NewBox.vue'
import IconPencil from 'vue-material-design-icons/PencilOutline.vue'
import IconSourceBranch from 'vue-material-design-icons/SourceBranch.vue'
Expand All @@ -202,12 +208,16 @@ export default defineComponent({
name: 'UpdateNotification',
components: {
IconChevronDown,
IconInformationOutline,
IconLink,
IconMenuDown,
IconMenuUp,
IconNewBox,
NcActions,
NcActionButton,
NcActionCaption,
NcActionLink,
NcLoadingIcon,
NcNoteCard,
NcSelect,
NcSettingsSection,
Expand Down Expand Up @@ -535,7 +545,7 @@ export default defineComponent({
display: inline-block;
margin-bottom: -3px;
}
.icon-triangle-s, .icon-triangle-n {
.icon--toggle {
opacity: 0.5;
}
.applist {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,20 @@
<div
v-else
class="predefined-statuses-list">
<div class="icon icon-loading-small" />
<NcLoadingIcon :size="16" />
</div>
</template>

<script>
import { t } from '@nextcloud/l10n'
import { mapGetters, mapState } from 'vuex'
import NcLoadingIcon from '@nextcloud/vue/components/NcLoadingIcon'
import PredefinedStatus from './PredefinedStatus.vue'

export default {
name: 'PredefinedStatusesList',
components: {
NcLoadingIcon,
PredefinedStatus,
},

Expand Down
12 changes: 10 additions & 2 deletions apps/weather_status/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,16 @@
ref="addressInput"
:label="t('weather_status', 'Set custom address')"
:disabled="false"
icon="icon-rename"
type="text"
modelValue=""
@submit="onAddressSubmit" />
@submit="onAddressSubmit">
<template #icon>
<NcIconSvgWrapper
name="Pencil"
:svg="pencilOutlineSvg"
:size="20" />
</template>
</NcActionInput>
<template v-if="favorites.length > 0">
<NcActionCaption :name="t('weather_status', 'Favorites')" />
<NcActionButton
Expand All @@ -98,6 +104,7 @@
<script>
import crosshairsSvg from '@mdi/svg/svg/crosshairs.svg?raw'
import mapMarkerSvg from '@mdi/svg/svg/map-marker.svg?raw'
import pencilOutlineSvg from '@mdi/svg/svg/pencil-outline.svg?raw'
import starOutlineSvg from '@mdi/svg/svg/star-outline.svg?raw'
import starSvg from '@mdi/svg/svg/star.svg?raw'
import { showError } from '@nextcloud/dialogs'
Expand Down Expand Up @@ -553,6 +560,7 @@ export default {
return {
crosshairsSvg,
mapMarkerSvg,
pencilOutlineSvg,
starSvg,
starOutlineSvg,
locale: getLocale(),
Expand Down
8 changes: 8 additions & 0 deletions core/src/components/UnifiedSearch/LegacySearchResult.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@
<script setup lang="ts">
import { computed, ref, watch } from 'vue'
import NcHighlight from '@nextcloud/vue/components/NcHighlight'
import NcLoadingIcon from '@nextcloud/vue/components/NcLoadingIcon'

const props = withDefaults(defineProps<{
title: string
thumbnailUrl?: string | null
subline?: string | null
resourceUrl?: string | null
icon?: string
/** Show a spinner instead of the icon */
loading?: boolean
rounded?: boolean
query?: string
/**
Expand All @@ -25,6 +28,7 @@ const props = withDefaults(defineProps<{
subline: null,
resourceUrl: null,
icon: '',
loading: false,
rounded: false,
query: '',
focused: false,
Expand Down Expand Up @@ -96,6 +100,7 @@ function onLoad() {
:style="{
backgroundImage: isIconUrl ? `url(${icon})` : '',
}">
<NcLoadingIcon v-if="loading" :size="16" />

<img
v-if="hasValidThumbnail"
Expand Down Expand Up @@ -146,6 +151,9 @@ $margin: 10px;
}

&-icon {
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
width: $clickable-area;
height: $clickable-area;
Expand Down
14 changes: 14 additions & 0 deletions core/src/tests/views/LegacyUnifiedSearch.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,20 @@ describe('LegacyUnifiedSearch results', () => {
expect(wrapper.vm.reached.files).toBe(true)
})

it('flags a provider as loading while its next page is fetched', async () => {
respondWith({
files: [{ entries: entries(2), cursor: 2, isPaginated: true }, { entries: entries(2, 'more'), cursor: 4, isPaginated: true }],
mail: [{ entries: [] }],
})
const wrapper = await searchFor('file')

const loaded = wrapper.vm.loadMore('files')
expect(wrapper.vm.loading.files).toBe(true)

await loaded
expect(wrapper.vm.loading.files).toBe(false)
})

it('reveals the results of a provider without pagination in steps of the limit', async () => {
respondWith({ files: [{ entries: entries(5) }], mail: [{ entries: [] }] })
const wrapper = await searchFor('file')
Expand Down
Loading
Loading