diff --git a/changelog/unreleased/change-remove-importer b/changelog/unreleased/change-remove-importer new file mode 100644 index 00000000000..0aa904300c5 --- /dev/null +++ b/changelog/unreleased/change-remove-importer @@ -0,0 +1,8 @@ +Change: Remove importer as default app + +BREAKING CHANGE for administrators: importer has been removed as default web app. The app is now available via the [web-extensions repository](https://github.com/owncloud/web-extensions). + +Please refer to [the web-app docs](https://owncloud.dev/services/web/#web-apps) to see how to load an external web app. + +https://github.com/owncloud/web/pull/11709 +https://github.com/owncloud/web/issues/11698 diff --git a/dev/docker/ocis.web-federated.config.json b/dev/docker/ocis.web-federated.config.json index 28f96171d13..f60d1c805fe 100644 --- a/dev/docker/ocis.web-federated.config.json +++ b/dev/docker/ocis.web-federated.config.json @@ -29,13 +29,6 @@ "config": { "mimeTypes": ["image/tiff", "image/bmp", "image/x-ms-bmp"] } - }, - { - "id": "importer", - "path": "web-app-importer", - "config": { - "companionUrl": "https://host.docker.internal:9200/companion" - } } ] } diff --git a/dev/docker/ocis.web.config.json b/dev/docker/ocis.web.config.json index b6e680d769b..f0a66cbe494 100644 --- a/dev/docker/ocis.web.config.json +++ b/dev/docker/ocis.web.config.json @@ -28,18 +28,7 @@ "id": "preview", "path": "web-app-preview", "config": { - "mimeTypes": [ - "image/tiff", - "image/bmp", - "image/x-ms-bmp" - ] - } - }, - { - "id": "importer", - "path": "web-app-importer", - "config": { - "companionUrl": "https://host.docker.internal:9200/companion" + "mimeTypes": ["image/tiff", "image/bmp", "image/x-ms-bmp"] } } ] diff --git a/docker-compose.yml b/docker-compose.yml index 1a195bbd4e4..44289fc06f8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -145,28 +145,6 @@ services: - ocis-federated-config:/etc/ocis - ${OCIS_WEB_CONFIG:-./dev/docker/ocis.web-federated.config.json}:/web/config.json:ro - companion: - image: owncloud/uppy-companion:3.12.13-owncloud - extra_hosts: - - host.docker.internal:${DOCKER_HOST:-host-gateway} - environment: - NODE_TLS_REJECT_UNAUTHORIZED: 0 - COMPANION_ALLOW_LOCAL_URLS: 'true' - COMPANION_DATADIR: /tmp/companion/ - COMPANION_DOMAIN: host.docker.internal:9200 - COMPANION_PROTOCOL: https - COMPANION_PATH: /companion - COMPANION_ONEDRIVE_KEY: '${COMPANION_ONEDRIVE_KEY}' - COMPANION_ONEDRIVE_SECRET: '${COMPANION_ONEDRIVE_SECRET}' - volumes: - - uppy_companion_datadir:/tmp/companion/ - labels: - traefik.enable: true - traefik.http.routers.companion.tls: true - traefik.http.routers.companion.rule: Host(`host.docker.internal`) && PathPrefix(`/companion`) - traefik.http.routers.companion.entrypoints: ocis - traefik.http.services.companion.loadbalancer.server.port: 3020 - collaboration: image: ${OCIS_IMAGE:-owncloud/ocis-rolling:master} depends_on: @@ -365,7 +343,6 @@ services: volumes: uploads: - uppy_companion_datadir: ocis-config: ocis-federated-config: diff --git a/packages/web-app-importer/l10n/.tx/config b/packages/web-app-importer/l10n/.tx/config deleted file mode 100644 index 0fa95f8395d..00000000000 --- a/packages/web-app-importer/l10n/.tx/config +++ /dev/null @@ -1,9 +0,0 @@ -[main] -host = https://www.transifex.com - -[o:owncloud-org:p:owncloud-web:r:importer] -file_filter = locale//app.po -minimum_perc = 0 -source_file = template.pot -source_lang = en -type = PO diff --git a/packages/web-app-importer/l10n/translations.json b/packages/web-app-importer/l10n/translations.json deleted file mode 100644 index 9b6285bab4c..00000000000 --- a/packages/web-app-importer/l10n/translations.json +++ /dev/null @@ -1 +0,0 @@ -{"af":{},"ar":{"Cancel":"إلغاء"},"bg":{"Cancel":"Отказ","Import":"Импортиране","Import files":"Импортиране на файлове","Import files from:":"Импортиране на файлове от:","Import from %{name}":"Импортиране от %{name}"},"cs":{"Cancel":"Zrušit"},"de":{"Cancel":"Abbrechen","Import":"Importieren","Import files":"Dateien importieren","Import files from:":"Dateien importieren von:","Import from %{name}":"Importieren von %{name}","Importer":"Importeur","Please wait until all imports have finished":"Bitte warten, bis alle Importe abgeschlossen sind."},"el":{"Cancel":"Ακύρωση"},"bs":{},"es":{"Cancel":"Cancelar","Import":"Importar","Import files":"Importar archivos","Import files from:":"Importar archivos de:","Import from %{name}":"Importar de %{name}","Importer":"Importador","Please wait until all imports have finished":"Espere a que finalicen todas las importaciones"},"et":{},"fr":{"Cancel":"Annuler"},"gl":{"Cancel":"Cancelar"},"he":{"Cancel":"ביטול","Import":"ייבוא","Import files":"ייבוא קבצים","Import files from:":"ייבוא קבצים מתוך:","Import from %{name}":"ייבוא מתוך %{name}","Importer":"מייבא","Please wait until all imports have finished":"נא להמתין לסיום תהליכי הייבוא"},"it":{"Cancel":"Cancella"},"hr":{},"ja":{},"id":{"Cancel":"Batal"},"pl":{"Cancel":"Anuluj","Import":"Import","Import files":"Importuj pliki","Import files from:":"Importuj pliki z:","Import from %{name}":"Importuj z %{name}","Importer":"Importer","Please wait until all imports have finished":"Poczekaj, aż import się zakończy"},"nl":{"Cancel":"Annuleer","Import":"Importeren","Import files":"Importeer bestanden","Import files from:":"Importeer bestanden uit:","Import from %{name}":"Importeer uit %{name}","Importer":"Importeerder","Please wait until all imports have finished":"Wacht svp tot alle imports zijn voltooid"},"ko":{"Cancel":"취소","Import":"가져오기","Import files":"파일 가져오기","Import files from:":"다음에서 파일 가져오기:","Import from %{name}":"%{name}에서 가져오기","Please wait until all imports have finished":"내보내기가 완료될 때까지 잠시 기다려주세요"},"pt":{},"ro":{"Cancel":"Anulează"},"ka":{},"ru":{"Cancel":"Отмена","Import":"Импорт","Import files":"Импортировать файлы","Import files from:":"Импортировать файлы из:","Import from %{name}":"Импортировать из %{name}","Importer":"Импортируется посредством","Please wait until all imports have finished":"Пожалуйста, подождите, пока весь импорт не завершится."},"si":{"Cancel":"අවලංගු"},"sk":{"Cancel":"Zrušiť"},"sq":{"Cancel":"Anuloje","Import":"Importo","Import files":"Importo kartela","Import files from:":"Importo kartela prej:","Import from %{name}":"Importo prej %{name}","Importer":"Importues","Please wait until all imports have finished":"Ju lutemi, pritni deri sa të kenë përfunduar krejt importimet"},"sr":{},"ta":{"Cancel":"ரத்துசெய்"},"sv":{"Cancel":"Avbryt","Import":"Importera","Import files":"Importera filer","Import files from:":"Importera filer från:","Import from %{name}":"Importera från %{name}","Importer":"Importerare","Please wait until all imports have finished":"Vänligen vänta tills importeringen blir klar"},"tr":{"Cancel":"İptal","Import":"İçe Aktar","Import files":"İçe aktarılan dosyalar","Import files from:":"Şuradan içe aktarılan dosyalar:","Import from %{name}":"%{name}'dan içe aktar","Importer":"İçe aktaran","Please wait until all imports have finished":"Lütfen tüm içe aktarma işlemleri bitene kadar bekleyin"},"ug":{},"uk":{"Cancel":"Скасувати","Import":"Імпорт","Import files":"Імпорт файлів","Import files from:":"Імпортувати файли з:","Import from %{name}":"Імпортувати з %{name}","Importer":"Імпортер","Please wait until all imports have finished":"Будь ласка, зачекайте, доки всі імпорти завершаться"},"zh":{"Cancel":"取消","Import":"导入","Import files":"导入文件","Import files from:":"导入文件从:","Import from %{name}":"从 %{name} 导入","Importer":"导入器","Please wait until all imports have finished":"请等待所有导入完成。"}} \ No newline at end of file diff --git a/packages/web-app-importer/package.json b/packages/web-app-importer/package.json deleted file mode 100644 index 0fa751ef928..00000000000 --- a/packages/web-app-importer/package.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "web-app-importer", - "version": "0.0.0", - "private": true, - "description": "ownCloud Web Importer", - "license": "AGPL-3.0", - "devDependencies": { - "web-test-helpers": "workspace:*" - }, - "dependencies": { - "@uppy/dashboard": "3.3.0", - "@uppy/google-drive": "3.3.0", - "@uppy/onedrive": "3.3.0", - "@uppy/webdav": "https://github.com/owncloud/uppy/releases/download/v3.12.13-owncloud/uppy-webdav.tgz" - }, - "peerDependencies": { - "@ownclouders/design-system": "workspace:*", - "@ownclouders/web-client": "workspace:*", - "@ownclouders/web-pkg": "workspace:*", - "@uppy/core": "^3.3.0", - "pinia": "^2.1.7" - } -} diff --git a/packages/web-app-importer/src/extensions.ts b/packages/web-app-importer/src/extensions.ts deleted file mode 100644 index 7e194365552..00000000000 --- a/packages/web-app-importer/src/extensions.ts +++ /dev/null @@ -1,154 +0,0 @@ -import { storeToRefs } from 'pinia' -import { - useThemeStore, - useModals, - useUserStore, - useAuthStore, - useResourcesStore -} from '@ownclouders/web-pkg' -import { useGettext } from 'vue3-gettext' -import { useService } from '@ownclouders/web-pkg' -import { computed, nextTick, unref } from 'vue' -import type { UppyService } from '@ownclouders/web-pkg' -import '@uppy/dashboard/dist/style.min.css' -import { Extension } from '@ownclouders/web-pkg' -import { ApplicationSetupOptions } from '@ownclouders/web-pkg' - -// @ts-ignore -import { WebdavPublicLink } from '@uppy/webdav' - -export const extensions = ({ applicationConfig }: ApplicationSetupOptions) => { - const userStore = useUserStore() - const { $gettext } = useGettext() - const uppyService = useService('$uppyService') - const authStore = useAuthStore() - const themeStore = useThemeStore() - const { currentTheme } = storeToRefs(themeStore) - const modals = useModals() - const { dispatchModal, removeModal } = modals - const { activeModal } = storeToRefs(modals) - - const resourcesStore = useResourcesStore() - const { currentFolder } = storeToRefs(resourcesStore) - - const { companionUrl, webdavCloudType } = applicationConfig - let { supportedClouds } = applicationConfig - supportedClouds = supportedClouds || ['OneDrive', 'GoogleDrive', 'WebdavPublicLink'] - - const canUpload = computed(() => { - return unref(currentFolder)?.canUpload({ user: userStore.user }) - }) - - const removeUppyPlugins = () => { - const dashboardPlugin = uppyService.getPlugin('Dashboard') - if (dashboardPlugin) { - uppyService.removePlugin(dashboardPlugin) - } - for (const cloud of supportedClouds) { - const plugin = uppyService.getPlugin(cloud) - if (plugin) { - uppyService.removePlugin(plugin) - } - } - } - - uppyService.subscribe('addedForUpload', () => { - if (unref(activeModal)) { - removeModal(unref(activeModal).id) - } - }) - - uppyService.subscribe('uploadCompleted', () => { - removeUppyPlugins() - }) - - const getUppyPlugins = async () => { - // lazy loading to avoid loading these on page load - const Dashboard = (await import('@uppy/dashboard')).default - const OneDrive = (await import('@uppy/onedrive')).default - const GoogleDrive = (await import('@uppy/google-drive')).default - return { Dashboard, OneDrive, GoogleDrive } - } - const handler = async () => { - const { Dashboard, OneDrive, GoogleDrive } = await getUppyPlugins() - const renderDarkTheme = currentTheme.value.isDark - - dispatchModal({ - title: $gettext('Import files'), - hideConfirmButton: true, - onCancel: () => { - removeUppyPlugins() - } - }) - - await nextTick() - - uppyService.addPlugin(Dashboard, { - uppyService, - inline: true, - target: '.oc-modal-body', - disableLocalFiles: true, - disableStatusBar: true, - showSelectedFiles: false, - ...(renderDarkTheme && { theme: 'dark' }), - locale: { - strings: { - cancel: $gettext('Cancel'), - importFiles: $gettext('Import files from:'), - importFrom: $gettext('Import from %{name}') - } - } - }) - - if (supportedClouds.includes('OneDrive')) { - uppyService.addPlugin(OneDrive, { - target: Dashboard, - companionUrl - }) - } - - if (supportedClouds.includes('GoogleDrive')) { - uppyService.addPlugin(GoogleDrive, { - target: Dashboard, - companionUrl - }) - } - - if (supportedClouds.includes('WebdavPublicLink')) { - uppyService.addPlugin(WebdavPublicLink, { - target: Dashboard, - id: 'WebdavPublicLink', - companionUrl, - ...(webdavCloudType && { cloudType: webdavCloudType }) - }) - } - } - - return computed(() => [ - { - id: 'com.github.owncloud.web.import-file', - type: 'action', - extensionPointIds: ['app.files.upload-menu'], - action: { - name: 'import-files', - icon: 'upload-cloud', - handler, - label: () => $gettext('Import'), - isVisible: () => { - if (!companionUrl) { - return false - } - - if (authStore.publicLinkContextReady) { - return false - } - - return unref(canUpload) && supportedClouds.length - }, - isDisabled: () => !!Object.keys(uppyService.getCurrentUploads()).length, - disabledTooltip: () => $gettext('Please wait until all imports have finished'), - class: 'oc-files-actions-import' - } - } - ]) -} diff --git a/packages/web-app-importer/src/index.ts b/packages/web-app-importer/src/index.ts deleted file mode 100644 index f6f57d43279..00000000000 --- a/packages/web-app-importer/src/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -import translations from '../l10n/translations.json' -import { extensions } from './extensions' -import { useGettext } from 'vue3-gettext' -import { defineWebApplication } from '@ownclouders/web-pkg' - -export default defineWebApplication({ - setup(args) { - const { $gettext } = useGettext() - return { - appInfo: { - id: 'importer', - name: $gettext('Importer') - }, - extensions: extensions(args), - translations - } - } -}) diff --git a/packages/web-app-importer/tests/unit/extensions.spec.ts b/packages/web-app-importer/tests/unit/extensions.spec.ts deleted file mode 100644 index 55b26412b41..00000000000 --- a/packages/web-app-importer/tests/unit/extensions.spec.ts +++ /dev/null @@ -1,144 +0,0 @@ -import { defaultComponentMocks, getComposableWrapper, RouteLocation } from 'web-test-helpers' -import { unref } from 'vue' -import { Resource } from '@ownclouders/web-client' -import { mock, mockDeep } from 'vitest-mock-extended' -import { extensions } from '../../src/extensions' -import { ActionExtension, ApplicationSetupOptions, UppyService } from '@ownclouders/web-pkg' - -const getAction = (opts: ApplicationSetupOptions) => { - const importFileExtension = unref(extensions(opts))[0] as ActionExtension - return importFileExtension.action -} - -describe('useFileActionsImport', () => { - describe('isVisible', () => { - it('is false when no companion url is given', () => { - getWrapper({ - currentFolder: mock({ canUpload: () => true }), - setup: () => { - const action = getAction({ applicationConfig: {} }) - expect(action.isVisible()).toBeFalsy() - } - }) - }) - it('is false on public link pages', () => { - getWrapper({ - routeName: 'files-public-link', - setup: () => { - const action = getAction({ - applicationConfig: { - companionUrl: 'companionUrl' - } - }) - - expect(action.isVisible()).toBeFalsy() - } - }) - }) - it('is false when no write access is given', () => { - getWrapper({ - currentFolder: mock({ canUpload: () => false }), - setup: () => { - const action = getAction({ - applicationConfig: { - companionUrl: 'companionUrl' - } - }) - expect(action.isVisible()).toBeFalsy() - } - }) - }) - it('is false when no supported clouds are given', () => { - getWrapper({ - currentFolder: mock({ canUpload: () => true }), - setup: () => { - const action = getAction({ - applicationConfig: { - companionUrl: 'companionUrl', - supportedClouds: [] - } - }) - expect(action.isVisible()).toBeFalsy() - } - }) - }) - it('is true on generic space view when write access is given', () => { - getWrapper({ - currentFolder: mock({ canUpload: () => true }), - setup: () => { - const action = getAction({ - applicationConfig: { - companionUrl: 'companionUrl' - } - }) - expect(action.isVisible()).toBeTruthy() - } - }) - }) - }) - describe('isDisabled', () => { - it('is true when uploads are running', () => { - const uppyService = mockDeep() - uppyService.getCurrentUploads.mockReturnValue({ id: '1' }) - getWrapper({ - uppyService, - setup: () => { - const action = getAction({ applicationConfig: { companionUrl: 'companionUrl' } }) - expect(action.isDisabled()).toBeTruthy() - } - }) - }) - it('is false when no uploads are running', () => { - const uppyService = mockDeep() - uppyService.getCurrentUploads.mockReturnValue({}) - getWrapper({ - uppyService, - setup: () => { - const action = getAction({ applicationConfig: { companionUrl: 'companionUrl' } }) - expect(action.isDisabled()).toBeFalsy() - } - }) - }) - }) - - describe('handler', () => { - it.each([ - { supportedClouds: undefined, calls: 4 }, - { supportedClouds: ['OneDrive'], calls: 2 }, - { supportedClouds: ['GoogleDrive'], calls: 2 }, - { supportedClouds: ['WebdavPublicLink'], calls: 2 } - ])('should only add supported clouds as uppy plugin', ({ supportedClouds, calls }) => { - const uppyService = mockDeep() - getWrapper({ - uppyService, - setup: async () => { - const action = getAction({ - applicationConfig: { companionUrl: 'companionUrl', supportedClouds } - }) - await action.handler() - expect(uppyService.addPlugin).toHaveBeenCalledTimes(calls) - } - }) - }) - }) -}) - -function getWrapper({ - routeName = 'files-spaces-generic', - currentFolder = mock(), - uppyService = mockDeep(), - setup = () => undefined -} = {}) { - const mocks = { - ...defaultComponentMocks({ currentRoute: mock({ name: routeName }) }), - $uppyService: uppyService - } - - return { - wrapper: getComposableWrapper(setup, { - mocks, - provide: mocks, - pluginOptions: { piniaOptions: { resourcesStore: { currentFolder } } } - }) - } -}