Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: migrate to vite #3804

Merged
merged 1 commit into from
Jun 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ yarn-error.log*
.marginalia

js/
/css/
build/
coverage*
vendor/
Expand Down
File renamed without changes.
File renamed without changes.
2 changes: 2 additions & 0 deletions lib/Controller/PageController.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ public function index(): TemplateResponse {
$this->initialStateService->provideInitialState(Application::APP_ID, 'isCirclesEnabled', $isCirclesEnabled && $isCircleVersionCompatible);
$this->initialStateService->provideInitialState(Application::APP_ID, 'isTalkEnabled', $isTalkEnabled && $isTalkVersionCompatible);

Util::addStyle(Application::APP_ID, 'contacts-index');
Util::addStyle(Application::APP_ID, 'contacts-main');
Util::addScript(Application::APP_ID, 'contacts-main');

return new TemplateResponse(Application::APP_ID, 'main');
Expand Down
3 changes: 3 additions & 0 deletions lib/Listener/LoadContactsFilesActions.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ public function handle(Event $event): void {
return;
}

Util::addStyle(Application::APP_ID, 'contacts-index');
Util::addStyle(Application::APP_ID, 'contacts-files-action');

// only available since Nc 28
if (method_exists(Util::class, 'addInitScript')) {
Util::addInitScript(Application::APP_ID, 'contacts-files-action');
Expand Down
11,010 changes: 5,418 additions & 5,592 deletions package-lock.json

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@
"homepage": "https://github.com/nextcloud/contacts",
"license": "agpl",
"private": true,
"type": "module",
"scripts": {
"build": "webpack --node-env production --progress",
"dev": "webpack --node-env development --progress",
"watch": "webpack --node-env development --progress --watch",
"build": "vite build --mode production",
"dev": "vite build --mode development",
"watch": "vite build --mode development --watch",
"lint": "eslint --ext .js,.ts,.vue src",
"lint:fix": "eslint --ext .js,.ts,.vue src --fix",
"stylelint": "stylelint src",
Expand All @@ -53,6 +54,7 @@
"@nextcloud/router": "^2.2.0",
"@nextcloud/sharing": "^0.1.0",
"@nextcloud/vue": "^8.11.3",
"@shortcm/qr-image": "^9.0.4",
"@vueuse/core": "^10.9.0",
"b64-to-blob": "^1.2.19",
"camelcase": "^8.0.0",
Expand All @@ -65,7 +67,6 @@
"moment": "^2.30.1",
"p-limit": "^5.0.0",
"pinia": "^2.1.7",
"qr-image": "^3.2.0",
"string-natural-compare": "^3.0.1",
"uuid": "^9.0.1",
"vue": "~2.7.15",
Expand All @@ -83,14 +84,12 @@
"npm": "^9.0.0"
},
"devDependencies": {
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/preset-env": "^7.24.6",
"@nextcloud/babel-config": "^1.2.0",
"@nextcloud/browserslist-config": "^3.0.1",
"@nextcloud/eslint-config": "^8.3.0",
"@nextcloud/stylelint-config": "^2.3.0",
"@nextcloud/typings": "^1.7.0",
"@nextcloud/webpack-vue-config": "^6.0.1",
"@nextcloud/vite-config": "^1.2.3",
"@types/jest": "^29.5.12",
"@vue/vue2-jest": "^29.2.6",
"babel-jest": "^29.7.0",
Expand All @@ -103,6 +102,7 @@
"ts-jest": "^29.1.3",
"ts-loader": "^9.5.1",
"typescript": "^5.4.5",
"vite": "^5.2.12",
"vue-template-compiler": "~2.7"
},
"browserslist": [
Expand Down
3 changes: 3 additions & 0 deletions src/admin-settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

// eslint-disable-next-line import/no-unresolved, n/no-missing-import
import 'vite/modulepreload-polyfill'

import Vue from 'vue'
import AdminSettings from './components/AdminSettings.vue'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,15 +272,15 @@ export default {
}
},
confirmDeletion() {
OC.dialogs.confirm(
window.OC.dialogs.confirm(
t('contacts', 'This will delete the address book and every contacts within it'),
t('contacts', 'Delete {addressbook}?', { addressbook: this.addressbook.displayName }),
this.deleteAddressbook,
true,
)
},
confirmUnshare() {
OC.dialogs.confirm(
window.OC.dialogs.confirm(
t('contacts', 'This will unshare the address book and every contacts within it'),
t('contacts', 'Unshare {addressbook}?', { addressbook: this.addressbook.displayName }),
this.deleteAddressbook,
Expand Down
12 changes: 7 additions & 5 deletions src/components/ContactDetails.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
<!-- org, title -->
<template #subtitle>
<template v-if="isReadOnly">
<span v-html="formattedSubtitle" />

Check warning on line 51 in src/components/ContactDetails.vue

View workflow job for this annotation

GitHub Actions / NPM lint

'v-html' directive can lead to XSS attack
</template>
<template v-else>
<input id="contact-title"
Expand Down Expand Up @@ -213,7 +213,7 @@
<template #icon>
<IconMail :size="20" />
</template>
<ActionLink v-for="emailAddress in emailAddressList"

Check warning on line 216 in src/components/ContactDetails.vue

View workflow job for this annotation

GitHub Actions / NPM lint

Variable 'emailAddress' is already declared in the upper scope
:key="emailAddress"
:href="'mailto:' + emailAddress">
<template #icon>
Expand Down Expand Up @@ -355,7 +355,7 @@
import { showError } from '@nextcloud/dialogs'

import { stringify } from 'ical.js'
import qr from 'qr-image'
import { getSVG } from '@shortcm/qr-image/lib/svg'
import mitt from 'mitt'
import {
NcActions as Actions,
Expand Down Expand Up @@ -681,7 +681,7 @@
},

enableToggleBirthdayExclusion() {
return parseInt(OC.config.version.split('.')[0]) >= 26
return parseInt(window.OC.config.version.split('.')[0]) >= 26
&& this.localContact?.vCard // Wait until localContact was fetched
},

Expand Down Expand Up @@ -732,7 +732,7 @@
return this.contact.addressbook.id === 'z-server-generated--system'
},
nextcloudVersionAtLeast28() {
return parseInt(OC.config.version.split('.')[0]) >= 28
return parseInt(window.OC.config.version.split('.')[0]) >= 28
},
},

Expand Down Expand Up @@ -788,14 +788,16 @@
/**
* Generate a qrcode for the contact
*/
showQRcode() {
async showQRcode() {
const jCal = this.contact.jCal.slice(0)
// do not encode photo
jCal[1] = jCal[1].filter(props => props[0] !== 'photo')

const data = stringify(jCal)
if (data.length > 0) {
this.qrcode = btoa(qr.imageSync(data, { type: 'svg' }))
const svgBytes = await getSVG(data)
const svgString = new TextDecoder().decode(svgBytes)
this.qrcode = btoa(svgString)
ChristophWurst marked this conversation as resolved.
Show resolved Hide resolved
}
},

Expand Down Expand Up @@ -954,7 +956,7 @@
/**
* Update this.localContact and set this.fixed
*
* @param {Contact} contact the contact to clone

Check warning on line 959 in src/components/ContactDetails.vue

View workflow job for this annotation

GitHub Actions / NPM lint

The type 'Contact' is undefined
*/
async updateLocalContact(contact) {
// create empty contact and copy inner data
Expand Down
2 changes: 1 addition & 1 deletion src/components/DetailsHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export default {
</script>

<style lang="scss" scoped>
@import '../../css/ContactDetailsLayout';
@import '../css/ContactDetailsLayout';

$top-padding: 50px;

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

@import '../ContactDetailsLayout.scss';
@import '../ContactDetailsLayout';

$property-label-max-width: $contact-details-label-max-width;
$property-value-max-width: $contact-details-value-max-width;
Expand Down Expand Up @@ -63,8 +63,8 @@ $property-row-gap: $contact-details-row-gap;

textarea {
// Limit max height to make scrolling the form a bit easier
min-height: 2 * $grid-height-unit - 2*$grid-input-margin;
max-height: 5 * $grid-height-unit - 2*$grid-input-margin;
min-height: 2 * $grid-height-unit - 2 * $grid-input-margin;
max-height: 5 * $grid-height-unit - 2 * $grid-input-margin;
}

input,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

// contacts settings section
.app-contacts #app-settings-content {
padding-left: 0px !important;
padding-left: 0px !important;
}

#app-settings-content {
Expand Down
File renamed without changes.
File renamed without changes.
14 changes: 9 additions & 5 deletions src/files-action.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

// eslint-disable-next-line import/no-unresolved, n/no-missing-import
import 'vite/modulepreload-polyfill'

import ConfirmationDialog from './components/ConfirmationDialog.vue'

import { generateUrl } from '@nextcloud/router'
Expand All @@ -15,7 +19,7 @@ Vue.prototype.t = t

const mime = 'text/vcard'
const name = 'contacts-import'
const nextcloudVersionIsGreaterThanOr28 = parseInt(OC.config.version.split('.')[0]) >= 28
const nextcloudVersionIsGreaterThanOr28 = parseInt(window.OC.config.version.split('.')[0]) >= 28

if (nextcloudVersionIsGreaterThanOr28) {
registerFileAction(new FileAction({
Expand Down Expand Up @@ -62,19 +66,19 @@ if (nextcloudVersionIsGreaterThanOr28) {
}))
} else {
window.addEventListener('DOMContentLoaded', () => {
if (OCA.Files && OCA.Files.fileActions) {
OCA.Files.fileActions.registerAction({
if (window.OCA.Files && window.OCA.Files.fileActions) {
window.OCA.Files.fileActions.registerAction({
name,
displayName: t('contacts', 'Import'),
mime,
permissions: OC.PERMISSION_READ,
permissions: window.OC.PERMISSION_READ,
iconClass: 'icon-contacts-dark',
actionHandler(fileName, context) {
const absPath = `${context.dir === '/' ? '' : context.dir}/${fileName}`
window.location = generateUrl(`/apps/contacts/import?file=${absPath}`)
},
})
OCA.Files.fileActions.setDefault(mime, name)
window.OCA.Files.fileActions.setDefault(mime, name)
return
}
console.error('Unable to register vcf import action')
Expand Down
25 changes: 7 additions & 18 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

/* eslint-disable vue/match-component-file-name */
import { generateFilePath } from '@nextcloud/router'
import { getRequestToken } from '@nextcloud/auth'
// eslint-disable-next-line import/no-unresolved, n/no-missing-import
import 'vite/modulepreload-polyfill'

import { sync } from 'vuex-router-sync'
import Vue from 'vue'

Expand All @@ -19,24 +19,13 @@ import ClickOutside from 'vue-click-outside'
import { Tooltip as VTooltip } from '@nextcloud/vue'

// Global scss sheets
import '../css/contacts.scss'
import './css/contacts.scss'

// Dialogs css
import '@nextcloud/dialogs/style.css'

import { createPinia, PiniaVuePlugin } from 'pinia'

// CSP config for webpack dynamic chunk loading
// eslint-disable-next-line
__webpack_nonce__ = btoa(getRequestToken())

// Correct the root of the app for chunk loading
// OC.linkTo matches the apps folders
// OC.generateUrl ensure the index.php (or not)
// We do not want the index.php since we're loading files
// eslint-disable-next-line
__webpack_public_path__ = generateFilePath('contacts', '', 'js/')

Vue.use(PiniaVuePlugin)
const pinia = createPinia()

Expand All @@ -52,12 +41,12 @@ Vue.prototype.n = n
Vue.prototype.appName = appName
Vue.prototype.appVersion = appVersion
Vue.prototype.logger = logger
Vue.prototype.OC = OC
Vue.prototype.OCA = OCA
Vue.prototype.OC = window.OC
Vue.prototype.OCA = window.OCA

// Force redirect if rewrite enabled but accessed through index.php
if (window.location.pathname.split('/')[1] === 'index.php'
&& OC.config.modRewriteWorking) {
&& window.OC.config.modRewriteWorking) {
router.push({
name: 'group',
params: { selectedGroup: t('contacts', 'All contacts') },
Expand Down
8 changes: 4 additions & 4 deletions src/mixins/CircleActionsMixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ export default {

methods: {
confirmLeaveCircle() {
OC.dialogs.confirmDestructive(
window.OC.dialogs.confirmDestructive(
t('contacts', 'You are about to leave {circle}.\nAre you sure?', {
circle: this.circle.displayName,
}),
t('contacts', 'Please confirm team leave'),
OC.dialogs.YES_NO_BUTTONS,
window.OC.dialogs.YES_NO_BUTTONS,
this.leaveCircle,
true,
)
Expand Down Expand Up @@ -110,12 +110,12 @@ export default {
},

confirmDeleteCircle() {
OC.dialogs.confirmDestructive(
window.OC.dialogs.confirmDestructive(
t('contacts', 'You are about to delete {circle}.\nAre you sure?', {
circle: this.circle.displayName,
}),
t('contacts', 'Please confirm team deletion'),
OC.dialogs.YES_NO_BUTTONS,
window.OC.dialogs.YES_NO_BUTTONS,
this.deleteCircle,
true,
)
Expand Down
2 changes: 1 addition & 1 deletion src/services/cdav.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ function xhrProvider() {
}
return result
}
OC.registerXHRForErrorProcessing(xhr)
window.OC.registerXHRForErrorProcessing(xhr)
return xhr
}

Expand Down
4 changes: 2 additions & 2 deletions src/services/collaborationAutocompletion.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { SHARES_TYPES_MEMBER_MAP } from '../models/constants.ts'

// generate allowed shareType from SHARES_TYPES_MEMBER_MAP
const shareType = Object.keys(SHARES_TYPES_MEMBER_MAP)
const maxAutocompleteResults = parseInt(OC.config['sharing.maxAutocompleteResults'], 10) || 25
const maxAutocompleteResults = parseInt(window.OC.config['sharing.maxAutocompleteResults'], 10) || 25

/**
* Get suggestions
Expand Down Expand Up @@ -107,7 +107,7 @@ const formatResults = function(result) {
label: result.label,
id: `${type}-${result.value.shareWith}`,
// If this is a user, set as user for avatar display by UserBubble
user: [OC.Share.SHARE_TYPE_USER, OC.Share.SHARE_TYPE_REMOTE].indexOf(result.value.shareType) > -1
user: [window.OC.Share.SHARE_TYPE_USER, window.OC.Share.SHARE_TYPE_REMOTE].indexOf(result.value.shareType) > -1
? result.value.shareWith
: null,
type,
Expand Down
File renamed without changes.
4 changes: 4 additions & 0 deletions templates/settings/admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

// TODO: uncomment once there are custom styles in the admin settings entrypoint
// style('contacts', 'contacts-index');
// style('contacts', 'contacts-admin-settings');
st3iny marked this conversation as resolved.
Show resolved Hide resolved
script('contacts', 'contacts-admin-settings');
?>

Expand Down
15 changes: 15 additions & 0 deletions vite.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import path from 'path'
import { createAppConfig } from '@nextcloud/vite-config'

export default createAppConfig({
'main': path.join(__dirname, 'src', 'main.js'),
'files-action': path.join(__dirname, 'src', 'files-action.js'),
'admin-settings': path.join(__dirname, 'src', 'admin-settings.js'),
}, {
inlineCSS: false,
})
Loading