├── .dockerignore ├── .env.sample ├── .eslintignore ├── .eslintrc.js ├── .gitattributes ├── .github └── workflows │ ├── a11y.yaml │ ├── catalog.yaml │ ├── clean.yaml │ ├── cross-repo.yaml │ ├── crowdin.yaml │ ├── ftest.yaml │ ├── lint.yaml │ ├── main.yaml │ ├── preview.yaml │ ├── promote.yaml │ ├── test.yaml │ ├── veracode-2025.yaml │ ├── veracode-3.0.x.yaml │ └── veracode-3.1.x.yaml ├── .gitignore ├── .npmrc ├── .prettierignore ├── CODEOWNERS ├── Dockerfile ├── Dockerfile.dev ├── Jenkinsfiles └── web-ui-pipeline.groovy ├── README.md ├── addons ├── README.md ├── amazon-s3-online-storage │ └── index.js ├── easyshare │ ├── document │ │ └── easysharefolder │ │ │ ├── nuxeo-easysharefolder-create-layout.html │ │ │ ├── nuxeo-easysharefolder-edit-layout.html │ │ │ ├── nuxeo-easysharefolder-metadata-layout.html │ │ │ └── nuxeo-easysharefolder-view-layout.html │ ├── easyshare.html │ ├── elements │ │ └── nuxeo-easyshare-share-link.js │ ├── images │ │ └── doctypes │ │ │ └── easysharefolder.svg │ └── index.js ├── nuxeo-csv │ ├── elements │ │ └── nuxeo-document-import-csv.js │ ├── images │ │ └── doctypes │ │ │ └── csv.png │ ├── index.js │ └── nuxeo-csv.html ├── nuxeo-drive │ ├── elements │ │ ├── nuxeo-authentication-tokens-management.js │ │ ├── nuxeo-drive-desktop-packages.js │ │ ├── nuxeo-drive-edit-button.js │ │ ├── nuxeo-drive-page.js │ │ ├── nuxeo-drive-sync-roots-management.js │ │ └── nuxeo-drive-sync-toggle-button.js │ ├── index.js │ └── nuxeo-drive.html ├── nuxeo-imap-connector │ ├── document │ │ ├── mailfolder │ │ │ ├── nuxeo-mailfolder-create-layout.html │ │ │ ├── nuxeo-mailfolder-edit-layout.html │ │ │ ├── nuxeo-mailfolder-list-item.html │ │ │ ├── nuxeo-mailfolder-metadata-layout.html │ │ │ └── nuxeo-mailfolder-view-layout.html │ │ └── mailmessage │ │ │ ├── nuxeo-mailmessage-edit-layout.html │ │ │ ├── nuxeo-mailmessage-metadata-layout.html │ │ │ └── nuxeo-mailmessage-view-layout.html │ ├── elements │ │ ├── nuxeo-mail-icons.js │ │ └── nuxeo-mail-sync-button.js │ ├── images │ │ └── doctypes │ │ │ └── mailfolder.svg │ ├── index.js │ └── nuxeo-imap-connector.html ├── nuxeo-liveconnect │ ├── elements │ │ ├── nuxeo-liveconnect-behavior.js │ │ ├── nuxeo-liveconnect-box-link.js │ │ ├── nuxeo-liveconnect-box-provider.js │ │ ├── nuxeo-liveconnect-google-drive-link.js │ │ └── nuxeo-liveconnect-google-drive-provider.js │ ├── images │ │ ├── box.png │ │ └── google_drive.png │ ├── index.js │ ├── nuxeo-liveconnect-box.html │ └── nuxeo-liveconnect-google-drive.html ├── nuxeo-platform-3d │ ├── README.md │ ├── controls │ │ └── OrbitControls.js │ ├── document │ │ └── threed │ │ │ ├── nuxeo-threed-create-layout.html │ │ │ ├── nuxeo-threed-edit-layout.html │ │ │ ├── nuxeo-threed-import-layout.html │ │ │ ├── nuxeo-threed-metadata-layout.html │ │ │ └── nuxeo-threed-view-layout.html │ ├── elements │ │ ├── nuxeo-3d-preview.js │ │ ├── nuxeo-3d-render-views.js │ │ ├── nuxeo-3d-transmission-formats.js │ │ └── nuxeo-3d-viewer.js │ ├── images │ │ └── doctypes │ │ │ └── threed.svg │ ├── index.js │ └── loaders │ │ ├── GLTFLoader.js │ │ └── gltf │ │ ├── glTF-parser.js │ │ ├── glTFAnimation.js │ │ ├── glTFLoader.js │ │ ├── glTFLoaderUtils.js │ │ └── glTFShaders.js ├── nuxeo-spreadsheet │ ├── app │ │ ├── .eslintrc │ │ ├── app.js │ │ ├── images │ │ │ └── ajax-loader.gif │ │ ├── index.html │ │ ├── lib │ │ │ ├── handsontable.patches.js │ │ │ └── select2-editor.js │ │ ├── nuxeo │ │ │ ├── rest │ │ │ │ ├── directory.js │ │ │ │ ├── query.js │ │ │ │ ├── request.js │ │ │ │ └── schemas.js │ │ │ ├── rpc │ │ │ │ ├── directory.js │ │ │ │ ├── operation.js │ │ │ │ └── query.js │ │ │ └── widget.js │ │ ├── styles │ │ │ └── styles.css │ │ ├── ui │ │ │ ├── column.js │ │ │ ├── editors │ │ │ │ ├── directory.js │ │ │ │ ├── document.js │ │ │ │ ├── image.js │ │ │ │ ├── select2.js │ │ │ │ └── user.js │ │ │ ├── i18n.js │ │ │ ├── log.js │ │ │ ├── spreadsheet.js │ │ │ └── widgets.js │ │ ├── utils.js │ │ └── vendor │ │ │ ├── jquery.handsontable.full.css │ │ │ └── jquery.handsontable.full.js │ ├── elements │ │ └── nuxeo-spreadsheet-button.js │ ├── index.js │ └── webpack.config.js ├── nuxeo-template-rendering │ ├── document │ │ ├── templatesource │ │ │ ├── nuxeo-templatesource-create-layout.html │ │ │ ├── nuxeo-templatesource-edit-layout.html │ │ │ ├── nuxeo-templatesource-import-layout.html │ │ │ ├── nuxeo-templatesource-metadata-layout.html │ │ │ └── nuxeo-templatesource-view-layout.html │ │ └── webtemplatesource │ │ │ ├── nuxeo-webtemplatesource-create-layout.html │ │ │ ├── nuxeo-webtemplatesource-edit-layout.html │ │ │ ├── nuxeo-webtemplatesource-import-layout.html │ │ │ ├── nuxeo-webtemplatesource-metadata-layout.html │ │ │ └── nuxeo-webtemplatesource-view-layout.html │ ├── elements │ │ ├── nuxeo-delete-template-button.js │ │ ├── nuxeo-render-template-button.js │ │ ├── nuxeo-template-param-editor.js │ │ └── nuxeo-template-rendering-page.js │ ├── images │ │ └── doctypes │ │ │ ├── templatesource.svg │ │ │ └── webtemplatesource.svg │ ├── index.js │ └── nuxeo-template-rendering.html └── nuxeo-wopi │ ├── elements │ └── nuxeo-wopi-link.js │ ├── images │ ├── excel.png │ ├── powerpoint.png │ ├── wopitest.png │ └── word.png │ ├── index.js │ └── nuxeo-wopi.html ├── browserconfig.xml ├── cache-config.json ├── charts └── preview │ ├── Chart.yaml │ ├── requirements.yaml │ ├── templates │ ├── _helpers.tpl │ ├── deployment.yaml │ ├── service.yaml │ └── webui-cluster-https-tls.yaml │ └── values.yaml ├── crowdin-conf.yml ├── docker-compose.yml ├── elements ├── bulk │ ├── nuxeo-bulk-default-layout.html │ ├── nuxeo-bulk-widget.js │ └── nuxeo-edit-documents-button.js ├── common-utils.js ├── diff │ ├── elements │ │ ├── nuxeo-blob-diff.html │ │ ├── nuxeo-date-diff.html │ │ ├── nuxeo-default-diff.html │ │ ├── nuxeo-directory-arr-diff.html │ │ ├── nuxeo-directory-diff.html │ │ ├── nuxeo-document-arr-diff.html │ │ ├── nuxeo-document-diff.html │ │ ├── nuxeo-user-arr-diff.html │ │ └── nuxeo-user-diff.html │ ├── imports.html │ ├── nuxeo-diff-behavior.js │ ├── nuxeo-diff-styles.js │ ├── nuxeo-diff.js │ ├── nuxeo-document-diff-button.js │ ├── nuxeo-object-diff.js │ └── nuxeo-versions-diff-button.js ├── directory │ ├── l10nvocabulary │ │ └── nuxeo-l10nvocabulary-edit-layout.html │ ├── l10nxvocabulary │ │ └── nuxeo-l10nxvocabulary-edit-layout.html │ ├── nuxeo-vocabulary-management.js │ ├── vocabulary │ │ └── nuxeo-vocabulary-edit-layout.html │ └── xvocabulary │ │ └── nuxeo-xvocabulary-edit-layout.html ├── document │ ├── audio │ │ ├── nuxeo-audio-create-layout.html │ │ ├── nuxeo-audio-edit-layout.html │ │ ├── nuxeo-audio-import-layout.html │ │ ├── nuxeo-audio-metadata-layout.html │ │ └── nuxeo-audio-view-layout.html │ ├── collection │ │ ├── nuxeo-collection-create-layout.html │ │ ├── nuxeo-collection-edit-layout.html │ │ ├── nuxeo-collection-metadata-layout.html │ │ └── nuxeo-collection-view-layout.html │ ├── collections │ │ ├── nuxeo-collections-create-layout.html │ │ ├── nuxeo-collections-edit-layout.html │ │ ├── nuxeo-collections-metadata-layout.html │ │ └── nuxeo-collections-view-layout.html │ ├── domain │ │ ├── nuxeo-domain-create-layout.html │ │ ├── nuxeo-domain-edit-layout.html │ │ ├── nuxeo-domain-metadata-layout.html │ │ └── nuxeo-domain-view-layout.html │ ├── favorites │ │ ├── nuxeo-favorites-edit-layout.html │ │ ├── nuxeo-favorites-metadata-layout.html │ │ └── nuxeo-favorites-view-layout.html │ ├── file │ │ ├── nuxeo-file-create-layout.html │ │ ├── nuxeo-file-edit-layout.html │ │ ├── nuxeo-file-import-layout.html │ │ ├── nuxeo-file-metadata-layout.html │ │ └── nuxeo-file-view-layout.html │ ├── folder │ │ ├── nuxeo-folder-create-layout.html │ │ ├── nuxeo-folder-edit-layout.html │ │ ├── nuxeo-folder-metadata-layout.html │ │ └── nuxeo-folder-view-layout.html │ ├── note │ │ ├── nuxeo-note-create-layout.html │ │ ├── nuxeo-note-edit-layout.html │ │ ├── nuxeo-note-import-layout.html │ │ ├── nuxeo-note-metadata-layout.html │ │ └── nuxeo-note-view-layout.html │ ├── nuxeo-collapsible-document-page.js │ ├── nuxeo-document-create.js │ ├── nuxeo-document-edit.js │ ├── nuxeo-document-form-layout.js │ ├── nuxeo-document-import.js │ ├── nuxeo-document-metadata.js │ ├── nuxeo-document-page.js │ ├── nuxeo-document-view.js │ ├── nuxeo-picture-document-page.js │ ├── nuxeo-picture-exif.js │ ├── nuxeo-picture-formats.js │ ├── nuxeo-picture-info.js │ ├── nuxeo-picture-iptc.js │ ├── orderedfolder │ │ ├── nuxeo-orderedfolder-create-layout.html │ │ ├── nuxeo-orderedfolder-edit-layout.html │ │ ├── nuxeo-orderedfolder-metadata-layout.html │ │ └── nuxeo-orderedfolder-view-layout.html │ ├── picture │ │ ├── nuxeo-picture-create-layout.html │ │ ├── nuxeo-picture-edit-layout.html │ │ ├── nuxeo-picture-import-layout.html │ │ ├── nuxeo-picture-metadata-layout.html │ │ └── nuxeo-picture-view-layout.html │ ├── root │ │ ├── nuxeo-root-edit-layout.html │ │ ├── nuxeo-root-metadata-layout.html │ │ └── nuxeo-root-view-layout.html │ ├── section │ │ ├── nuxeo-section-create-layout.html │ │ ├── nuxeo-section-edit-layout.html │ │ ├── nuxeo-section-metadata-layout.html │ │ └── nuxeo-section-view-layout.html │ ├── sectionroot │ │ ├── nuxeo-sectionroot-edit-layout.html │ │ ├── nuxeo-sectionroot-metadata-layout.html │ │ └── nuxeo-sectionroot-view-layout.html │ ├── template │ │ └── nuxeo-template-edit-layout.html │ ├── templateroot │ │ ├── nuxeo-templateroot-edit-layout.html │ │ ├── nuxeo-templateroot-metadata-layout.html │ │ └── nuxeo-templateroot-view-layout.html │ ├── userworkspacesroot │ │ ├── nuxeo-userworkspacesroot-edit-layout.html │ │ ├── nuxeo-userworkspacesroot-metadata-layout.html │ │ └── nuxeo-userworkspacesroot-view-layout.html │ ├── video │ │ ├── nuxeo-video-create-layout.html │ │ ├── nuxeo-video-edit-layout.html │ │ ├── nuxeo-video-import-layout.html │ │ ├── nuxeo-video-metadata-layout.html │ │ └── nuxeo-video-view-layout.html │ ├── workspace │ │ ├── nuxeo-workspace-create-layout.html │ │ ├── nuxeo-workspace-edit-layout.html │ │ ├── nuxeo-workspace-metadata-layout.html │ │ └── nuxeo-workspace-view-layout.html │ └── workspaceroot │ │ ├── nuxeo-workspaceroot-create-layout.html │ │ ├── nuxeo-workspaceroot-edit-layout.html │ │ ├── nuxeo-workspaceroot-metadata-layout.html │ │ └── nuxeo-workspaceroot-view-layout.html ├── elements.js ├── fetch-schemas.js ├── nuxeo-admin.html ├── nuxeo-admin │ ├── nuxeo-analytics.js │ ├── nuxeo-audit.js │ ├── nuxeo-chart-data-behavior.js │ ├── nuxeo-distribution-analytics.js │ ├── nuxeo-mime-types.js │ ├── nuxeo-repository-analytics.js │ ├── nuxeo-search-analytics.js │ ├── nuxeo-user-group-management-page.js │ └── nuxeo-workflow-analytics.js ├── nuxeo-app.js ├── nuxeo-app │ ├── nuxeo-expired-session.js │ ├── nuxeo-menu-icon.js │ ├── nuxeo-menu-item.js │ ├── nuxeo-offline-banner.js │ ├── nuxeo-page-item.js │ ├── nuxeo-page.js │ └── nuxeo-progress-indicator.js ├── nuxeo-audit │ └── nuxeo-audit-search.js ├── nuxeo-browser.html ├── nuxeo-browser │ ├── nuxeo-breadcrumb.js │ └── nuxeo-repositories.js ├── nuxeo-clipboard │ └── nuxeo-clipboard.js ├── nuxeo-cloud-services │ ├── nuxeo-cloud-consumers.js │ ├── nuxeo-cloud-providers.js │ ├── nuxeo-cloud-services.js │ ├── nuxeo-cloud-tokens.js │ ├── nuxeo-oauth2-consumed-tokens.js │ ├── nuxeo-oauth2-provided-tokens.js │ └── nuxeo-tokens-behavior.js ├── nuxeo-collections │ ├── nuxeo-collection-move-bottom-action.js │ ├── nuxeo-collection-move-down-action.js │ ├── nuxeo-collection-move-top-action.js │ ├── nuxeo-collection-move-up-action.js │ ├── nuxeo-collection-remove-action.js │ ├── nuxeo-collections.js │ ├── nuxeo-document-collections.js │ └── nuxeo-favorites.js ├── nuxeo-confirm-button │ └── nuxeo-confirm-button.js ├── nuxeo-csv-export │ └── nuxeo-csv-export-button.js ├── nuxeo-data-grid │ └── nuxeo-document-grid-thumbnail.js ├── nuxeo-data-list │ └── nuxeo-document-list-item.js ├── nuxeo-diff-page.html ├── nuxeo-document-actions │ ├── nuxeo-clipboard-toggle-button.js │ ├── nuxeo-document-edit-button.js │ ├── nuxeo-document-form-button.js │ └── nuxeo-replace-blob-button.js ├── nuxeo-document-activity │ └── nuxeo-document-activity.js ├── nuxeo-document-attachments │ └── nuxeo-document-attachments.js ├── nuxeo-document-blob │ └── nuxeo-document-blob.js ├── nuxeo-document-bulk-actions │ ├── nuxeo-add-to-collection-documents-button.js │ ├── nuxeo-clipboard-documents-button.js │ ├── nuxeo-delete-documents-button.js │ ├── nuxeo-download-documents-button.js │ └── nuxeo-untrash-documents-button.js ├── nuxeo-document-create-actions │ ├── nuxeo-document-create-shortcut.js │ └── nuxeo-document-create-shortcuts.js ├── nuxeo-document-create-button │ └── nuxeo-document-create-button.js ├── nuxeo-document-create-popup │ └── nuxeo-document-create-popup.js ├── nuxeo-document-creation-stats │ └── nuxeo-document-creation-stats.js ├── nuxeo-document-creation │ └── nuxeo-document-creation-behavior.js ├── nuxeo-document-export │ └── nuxeo-document-export.js ├── nuxeo-document-highlight │ └── nuxeo-document-highlights.js ├── nuxeo-document-history │ └── nuxeo-document-history.js ├── nuxeo-document-info-bar │ └── nuxeo-document-info-bar.js ├── nuxeo-document-info │ └── nuxeo-document-info.js ├── nuxeo-document-storage │ └── nuxeo-document-storage.js ├── nuxeo-document-tree │ └── nuxeo-document-tree.js ├── nuxeo-document-versions │ ├── nuxeo-document-create-version.js │ ├── nuxeo-document-versions-list.js │ └── nuxeo-document-versions.js ├── nuxeo-document-viewer │ └── nuxeo-document-viewer.js ├── nuxeo-dropzone │ └── nuxeo-dropzone.js ├── nuxeo-grid │ └── nuxeo-grid.js ├── nuxeo-home.html ├── nuxeo-keys │ └── nuxeo-keys.js ├── nuxeo-mobile │ └── nuxeo-mobile-banner.js ├── nuxeo-note-editor │ └── nuxeo-note-editor.js ├── nuxeo-profile.html ├── nuxeo-publication │ ├── nuxeo-document-publications.js │ ├── nuxeo-internal-publish.js │ ├── nuxeo-publication-info-bar.js │ ├── nuxeo-publish-button.js │ └── nuxeo-unpublish-button.js ├── nuxeo-recent-documents │ └── nuxeo-recent-documents.js ├── nuxeo-restore-version-button │ └── nuxeo-restore-version-button.js ├── nuxeo-results │ ├── nuxeo-default-results.js │ ├── nuxeo-document-content-behavior.js │ ├── nuxeo-document-content.js │ ├── nuxeo-document-trash-content.js │ └── nuxeo-results.js ├── nuxeo-sardine.js ├── nuxeo-search-page.js ├── nuxeo-selection │ └── nuxeo-selection-toolbar.js ├── nuxeo-suggester │ └── nuxeo-suggester.js ├── nuxeo-tasks.html ├── nuxeo-tasks │ ├── nuxeo-tasks-drawer.js │ └── nuxeo-tasks-list.js ├── nuxeo-themes.html ├── nuxeo-themes │ └── nuxeo-theme.js ├── nuxeo-user-authorized-apps.html ├── nuxeo-user-cloud-services.html ├── nuxeo-web-ui-bundle.html ├── nuxeo-workflow-graph │ └── nuxeo-workflow-graph.js ├── performance.js ├── routing.js ├── search │ ├── assets │ │ ├── nuxeo-assets-search-form.html │ │ └── nuxeo-assets-search-results.html │ ├── default │ │ ├── nuxeo-default-search-form.html │ │ └── nuxeo-default-search-results.html │ ├── document_picker │ │ ├── nuxeo-document_picker-search-form.html │ │ └── nuxeo-document_picker-search-results.html │ ├── expired │ │ ├── nuxeo-expired-search-form.html │ │ └── nuxeo-expired-search-results.html │ ├── nuxeo-saved-search-actions.js │ ├── nuxeo-search-form.js │ ├── nxql │ │ ├── nuxeo-nxql-search-form.html │ │ └── nuxeo-nxql-search-results.html │ └── trash │ │ ├── nuxeo-trash-search-form.html │ │ └── nuxeo-trash-search-results.html ├── select-all-helpers.js └── workflow │ ├── nuxeo-document-task-assignment-popup.js │ ├── nuxeo-document-task-review-result.js │ ├── nuxeo-document-task.js │ ├── paralleldocumentreview │ ├── nuxeo-task2169-layout.html │ ├── nuxeo-task2556-layout.html │ └── nuxeo-task328d-layout.html │ └── serialdocumentreview │ ├── nuxeo-task38e-layout.html │ ├── nuxeo-task542-layout.html │ └── nuxeo-task6d8-layout.html ├── favicon.ico ├── fonts ├── Inter-Bold.woff ├── Inter-Bold.woff2 ├── Inter-Regular.woff ├── Inter-Regular.woff2 ├── Inter-SemiBold.woff └── Inter-SemiBold.woff2 ├── ftest ├── .eslintrc ├── features │ ├── activity.feature │ ├── admin.feature │ ├── audit.feature │ ├── authorized_apps.feature │ ├── browser.feature │ ├── bulk_edit.feature │ ├── bulk_edit_custom_layouts.feature │ ├── clipboard.feature │ ├── cloud.feature │ ├── collections.feature │ ├── comments.feature │ ├── compare.feature │ ├── create_doc.feature │ ├── csv-import.feature │ ├── datatable_editing.feature │ ├── doc_suggestion.feature │ ├── edit-note.feature │ ├── expired_doc.feature │ ├── favorites.feature │ ├── grid.feature │ ├── group.feature │ ├── history.feature │ ├── home.feature │ ├── import_doc.feature │ ├── login-logout.feature │ ├── metadata.feature │ ├── ordered_folder.feature │ ├── permissions.feature │ ├── personal.feature │ ├── picture.feature │ ├── preview.feature │ ├── publication.feature │ ├── recents.feature │ ├── search.feature │ ├── spreadsheet.feature │ ├── tasks.feature │ ├── trash.feature │ ├── upload.feature │ ├── user.feature │ ├── user_cloud.feature │ ├── validation.feature │ ├── versions.feature │ ├── video.feature │ ├── vocabularies.feature │ └── workflows.feature ├── itests.xml ├── pom.xml ├── resources │ ├── csv-import-sample.csv │ ├── sample.mp3 │ ├── sample.mp4 │ ├── sample.odt │ ├── sample.pdf │ ├── sample.png │ └── sample.txt └── src │ ├── main │ └── resources │ │ └── META-INF │ │ └── MANIFEST.MF │ └── test │ ├── java │ └── org │ │ └── nuxeo │ │ └── sample │ │ └── functionaltests │ │ └── ITLoginLogoutTest.java │ └── resources │ └── log4j.xml ├── i18n ├── i18n.js ├── messages-ar.json ├── messages-cs.json ├── messages-de.json ├── messages-es-ES.json ├── messages-eu.json ├── messages-fr.json ├── messages-he.json ├── messages-id.json ├── messages-it.json ├── messages-ja.json ├── messages-nl.json ├── messages-pl.json ├── messages-pt-PT.json ├── messages-sv-SE.json ├── messages-zh-CN.json └── messages.json ├── images ├── README.md ├── blank.png ├── doctypes │ ├── README.md │ ├── audio.svg │ ├── collection.svg │ ├── collections.svg │ ├── document.svg │ ├── domain.svg │ ├── file.svg │ ├── folder.svg │ ├── note.svg │ ├── orderedfolder.svg │ ├── picture.svg │ ├── section.svg │ ├── video.svg │ └── workspace.svg ├── gift.png ├── nuxeo.png ├── sardine.png └── touch │ ├── README.md │ ├── android-chrome-192x192.png │ ├── android-chrome-384x384.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── icon-128x128.png │ ├── ms-icon-144x144.png │ ├── ms-touch-icon-144x144-precomposed.png │ ├── mstile-150x150.png │ └── safari-pinned-tab.svg ├── index.css ├── index.html ├── index.js ├── karma.conf.js ├── legacy.js ├── manifest.json ├── package.json ├── packages ├── nuxeo-designer-catalog │ ├── .gitignore │ ├── README.md │ ├── data │ │ └── applications │ │ │ └── nuxeo │ │ │ ├── 10.10 │ │ │ └── catalog-packages.json │ │ │ ├── 11.1 │ │ │ └── catalog-packages.json │ │ │ ├── 11.3 │ │ │ └── catalog-packages.json │ │ │ ├── 2023.0 │ │ │ └── catalog-packages.json │ │ │ ├── 8.10 │ │ │ └── catalog-packages.json │ │ │ └── 9.10 │ │ │ └── catalog-packages.json │ ├── gulpfile.js │ ├── package.json │ └── src │ │ ├── elements.js │ │ ├── hints │ │ ├── generators │ │ │ ├── html-hint-generator.js │ │ │ ├── polymer-behavior-hint-generator.js │ │ │ └── polymer-hint-generator.js │ │ └── index.js │ │ ├── index.js │ │ ├── packages.js │ │ └── utils │ │ ├── analyze.js │ │ ├── clean-tags.js │ │ ├── git-branch.js │ │ ├── object-from-streams.js │ │ ├── package-details.js │ │ ├── package-elements.js │ │ ├── parse-version.js │ │ ├── render-guide.js │ │ └── stream.js └── nuxeo-web-ui-ftest │ ├── .eslintrc │ ├── README.md │ ├── bin │ └── nuxeo-web-ui-ftest.js │ ├── features │ └── step_definitions │ │ ├── admin.js │ │ ├── audit.js │ │ ├── browser.js │ │ ├── bulk_edit.js │ │ ├── clipboard.js │ │ ├── cloud.js │ │ ├── collections.js │ │ ├── comments.js │ │ ├── compare.js │ │ ├── create_dialog.js │ │ ├── csv-import.js │ │ ├── doc_suggestion.js │ │ ├── document.js │ │ ├── favorites.js │ │ ├── group.js │ │ ├── history.js │ │ ├── home.js │ │ ├── import_dialog.js │ │ ├── login.js │ │ ├── permissions.js │ │ ├── personal.js │ │ ├── picture.js │ │ ├── preview.js │ │ ├── recents.js │ │ ├── search.js │ │ ├── spreadsheet.js │ │ ├── support │ │ ├── fixtures │ │ │ ├── _fixtures.js │ │ │ ├── blobs.js │ │ │ ├── collections.js │ │ │ ├── comments.js │ │ │ ├── consumers.js │ │ │ ├── documents.js │ │ │ ├── groups.js │ │ │ ├── layouts.js │ │ │ ├── localstorage.js │ │ │ ├── notes.js │ │ │ ├── oauth2.js │ │ │ ├── providers.js │ │ │ ├── searches.js │ │ │ ├── users.js │ │ │ ├── vocabularies.js │ │ │ └── workflows.js │ │ ├── screenshots.js │ │ ├── services │ │ │ ├── client.js │ │ │ ├── date.js │ │ │ ├── documentService.js │ │ │ └── field_registry.js │ │ └── ui_config.js │ │ ├── tasks.js │ │ ├── trash.js │ │ ├── ui.js │ │ ├── upload.js │ │ ├── user.js │ │ ├── user_settings.js │ │ ├── versions.js │ │ ├── video.js │ │ └── vocabularies.js │ ├── package.json │ ├── pages │ ├── base.js │ ├── helpers.js │ ├── login.js │ ├── spreadsheet.js │ ├── ui.js │ └── ui │ │ ├── activity_feed.js │ │ ├── admin │ │ ├── audit.js │ │ ├── cloudServices.js │ │ └── vocabulary.js │ │ ├── administration.js │ │ ├── browser.js │ │ ├── browser │ │ ├── add_to_collection_dialog.js │ │ ├── collapsible_document_page.js │ │ ├── document_attachments.js │ │ ├── document_comment.js │ │ ├── document_comment_thread.js │ │ ├── document_create.js │ │ ├── document_form_layout.js │ │ ├── document_layout.js │ │ ├── document_metadata.js │ │ ├── document_page.js │ │ ├── document_permissions.js │ │ ├── document_publications.js │ │ ├── document_task.js │ │ ├── document_versions.js │ │ ├── document_view.js │ │ └── publication_dialog.js │ │ ├── bulk_edit.js │ │ ├── clipboard.js │ │ ├── collections.js │ │ ├── create_dialog.js │ │ ├── drawer.js │ │ ├── edit_doc.js │ │ ├── favorites.js │ │ ├── group.js │ │ ├── history_table.js │ │ ├── home.js │ │ ├── note_editor.js │ │ ├── oauth2 │ │ ├── user_authorized_apps.js │ │ └── user_cloud_services.js │ │ ├── recents.js │ │ ├── results.js │ │ ├── search.js │ │ ├── selection.js │ │ ├── tasks.js │ │ └── user.js │ ├── scripts │ └── test.js │ ├── wdio-compat-plugin.js │ ├── wdio-shadow-plugin.js │ └── wdio.conf.js ├── plugin ├── a11y │ ├── .eslintrc │ ├── README.md │ ├── a11y.xml │ ├── getDriverVersion.js │ ├── package.json │ ├── pom.xml │ ├── test │ │ ├── a11y-reporter.js │ │ ├── axe-reporter.js │ │ ├── helpers │ │ │ └── login.js │ │ ├── imports.js │ │ └── specs │ │ │ ├── browser.js │ │ │ └── home.js │ └── wdio.conf.js ├── itests │ ├── addon │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── org │ │ │ │ └── nuxeo │ │ │ │ └── web │ │ │ │ └── ui │ │ │ │ └── itests │ │ │ │ └── listeners │ │ │ │ └── GlobalValidationListener.java │ │ │ └── resources │ │ │ ├── META-INF │ │ │ └── MANIFEST.MF │ │ │ ├── OSGI-INF │ │ │ ├── deployment-fragment.xml │ │ │ ├── extensions.xml │ │ │ └── webui-itests-webresources-contrib.xml │ │ │ ├── data │ │ │ ├── i18n │ │ │ │ └── messages.json │ │ │ └── schemas │ │ │ │ ├── bke.xsd │ │ │ │ ├── ftest1.xsd │ │ │ │ ├── ftest2.xsd │ │ │ │ ├── ftest3.xsd │ │ │ │ ├── test_search_pp.xsd │ │ │ │ └── validation.xsd │ │ │ └── web │ │ │ └── nuxeo.war │ │ │ └── ui │ │ │ ├── bulk │ │ │ └── nuxeo-bulk-bulkedit-layout.html │ │ │ ├── document │ │ │ ├── bulkedit │ │ │ │ ├── nuxeo-bulkedit-create-layout.html │ │ │ │ ├── nuxeo-bulkedit-edit-layout.html │ │ │ │ ├── nuxeo-bulkedit-metadata-layout.html │ │ │ │ └── nuxeo-bulkedit-view-layout.html │ │ │ ├── docsuggestion │ │ │ │ ├── nuxeo-docsuggestion-create-layout.html │ │ │ │ ├── nuxeo-docsuggestion-edit-layout.html │ │ │ │ ├── nuxeo-docsuggestion-metadata-layout.html │ │ │ │ └── nuxeo-docsuggestion-view-layout.html │ │ │ ├── gridfile │ │ │ │ ├── nuxeo-gridfile-create-layout.html │ │ │ │ ├── nuxeo-gridfile-edit-layout.html │ │ │ │ ├── nuxeo-gridfile-metadata-layout.html │ │ │ │ └── nuxeo-gridfile-view-layout.html │ │ │ ├── legacyfile │ │ │ │ ├── nuxeo-legacyfile-create-layout.html │ │ │ │ ├── nuxeo-legacyfile-edit-layout.html │ │ │ │ ├── nuxeo-legacyfile-metadata-layout.html │ │ │ │ └── nuxeo-legacyfile-view-layout.html │ │ │ ├── multicomplex │ │ │ │ ├── nuxeo-multicomplex-create-layout.html │ │ │ │ ├── nuxeo-multicomplex-edit-layout.html │ │ │ │ ├── nuxeo-multicomplex-metadata-layout.html │ │ │ │ └── nuxeo-multicomplex-view-layout.html │ │ │ ├── multistring │ │ │ │ ├── nuxeo-multistring-create-layout.html │ │ │ │ ├── nuxeo-multistring-edit-layout.html │ │ │ │ ├── nuxeo-multistring-metadata-layout.html │ │ │ │ └── nuxeo-multistring-view-layout.html │ │ │ └── validation │ │ │ │ ├── nuxeo-validation-create-layout.html │ │ │ │ ├── nuxeo-validation-edit-layout.html │ │ │ │ ├── nuxeo-validation-metadata-layout.html │ │ │ │ └── nuxeo-validation-view-layout.html │ │ │ ├── images │ │ │ └── doctypes │ │ │ │ ├── bulkedit.svg │ │ │ │ ├── docsuggestion.svg │ │ │ │ ├── gridfile.svg │ │ │ │ ├── legacyfile.svg │ │ │ │ ├── multicomplex.svg │ │ │ │ ├── multistring.svg │ │ │ │ └── validation.svg │ │ │ ├── nuxeo-document-sidebar.html │ │ │ ├── nuxeo-gridfile-document-page.html │ │ │ ├── nuxeo-itests.html │ │ │ └── search │ │ │ ├── manual-default │ │ │ ├── nuxeo-manual-default-search-form.html │ │ │ └── nuxeo-manual-default-search-results.html │ │ │ └── test_search │ │ │ ├── nuxeo-test_search-search-form.html │ │ │ └── nuxeo-test_search-search-results.html │ └── marketplace │ │ ├── pom.xml │ │ └── src │ │ └── main │ │ ├── assemble │ │ └── assembly.xml │ │ └── resources │ │ ├── install.xml │ │ └── package.xml ├── metrics │ ├── index.js │ ├── lib │ │ └── sauce.js │ ├── metrics.xml │ ├── package.json │ ├── pom.xml │ ├── report │ │ └── metrics.html │ └── wdio.conf.js └── web-ui │ ├── addon │ ├── build.xml │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── org │ │ │ │ └── nuxeo │ │ │ │ └── web │ │ │ │ └── ui │ │ │ │ └── url │ │ │ │ └── codec │ │ │ │ └── WebNotificationDocumentIdCodec.java │ │ └── resources │ │ │ ├── META-INF │ │ │ └── MANIFEST.MF │ │ │ ├── OSGI-INF │ │ │ ├── actions-contrib.xml │ │ │ ├── auth-config.xml │ │ │ ├── browser-cache-contrib.xml │ │ │ ├── deployment-fragment.xml │ │ │ ├── login-startup-page-web-contrib.xml │ │ │ ├── url-codecs-web-contrib.xml │ │ │ └── web-ui-properties.xml │ │ │ └── web │ │ │ └── nuxeo.war │ │ │ └── ui │ │ │ ├── config.jsp │ │ │ └── index.jsp │ │ └── test │ │ ├── java │ │ └── org │ │ │ └── nuxeo │ │ │ └── web │ │ │ └── ui │ │ │ └── url │ │ │ └── codec │ │ │ └── TestWebNotificationCodec.java │ │ └── resources │ │ └── log4j2-test.xml │ └── marketplace │ ├── pom.xml │ └── src │ └── main │ ├── assemble │ └── assembly.xml │ └── resources │ ├── install.xml │ └── package.xml ├── polymer.json ├── pom.xml ├── prettier.config.js ├── robots.txt ├── scripts ├── merge-messages.js └── test-runner.js ├── server ├── Dockerfile ├── nginx.conf └── nginx.proxy.conf ├── sw.js ├── test ├── layouts │ └── bulk │ │ ├── nuxeo-bulk-custom-layout.html │ │ └── nuxeo-bulk-default-layout.html ├── nuxeo-audit-search.test.js ├── nuxeo-breadcrumb.test.js ├── nuxeo-document-activity.test.js ├── nuxeo-document-attachments.test.js ├── nuxeo-document-blob.test.js ├── nuxeo-document-tree.test.js ├── nuxeo-dropzone.test.js ├── nuxeo-edit-documents-button.test.js ├── nuxeo-grid.test.js ├── nuxeo-picture-formats.test.js └── nuxeo-replace-blob-button.test.js ├── themes ├── base.js ├── dark │ ├── README.md │ ├── logo.png │ ├── preview.jpg │ └── theme.html ├── default │ ├── README.md │ ├── logo.png │ ├── preview.jpg │ └── theme.html ├── kawaii │ ├── README.md │ ├── background.png │ ├── logo.png │ ├── preview.jpg │ └── theme.html ├── light │ ├── README.md │ ├── logo.png │ ├── preview.jpg │ └── theme.html └── loader.js ├── wct.conf.js └── webpack.config.js /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | target 3 | 4 | -------------------------------------------------------------------------------- /.env.sample: -------------------------------------------------------------------------------- 1 | NUXEO_WEB_UI_VERSION=3.1.20-SNAPSHOT 2 | NUXEO_VERSION=master 3 | NUXEO_PACKAGES=nuxeo-drive nuxeo-liveconnect nuxeo-template-rendering 4 | NUXEO_DEV_MODE=true 5 | NUXEO_CLID= 6 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | metrics/ 2 | node_modules/ 3 | coverage/ 4 | target/ 5 | dist/ 6 | .tmp/ 7 | index.html 8 | dist/ 9 | vendor/ 10 | addons/nuxeo-platform-3d/controls/ 11 | addons/nuxeo-platform-3d/loaders/ 12 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto -------------------------------------------------------------------------------- /.github/workflows/lint.yaml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - maintenance-3.1.x 7 | workflow_call: 8 | inputs: 9 | branch: 10 | description: 'The current branch' 11 | default: maintenance-3.1.x 12 | type: string 13 | required: false 14 | secrets: 15 | NPM_PACKAGES_TOKEN: 16 | description: 'NPM_PACKAGES_TOKEN' 17 | required: true 18 | 19 | env: 20 | BRANCH_NAME: ${{ github.head_ref || inputs.branch || 'maintenance-3.1.x' }} 21 | 22 | jobs: 23 | lint: 24 | runs-on: ubuntu-latest 25 | steps: 26 | - uses: actions/checkout@v2 27 | with: 28 | ref: ${{ env.BRANCH_NAME }} 29 | 30 | - uses: actions/setup-node@v3 31 | with: 32 | registry-url: 'https://packages.nuxeo.com/repository/npm-public/' 33 | node-version: 18 34 | scope: '@nuxeo' 35 | 36 | - name: Install 37 | env: 38 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 39 | run: npm install 40 | 41 | - name: Lint 42 | run: npm run lint -------------------------------------------------------------------------------- /.github/workflows/test.yaml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - maintenance-3.1.x 7 | workflow_call: 8 | inputs: 9 | branch: 10 | description: 'The current branch' 11 | default: maintenance-3.1.x 12 | type: string 13 | required: false 14 | secrets: 15 | NPM_PACKAGES_TOKEN: 16 | description: 'NPM_PACKAGES_TOKEN' 17 | required: true 18 | SAUCE_ACCESS_KEY: 19 | description: 'SAUCE_ACCESS_KEY' 20 | required: true 21 | 22 | env: 23 | BRANCH_NAME: ${{ github.head_ref || inputs.branch || 'maintenance-3.1.x' }} 24 | 25 | jobs: 26 | unit-test: 27 | runs-on: [ self-hosted, master ] 28 | steps: 29 | - uses: actions/checkout@v2 30 | with: 31 | ref: ${{ env.BRANCH_NAME }} 32 | 33 | - uses: actions/setup-node@v3 34 | with: 35 | registry-url: 'https://packages.nuxeo.com/repository/npm-public/' 36 | scope: '@nuxeo' 37 | node-version: 18 38 | 39 | - name: Install 40 | env: 41 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 42 | run: | 43 | npm cache clean --force 44 | npm install 45 | 46 | - name: Unit tests 47 | env: 48 | SAUCE_USERNAME: nuxeo-web-ui 49 | SAUCE_ACCESS_KEY: ${{ secrets.SAUCE_ACCESS_KEY }} 50 | run: npm run test -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | target 4 | .env 5 | .classpath 6 | .tmp 7 | .project 8 | npm-debug.log 9 | .settings/ 10 | .DS_Store 11 | .screenshots/ 12 | *.iml 13 | .idea 14 | .java-version 15 | .vscode 16 | coverage -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | @nuxeo:registry=https://packages.nuxeo.com/repository/npm-public/ 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | metrics/ 2 | node_modules/ 3 | coverage/ 4 | target/ 5 | dist/ 6 | .tmp/ 7 | dist/ 8 | vendor/ 9 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @nuxeo/ui 2 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | ARG SERVER_IMAGE=nuxeo-web-ui/server 2 | FROM $SERVER_IMAGE 3 | 4 | COPY dist/ ui/ -------------------------------------------------------------------------------- /Dockerfile.dev: -------------------------------------------------------------------------------- 1 | FROM node:10 2 | 3 | RUN npm config set registry=https://packages.nuxeo.com/repository/npm-all/ 4 | 5 | WORKDIR /ui 6 | 7 | # Copy packages 8 | COPY packages ./packages 9 | 10 | # Copy package.json and install dependencies 11 | COPY package*.json ./ 12 | 13 | RUN npm install 14 | 15 | # Copy application source code 16 | COPY . . 17 | 18 | EXPOSE 5000 19 | 20 | CMD ["npm", "start"] 21 | -------------------------------------------------------------------------------- /addons/README.md: -------------------------------------------------------------------------------- 1 | Addons Web UI extension are located in this directory 2 | -------------------------------------------------------------------------------- /addons/easyshare/easyshare.html: -------------------------------------------------------------------------------- 1 | 18 | 19 | 22 | 23 | -------------------------------------------------------------------------------- /addons/easyshare/images/doctypes/easysharefolder.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /addons/easyshare/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | @license 3 | ©2023 Hyland Software, Inc. and its affiliates. All rights reserved. 4 | All Hyland product names are registered or unregistered trademarks of Hyland Software, Inc. or its affiliates. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | import './elements/nuxeo-easyshare-share-link.js'; 19 | 20 | import html from './easyshare.html'; 21 | 22 | const tmpl = document.createElement('template'); 23 | tmpl.innerHTML = html; 24 | document.head.appendChild(tmpl.content); 25 | -------------------------------------------------------------------------------- /addons/nuxeo-csv/images/doctypes/csv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/addons/nuxeo-csv/images/doctypes/csv.png -------------------------------------------------------------------------------- /addons/nuxeo-csv/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | @license 3 | ©2023 Hyland Software, Inc. and its affiliates. All rights reserved. 4 | All Hyland product names are registered or unregistered trademarks of Hyland Software, Inc. or its affiliates. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | import './elements/nuxeo-document-import-csv.js'; 19 | 20 | import html from './nuxeo-csv.html'; 21 | 22 | const tmpl = document.createElement('template'); 23 | tmpl.innerHTML = html; 24 | document.head.appendChild(tmpl.content); 25 | -------------------------------------------------------------------------------- /addons/nuxeo-csv/nuxeo-csv.html: -------------------------------------------------------------------------------- 1 | 18 | 19 | 22 | 23 | 24 | 25 | 34 | 35 | -------------------------------------------------------------------------------- /addons/nuxeo-drive/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | @license 3 | ©2023 Hyland Software, Inc. and its affiliates. All rights reserved. 4 | All Hyland product names are registered or unregistered trademarks of Hyland Software, Inc. or its affiliates. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | import './elements/nuxeo-drive-sync-toggle-button.js'; 19 | import './elements/nuxeo-drive-edit-button.js'; 20 | import './elements/nuxeo-drive-page.js'; 21 | 22 | import html from './nuxeo-drive.html'; 23 | 24 | const tmpl = document.createElement('template'); 25 | tmpl.innerHTML = html; 26 | document.head.appendChild(tmpl.content); 27 | -------------------------------------------------------------------------------- /addons/nuxeo-imap-connector/document/mailmessage/nuxeo-mailmessage-edit-layout.html: -------------------------------------------------------------------------------- 1 | 17 | 22 | 23 | 26 | 31 | 32 | -------------------------------------------------------------------------------- /addons/nuxeo-imap-connector/images/doctypes/mailfolder.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /addons/nuxeo-imap-connector/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | @license 3 | ©2023 Hyland Software, Inc. and its affiliates. All rights reserved. 4 | All Hyland product names are registered or unregistered trademarks of Hyland Software, Inc. or its affiliates. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | import './elements/nuxeo-mail-sync-button.js'; 19 | 20 | import html from './nuxeo-imap-connector.html'; 21 | 22 | const tmpl = document.createElement('template'); 23 | tmpl.innerHTML = html; 24 | document.head.appendChild(tmpl.content); 25 | 26 | // push MailFolder to list of document types that are not available for import 27 | window.nuxeo.importBlacklist.push('MailFolder'); 28 | -------------------------------------------------------------------------------- /addons/nuxeo-imap-connector/nuxeo-imap-connector.html: -------------------------------------------------------------------------------- 1 | 17 | 18 | 25 | 26 | -------------------------------------------------------------------------------- /addons/nuxeo-liveconnect/images/box.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/addons/nuxeo-liveconnect/images/box.png -------------------------------------------------------------------------------- /addons/nuxeo-liveconnect/images/google_drive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/addons/nuxeo-liveconnect/images/google_drive.png -------------------------------------------------------------------------------- /addons/nuxeo-liveconnect/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | @license 3 | ©2023 Hyland Software, Inc. and its affiliates. All rights reserved. 4 | All Hyland product names are registered or unregistered trademarks of Hyland Software, Inc. or its affiliates. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | import './elements/nuxeo-liveconnect-box-link.js'; 19 | import './elements/nuxeo-liveconnect-google-drive-link.js'; 20 | import { LiveConnectBehavior } from './elements/nuxeo-liveconnect-behavior.js'; 21 | 22 | import boxHtml from './nuxeo-liveconnect-box.html'; 23 | import driveHtml from './nuxeo-liveconnect-google-drive.html'; 24 | 25 | const tmpl = document.createElement('template'); 26 | tmpl.innerHTML = [boxHtml, driveHtml].join(''); 27 | document.head.appendChild(tmpl.content); 28 | 29 | Nuxeo.LiveConnectBehavior = LiveConnectBehavior; 30 | -------------------------------------------------------------------------------- /addons/nuxeo-liveconnect/nuxeo-liveconnect-box.html: -------------------------------------------------------------------------------- 1 | 19 | 20 | 23 | 24 | -------------------------------------------------------------------------------- /addons/nuxeo-liveconnect/nuxeo-liveconnect-google-drive.html: -------------------------------------------------------------------------------- 1 | 19 | 20 | 23 | 24 | -------------------------------------------------------------------------------- /addons/nuxeo-platform-3d/README.md: -------------------------------------------------------------------------------- 1 | Following the resolution of [WEBUI-237](https://jira.nuxeo.com/browse/WEBUI-237): 2 | - The `threejs` dependency was updated from `v0.81.0` to `v0.125.0`. 3 | - The `loaders` directory was added with the (`v0.81.0`) loader utilities necessary to maintain the load of GLTF v1.0 models. These are now imported via ESM. 4 | - The `controls` directory was added with the (`v0.81.0`) control utilities so that they can now be imported via ESM. 5 | -------------------------------------------------------------------------------- /addons/nuxeo-platform-3d/document/threed/nuxeo-threed-create-layout.html: -------------------------------------------------------------------------------- 1 | 20 | 21 | 22 | 23 | 28 | 29 | 32 | 40 | 41 | -------------------------------------------------------------------------------- /addons/nuxeo-platform-3d/document/threed/nuxeo-threed-import-layout.html: -------------------------------------------------------------------------------- 1 | 20 | 21 | 22 | 23 | 28 | 29 | 32 | 40 | 41 | -------------------------------------------------------------------------------- /addons/nuxeo-platform-3d/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | @license 3 | ©2023 Hyland Software, Inc. and its affiliates. All rights reserved. 4 | All Hyland product names are registered or unregistered trademarks of Hyland Software, Inc. or its affiliates. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | import './controls/OrbitControls.js'; 19 | import './elements/nuxeo-3d-viewer.js'; 20 | import './elements/nuxeo-3d-preview.js'; 21 | import './elements/nuxeo-3d-render-views.js'; 22 | import './elements/nuxeo-3d-transmission-formats.js'; 23 | import './loaders/gltf/glTFLoader.js'; 24 | import './loaders/gltf/glTFAnimation.js'; 25 | import './loaders/gltf/glTFLoaderUtils.js'; 26 | import './loaders/gltf/glTFShaders.js'; 27 | import './loaders/GLTFLoader.js'; 28 | -------------------------------------------------------------------------------- /addons/nuxeo-spreadsheet/app/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "default-case": 0, 4 | "guard-for-in": 0, 5 | "no-case-declarations": 0, 6 | "no-continue": 0, 7 | "no-fallthrough": 0, 8 | "no-restricted-syntax": 0, 9 | "no-return-assign": 0, 10 | "prefer-const": 0, 11 | "prefer-destructuring": 0, 12 | "prefer-rest-params": 0, 13 | "vars-on-top": 0 14 | }, 15 | "globals": { 16 | "$": true, 17 | "Handsontable": true, 18 | "WalkontableCellRange": true 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /addons/nuxeo-spreadsheet/app/images/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/addons/nuxeo-spreadsheet/app/images/ajax-loader.gif -------------------------------------------------------------------------------- /addons/nuxeo-spreadsheet/app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Nuxeo Spreadsheet 4 | 5 | 6 | 9 | 10 |
11 | 12 |
13 | 14 |
15 | 16 |
17 | 18 | 19 |
20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /addons/nuxeo-spreadsheet/app/nuxeo/rest/directory.js: -------------------------------------------------------------------------------- 1 | /* 2 | *©2023 Hyland Software, Inc. and its affiliates. All rights reserved. 3 | All Hyland product names are registered or unregistered trademarks of Hyland Software, Inc. or its affiliates. 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the GNU Lesser General Public License 7 | * (LGPL) version 2.1 which accompanies this distribution, and is available at 8 | * http://www.gnu.org/licenses/lgpl-2.1.html 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * Contributors: 16 | * Nelson Silva 17 | */ 18 | import { Request } from './request'; 19 | 20 | const PATH = '/directory'; 21 | 22 | /** 23 | * REST Directory 24 | */ 25 | class Directory extends Request { 26 | constructor(connection, name) { 27 | super(connection, `${PATH}/${name}`); 28 | } 29 | 30 | entries() { 31 | return this.execute().then((result) => result.entries); 32 | } 33 | } 34 | 35 | export { Directory }; 36 | -------------------------------------------------------------------------------- /addons/nuxeo-spreadsheet/app/ui/editors/image.js: -------------------------------------------------------------------------------- 1 | /* 2 | *©2023 Hyland Software, Inc. and its affiliates. All rights reserved. 3 | All Hyland product names are registered or unregistered trademarks of Hyland Software, Inc. or its affiliates. 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the GNU Lesser General Public License 7 | * (LGPL) version 2.1 which accompanies this distribution, and is available at 8 | * http://www.gnu.org/licenses/lgpl-2.1.html 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * Contributors: 16 | * mobrebski 17 | * Jackie Aldama 18 | */ 19 | 20 | const ImageRenderer = (instance, td, row, col, prop, value, cellProperties) => { 21 | if (value && value.data) { 22 | const img = document.createElement('img'); 23 | img.src = value.data; 24 | if (cellProperties.width) { 25 | img.setAttribute('width', cellProperties.height); 26 | } 27 | if (cellProperties.height) { 28 | img.setAttribute('height', cellProperties.height); 29 | } 30 | Handsontable.Dom.empty(td); 31 | td.appendChild(img); 32 | } 33 | return td; 34 | }; 35 | 36 | export { ImageRenderer }; 37 | -------------------------------------------------------------------------------- /addons/nuxeo-spreadsheet/app/ui/i18n.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ©2023 Hyland Software, Inc. and its affiliates. All rights reserved. 3 | All Hyland product names are registered or unregistered trademarks of Hyland Software, Inc. or its affiliates. 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the GNU Lesser General Public License 7 | * (LGPL) version 2.1 which accompanies this distribution, and is available at 8 | * http://www.gnu.org/licenses/lgpl-2.1.html 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | */ 15 | 16 | export function i18n(key) { 17 | // XXX: cheating a bit and reusing top level i18n 18 | const nuxeo = (window.parent || window).nuxeo; 19 | return (nuxeo && nuxeo.I18n && nuxeo.I18n.translate && nuxeo.I18n.translate(`spreadsheet.${key}`)) || key; 20 | } 21 | -------------------------------------------------------------------------------- /addons/nuxeo-spreadsheet/app/ui/log.js: -------------------------------------------------------------------------------- 1 | /* 2 | *©2023 Hyland Software, Inc. and its affiliates. All rights reserved. 3 | All Hyland product names are registered or unregistered trademarks of Hyland Software, Inc. or its affiliates. 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the GNU Lesser General Public License 7 | * (LGPL) version 2.1 which accompanies this distribution, and is available at 8 | * http://www.gnu.org/licenses/lgpl-2.1.html 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * Contributors: 16 | * Nelson Silva 17 | */ 18 | 19 | class Log { 20 | constructor(el) { 21 | this.el = el; 22 | this._default = ''; 23 | } 24 | 25 | info(msg) { 26 | this.el.text(msg); 27 | } 28 | 29 | error(msg) { 30 | this.el.text(msg); 31 | } 32 | 33 | default(msg) { 34 | if (msg !== undefined) { 35 | this._default = msg; 36 | } 37 | this.el.text(this._default); 38 | } 39 | } 40 | 41 | export { Log }; 42 | -------------------------------------------------------------------------------- /addons/nuxeo-spreadsheet/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | @license 3 | ©2023 Hyland Software, Inc. and its affiliates. All rights reserved. 4 | All Hyland product names are registered or unregistered trademarks of Hyland Software, Inc. or its affiliates. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | import './elements/nuxeo-spreadsheet-button.js'; 19 | -------------------------------------------------------------------------------- /addons/nuxeo-spreadsheet/webpack.config.js: -------------------------------------------------------------------------------- 1 | const { resolve } = require('path'); 2 | const { ProvidePlugin } = require('webpack'); 3 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 4 | 5 | module.exports = { 6 | entry: { 7 | 'spreadsheet.app': resolve(__dirname, 'app', 'app.js'), 8 | }, 9 | plugins: [ 10 | new ProvidePlugin({ 11 | $: 'jquery', 12 | }), 13 | new HtmlWebpackPlugin({ 14 | title: 'Nuxeo Spreadsheet', 15 | filename: 'spreadsheet.popup.html', 16 | chunks: ['spreadsheet.app'], 17 | template: resolve(__dirname, 'app', 'index.html'), 18 | }), 19 | ], 20 | }; 21 | -------------------------------------------------------------------------------- /addons/nuxeo-template-rendering/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | @license 3 | ©2023 Hyland Software, Inc. and its affiliates. All rights reserved. 4 | All Hyland product names are registered or unregistered trademarks of Hyland Software, Inc. or its affiliates. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | import './elements/nuxeo-render-template-button.js'; 19 | import './elements/nuxeo-delete-template-button.js'; 20 | import './elements/nuxeo-template-rendering-page.js'; 21 | 22 | import html from './nuxeo-template-rendering.html'; 23 | 24 | const tmpl = document.createElement('template'); 25 | tmpl.innerHTML = html; 26 | document.head.appendChild(tmpl.content); 27 | -------------------------------------------------------------------------------- /addons/nuxeo-wopi/images/excel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/addons/nuxeo-wopi/images/excel.png -------------------------------------------------------------------------------- /addons/nuxeo-wopi/images/powerpoint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/addons/nuxeo-wopi/images/powerpoint.png -------------------------------------------------------------------------------- /addons/nuxeo-wopi/images/wopitest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/addons/nuxeo-wopi/images/wopitest.png -------------------------------------------------------------------------------- /addons/nuxeo-wopi/images/word.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/addons/nuxeo-wopi/images/word.png -------------------------------------------------------------------------------- /addons/nuxeo-wopi/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | @license 3 | ©2023 Hyland Software, Inc. and its affiliates. All rights reserved. 4 | All Hyland product names are registered or unregistered trademarks of Hyland Software, Inc. or its affiliates. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | import './elements/nuxeo-wopi-link.js'; 19 | 20 | import html from './nuxeo-wopi.html'; 21 | 22 | const Nuxeo = window.Nuxeo || {}; 23 | Nuxeo.UI = Nuxeo.UI || {}; 24 | Nuxeo.UI.config = Nuxeo.UI.config || {}; 25 | Nuxeo.UI.config.enrichers = Nuxeo.UI.config.enrichers || {}; 26 | Nuxeo.UI.config.enrichers.blob = Nuxeo.UI.config.enrichers.blob || []; 27 | Nuxeo.UI.config.enrichers.blob.push('wopi'); 28 | const tmpl = document.createElement('template'); 29 | tmpl.innerHTML = html; 30 | document.head.appendChild(tmpl.content); 31 | -------------------------------------------------------------------------------- /addons/nuxeo-wopi/nuxeo-wopi.html: -------------------------------------------------------------------------------- 1 | 18 | 19 | 22 | 23 | -------------------------------------------------------------------------------- /browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | #00aba9 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /cache-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "README": "This is the cache config for the dev server. The service worker cache is disabled, and it is recommended that you leave this as-is. In the dist environment, this file will be auto-generated based on the contents of your dist/ directory.", 3 | "disabled": true 4 | } 5 | -------------------------------------------------------------------------------- /charts/preview/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | description: A Helm chart for Web UI preview 3 | icon: https://media.licdn.com/dms/image/C4D0BAQFPXiXFrp4LBA/company-logo_200_200/0?e=2159024400&v=beta&t=RW9EU0QUciUVuPSpLySd9FtJ2yG-O37_hAAvc32f6ro 4 | name: preview 5 | version: 3.1.20-SNAPSHOT 6 | -------------------------------------------------------------------------------- /charts/preview/requirements.yaml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - alias: expose 3 | name: exposecontroller 4 | repository: https://jenkins-x-charts.github.io/v2/ 5 | version: 2.3.111 6 | - alias: cleanup 7 | name: exposecontroller 8 | repository: https://jenkins-x-charts.github.io/v2/ 9 | version: 2.3.111 10 | - name: nuxeo 11 | version: ~1.2.1 12 | repository: https://chartmuseum.platform.dev.nuxeo.com 13 | alias: nuxeo 14 | -------------------------------------------------------------------------------- /charts/preview/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "nuxeo.webui.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | */}} 13 | {{- define "nuxeo.webui.fullname" -}} 14 | {{- if .Values.fullnameOverride -}} 15 | {{- printf .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} 16 | {{- else -}} 17 | {{- $name := default .Chart.Name .Values.nameOverride -}} 18 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 19 | {{- end -}} 20 | {{- end -}} 21 | -------------------------------------------------------------------------------- /charts/preview/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ template "nuxeo.webui.fullname" . }} 5 | labels: 6 | chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}" 7 | spec: 8 | replicas: {{ .Values.nuxeo.webui.replicaCount }} 9 | selector: 10 | matchLabels: 11 | app: {{ template "nuxeo.webui.fullname" . }} 12 | template: 13 | metadata: 14 | labels: 15 | app: {{ template "nuxeo.webui.fullname" . }} 16 | {{- if .Values.podAnnotations }} 17 | annotations: 18 | {{ toYaml .Values.podAnnotations | indent 8 }} 19 | {{- end }} 20 | spec: 21 | containers: 22 | - name: {{ .Chart.Name }} 23 | image: "{{ .Values.nuxeo.webui.image.repository }}:{{ .Values.nuxeo.webui.image.tag }}" 24 | imagePullPolicy: {{ .Values.nuxeo.webui.image.pullPolicy }} 25 | ports: 26 | - containerPort: 80 27 | -------------------------------------------------------------------------------- /charts/preview/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ template "nuxeo.webui.fullname" . }} 5 | labels: 6 | chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}" 7 | {{- if .Values.nuxeo.webui.service.annotations }} 8 | annotations: 9 | {{ toYaml .Values.nuxeo.webui.service.annotations | indent 4 }} 10 | {{- end }} 11 | spec: 12 | type: ClusterIP 13 | ports: 14 | - port: {{ .Values.nuxeo.webui.service.port }} 15 | targetPort: 80 16 | protocol: TCP 17 | name: http 18 | selector: 19 | app: {{ template "nuxeo.webui.fullname" . }} 20 | -------------------------------------------------------------------------------- /charts/preview/templates/webui-cluster-https-tls.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: webui-cluster-https-tls 5 | annotations: 6 | replicator.v1.mittwald.de/replicate-from: webui/webui-cluster-https-tls 7 | data: {} 8 | -------------------------------------------------------------------------------- /charts/preview/values.yaml: -------------------------------------------------------------------------------- 1 | expose: 2 | Annotations: 3 | helm.sh/hook: post-install,post-upgrade 4 | helm.sh/hook-delete-policy: hook-succeeded 5 | config: 6 | domain: webui.dev.nuxeo.com 7 | exposer: Ingress 8 | http: true 9 | tlsacme: true 10 | tlsSecretName: webui-cluster-https-tls 11 | urltemplate: '"{{.Service}}-{{.Namespace}}.{{.Domain}}"' 12 | Image: "ghcr.io/jenkins-x/exposecontroller" 13 | ImageTag: "2.3.118" 14 | 15 | cleanup: 16 | Args: 17 | - --cleanup 18 | Annotations: 19 | helm.sh/hook: pre-delete 20 | helm.sh/hook-delete-policy: hook-succeeded 21 | 22 | nuxeo: 23 | 24 | nuxeo: 25 | service: 26 | annotations: 27 | fabric8.io/expose: "true" 28 | fabric8.io/ingress.path: /nuxeo/ 29 | fabric8.io/ingress.name: preview 30 | fabric8.io/ingress.annotations: "nginx.ingress.kubernetes.io/proxy-body-size: 0" 31 | mongodb: 32 | deploy: false 33 | postgresql: 34 | deploy: false 35 | 36 | webui: 37 | image: 38 | repository: $DOCKER_REGISTRY/$DOCKER_IMAGE 39 | tag: $VERSION 40 | pullPolicy: Always 41 | 42 | service: 43 | port: 80 44 | annotations: 45 | fabric8.io/expose: "true" 46 | fabric8.io/ingress.path: / 47 | fabric8.io/ingress.name: preview 48 | -------------------------------------------------------------------------------- /crowdin-conf.yml: -------------------------------------------------------------------------------- 1 | "files": [ 2 | { 3 | "source": "/i18n/messages.json", 4 | "translation": "/i18n/messages-%two_letters_code%.json", 5 | "translation_replace": { 6 | "-es": "-es-ES", 7 | "-pt": "-pt-PT", 8 | "-sv": "-sv-SE", 9 | "-zh": "-zh-CN", 10 | } 11 | } 12 | ] 13 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.5' 2 | services: 3 | proxy: 4 | image: docker.packages.nuxeo.com/nuxeo/nginx-centos7:0.0.1 5 | volumes: 6 | - ./server/nginx.proxy.conf:/etc/nginx/nginx.conf:ro 7 | ports: 8 | - "8080:80" 9 | links: 10 | - nuxeo 11 | - webui 12 | 13 | webui: 14 | image: nuxeo-web-ui:${NUXEO_WEB_UI_VERSION} 15 | build: 16 | context: . 17 | 18 | nuxeo: 19 | image: nuxeo/nuxeo:${NUXEO_VERSION} 20 | environment: 21 | - NUXEO_DEV_MODE 22 | - NUXEO_PACKAGES 23 | - NUXEO_CLID 24 | -------------------------------------------------------------------------------- /elements/common-utils.js: -------------------------------------------------------------------------------- 1 | /** 2 | @license 3 | ©2023 Hyland Software, Inc. and its affiliates. All rights reserved. 4 | All Hyland product names are registered or unregistered trademarks of Hyland Software, Inc. or its affiliates. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | 19 | export function handleVerticalKeyNavigation(e, itemSelector) { 20 | const { key } = e; 21 | if (key !== 'ArrowDown' && key !== 'ArrowUp') { 22 | return; 23 | } 24 | 25 | e.preventDefault(); 26 | e.stopPropagation(); 27 | 28 | const rootNode = e.target.getRootNode(); 29 | const items = rootNode.querySelectorAll(itemSelector); 30 | const currentIndex = Array.from(items).indexOf(e.currentTarget); 31 | const nextIndex = key === 'ArrowDown' ? currentIndex + 1 : currentIndex - 1; 32 | 33 | if (nextIndex >= 0 && nextIndex < items.length) { 34 | items[nextIndex].focus(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /elements/document/audio/nuxeo-audio-view-layout.html: -------------------------------------------------------------------------------- 1 | 18 | 19 | 24 | 25 | 33 | 34 | 46 | 47 | -------------------------------------------------------------------------------- /elements/document/collections/nuxeo-collections-view-layout.html: -------------------------------------------------------------------------------- 1 | 18 | 19 | 24 | 25 | 28 | 29 | 43 | 44 | -------------------------------------------------------------------------------- /elements/document/domain/nuxeo-domain-view-layout.html: -------------------------------------------------------------------------------- 1 | 18 | 19 | 24 | 25 | 28 | 29 | 42 | 43 | -------------------------------------------------------------------------------- /elements/document/file/nuxeo-file-view-layout.html: -------------------------------------------------------------------------------- 1 | 18 | 19 | 24 | 25 | 33 | 34 | 46 | 47 | -------------------------------------------------------------------------------- /elements/document/folder/nuxeo-folder-view-layout.html: -------------------------------------------------------------------------------- 1 | 18 | 19 | 24 | 25 | 28 | 29 | 42 | 43 | -------------------------------------------------------------------------------- /elements/document/note/nuxeo-note-view-layout.html: -------------------------------------------------------------------------------- 1 | 18 | 19 | 24 | 25 | 33 | 34 | 46 | 47 | -------------------------------------------------------------------------------- /elements/document/orderedfolder/nuxeo-orderedfolder-view-layout.html: -------------------------------------------------------------------------------- 1 | 18 | 19 | 24 | 25 | 28 | 29 | 42 | 43 | -------------------------------------------------------------------------------- /elements/document/picture/nuxeo-picture-view-layout.html: -------------------------------------------------------------------------------- 1 | 18 | 19 | 24 | 25 | 33 | 34 | 46 | 47 | -------------------------------------------------------------------------------- /elements/document/root/nuxeo-root-view-layout.html: -------------------------------------------------------------------------------- 1 | 18 | 19 | 24 | 25 | 28 | 29 | 42 | 43 | -------------------------------------------------------------------------------- /elements/document/section/nuxeo-section-view-layout.html: -------------------------------------------------------------------------------- 1 | 18 | 19 | 24 | 25 | 28 | 29 | 42 | 43 | -------------------------------------------------------------------------------- /elements/document/sectionroot/nuxeo-sectionroot-view-layout.html: -------------------------------------------------------------------------------- 1 | 18 | 19 | 24 | 25 | 28 | 29 | 42 | 43 | -------------------------------------------------------------------------------- /elements/document/templateroot/nuxeo-templateroot-view-layout.html: -------------------------------------------------------------------------------- 1 | 18 | 19 | 24 | 25 | 28 | 29 | 42 | 43 | -------------------------------------------------------------------------------- /elements/document/userworkspacesroot/nuxeo-userworkspacesroot-view-layout.html: -------------------------------------------------------------------------------- 1 | 18 | 19 | 24 | 25 | 28 | 29 | 43 | 44 | -------------------------------------------------------------------------------- /elements/document/workspace/nuxeo-workspace-view-layout.html: -------------------------------------------------------------------------------- 1 | 18 | 19 | 24 | 25 | 28 | 29 | 43 | 44 | -------------------------------------------------------------------------------- /elements/document/workspaceroot/nuxeo-workspaceroot-create-layout.html: -------------------------------------------------------------------------------- 1 | 18 | 19 | 24 | 25 | 37 | 38 | -------------------------------------------------------------------------------- /elements/document/workspaceroot/nuxeo-workspaceroot-view-layout.html: -------------------------------------------------------------------------------- 1 | 18 | 19 | 24 | 25 | 28 | 29 | 42 | 43 | -------------------------------------------------------------------------------- /elements/fetch-schemas.js: -------------------------------------------------------------------------------- 1 | let schemasCache; 2 | 3 | export const _fetchSchemas = async (resource) => { 4 | if (!schemasCache) { 5 | resource.path = 'config/schemas'; 6 | schemasCache = await resource.get(); 7 | } 8 | return schemasCache; 9 | }; 10 | -------------------------------------------------------------------------------- /elements/nuxeo-profile.html: -------------------------------------------------------------------------------- 1 | 18 | 19 | 24 | 25 | 33 | 34 | 49 | 50 | -------------------------------------------------------------------------------- /elements/search/document_picker/nuxeo-document_picker-search-form.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 20 | 21 | 44 | 45 | -------------------------------------------------------------------------------- /elements/select-all-helpers.js: -------------------------------------------------------------------------------- 1 | import { PageProviderDisplayBehavior } from '@nuxeo/nuxeo-ui-elements/nuxeo-page-provider-display-behavior.js'; 2 | 3 | export const isPageProviderDisplayBehavior = (el) => 4 | el && el.behaviors && el.selectAllActive && PageProviderDisplayBehavior.every((p) => el.behaviors.includes(p)); 5 | -------------------------------------------------------------------------------- /elements/workflow/serialdocumentreview/nuxeo-task542-layout.html: -------------------------------------------------------------------------------- 1 | 18 | 19 | 20 | 25 | 26 | 43 | 44 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/favicon.ico -------------------------------------------------------------------------------- /fonts/Inter-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/fonts/Inter-Bold.woff -------------------------------------------------------------------------------- /fonts/Inter-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/fonts/Inter-Bold.woff2 -------------------------------------------------------------------------------- /fonts/Inter-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/fonts/Inter-Regular.woff -------------------------------------------------------------------------------- /fonts/Inter-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/fonts/Inter-Regular.woff2 -------------------------------------------------------------------------------- /fonts/Inter-SemiBold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/fonts/Inter-SemiBold.woff -------------------------------------------------------------------------------- /fonts/Inter-SemiBold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/fonts/Inter-SemiBold.woff2 -------------------------------------------------------------------------------- /ftest/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | 'extends': 'airbnb-base', 3 | 'root': true, 4 | 'rules': { 5 | 'class-methods-use-this': 0, 6 | 'comma-dangle': ["error", "always-multiline"], 7 | 'consistent-return': 0, 8 | 'func-names': 0, 9 | 'max-len': [2, 120, 2, { 10 | 'ignoreUrls': true, 11 | 'ignoreComments': false 12 | }], 13 | 'new-cap': [2, { 14 | 'capIsNewExceptions': [ 15 | 'Given', 16 | 'When', 17 | 'Then', 18 | 'After', 19 | 'Before', 20 | ] 21 | }], 22 | 'no-unused-expressions': 0, 23 | 'no-param-reassign': 0, 24 | 'no-plusplus': 0, 25 | 'no-else-return': 0, 26 | 'no-return-assign': 0, 27 | 'no-throw-literal': 0, 28 | 'no-underscore-dangle': 0, 29 | 'prefer-destructuring': 0, 30 | 'radix': 0 31 | }, 32 | 'globals': { 33 | 'addedComments': true, 34 | 'driver': true, 35 | 'fixtures': true, 36 | 'liveCollections': true, 37 | 'liveDocuments': true, 38 | 'runningWorkflows': true, 39 | 'users': true, 40 | 'groups': true, 41 | 'browser': true, 42 | '$': true, 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /ftest/features/activity.feature: -------------------------------------------------------------------------------- 1 | Feature: Activity 2 | 3 | Background: 4 | Given I login as "Administrator" 5 | And I have a Workspace document 6 | 7 | Scenario: Validate entries in activity tab 8 | When I have a File document 9 | And This document has file "" for content 10 | And I browse to the document 11 | Then I reload the page 12 | And I can see "created the document" in the Activity feed 13 | And I reload the page 14 | And I can see "viewed the document" in the Activity feed 15 | When I click the blob download button 16 | And I reload the page 17 | Then I can see "downloaded the document" in the Activity feed 18 | 19 | Examples: 20 | | file | 21 | | sample.png | 22 | -------------------------------------------------------------------------------- /ftest/features/admin.feature: -------------------------------------------------------------------------------- 1 | Feature: Admin center 2 | 3 | As an Administrator I have an Admin center 4 | As a member user I have no Admin center 5 | 6 | Scenario: Admin center as Admin 7 | Given I login as "Administrator" 8 | When I click the "administration" button 9 | Then I can see the administration menu 10 | 11 | # Analytics 12 | When I click "analytics" in the administration menu 13 | Then I can see the analytics page 14 | 15 | # Users & Groups 16 | When I click "user-group-management" in the administration menu 17 | Then I can see the users and groups page 18 | 19 | #Audit 20 | When I click "audit" in the administration menu 21 | Then I can see the audit page 22 | 23 | #Cloud Services 24 | When I click "cloud-services" in the administration menu 25 | Then I can see the cloud services page 26 | 27 | Scenario: Admin center as member user 28 | Given user "John" exists in group "members" 29 | And I login as "John" 30 | Then I cannot see the administration button 31 | 32 | Scenario: NXQL Search 33 | Given I login as "Administrator" 34 | When I click the "administration" button 35 | Then I can see the administration menu 36 | When I click "nxql" in the administration menu 37 | Then I can see the nxql search page 38 | And I can see more than 1 search results 39 | -------------------------------------------------------------------------------- /ftest/features/audit.feature: -------------------------------------------------------------------------------- 1 | Feature: Audit 2 | 3 | Background: 4 | Given I login as "Administrator" 5 | And I have a Workspace document 6 | And I have a Picture document 7 | And I browse to the document 8 | 9 | Scenario: Validate entries in audit tab for picture 10 | When I upload file "sample.png" as document content 11 | And I reload the page 12 | Then I click the "administration" button 13 | And I can see the administration menu 14 | When I click "audit" in the administration menu 15 | And I can see the audit page 16 | And I can see the audit table 17 | Then I have a non empty audit table 18 | And I can see "Download" entry in audit table 19 | -------------------------------------------------------------------------------- /ftest/features/authorized_apps.feature: -------------------------------------------------------------------------------- 1 | Feature: Authorized Applications 2 | 3 | As an Administrator I can manage authorized applications 4 | As a member user I have no authorized applications 5 | 6 | Background: 7 | 8 | Given I login as "Administrator" 9 | And the following OAuth2 clients exist 10 | | name | 11 | | My Client | 12 | | My Second Client | 13 | And I have tokens for the following OAuth2 clients 14 | | name | 15 | | My Client | 16 | | My Second Client | 17 | 18 | Scenario: View authorized applications 19 | When I am on user authorized applications page 20 | Then I can only see 2 authorized applications 21 | 22 | Scenario: Revoke access to an authorized application 23 | When I am on user authorized applications page 24 | Then I can revoke access for "My Client" application 25 | And I can only see 1 authorized application 26 | 27 | Scenario: members cannot see authorized applications 28 | Given user "John" exists in group "members" 29 | And I login as "John" 30 | When I am on user authorized applications page 31 | Then I cannot see authorized application 32 | -------------------------------------------------------------------------------- /ftest/features/compare.feature: -------------------------------------------------------------------------------- 1 | Feature: Compare 2 | 3 | I can Compare the documents 4 | 5 | Background: 6 | Given I have the following documents 7 | | doctype | title | nature | subjects | coverage | creator | path | collections | tag | file | 8 | | Workspace | Test_Workspace | booklet | art/culture | europe/Portugal | JSmith | /default-domain | | | | 9 | | Folder | Test_Folder | booklet | art/culture | europe/Portugal | JSmith | /default-domain/Test_Workspace/ | | | | 10 | | File | First_File | booklet | art/culture | europe/Portugal | JSmith | /default-domain/Test_Workspace/Test_Folder/ | | | sample.png | 11 | | File | Second_File | booklet | art/culture | europe/Portugal | JSmith | /default-domain/Test_Workspace/Test_Folder/ | | | sample.png | 12 | And I login as "Administrator" 13 | 14 | Scenario: Select all documents and compare properties 15 | When I browse to the document with path "/default-domain/Test_Workspace/Test_Folder" 16 | And I can see the "Test_Folder" document 17 | Then I select the "First_File" document 18 | And I select the "Second_File" document 19 | When I can click on the compare button 20 | Then I can see compare document page is displayed 21 | -------------------------------------------------------------------------------- /ftest/features/csv-import.feature: -------------------------------------------------------------------------------- 1 | Feature: CSV Import 2 | 3 | Scenario: I can import a CSV file and navigate to the created documents 4 | Given user "John" exists in group "members" 5 | And I login as "John" 6 | And I have a Workspace document 7 | And I have permission ReadWrite for this document 8 | And I browse to the document 9 | 10 | When I click the Create Document button 11 | And I go to the importCSV tab 12 | And I import the csv-import-sample.csv file 13 | Then I can see the "my_folder" child document is at position 1 14 | When I navigate to "my_folder" child 15 | Then I can see the "file1" child document is at position 1 16 | When I navigate to "file1" child 17 | Then I can see File metadata with the following properties: 18 | | name | value | 19 | | title | file1 | 20 | | description | doc in folder | 21 | | nature | Letter | 22 | | subjects | Daily life/Gastronomy,Society/Company | 23 | -------------------------------------------------------------------------------- /ftest/features/edit-note.feature: -------------------------------------------------------------------------------- 1 | Feature: Edit Note 2 | 3 | Note is editable in all supported formats 4 | 5 | Background: 6 | Given user "John" exists in group "members" 7 | And I login as "John" 8 | And I have a Workspace document 9 | 10 | Scenario Outline: Edit Note with Read permission 11 | Given I have permission Read for this document 12 | And I have a Note 13 | When I browse to the document 14 | Then I can't edit the Note 15 | 16 | Examples: 17 | | format | 18 | # | HTML | 19 | | XML | 20 | | Markdown | 21 | | Text | 22 | 23 | Scenario Outline: Edit Note with WriteProperties permission 24 | Given I have permission WriteProperties for this document 25 | And I have a Note 26 | When I browse to the document 27 | Then I can edit the Note 28 | 29 | Examples: 30 | | format | 31 | # | HTML | 32 | | XML | 33 | | Markdown | 34 | | Text | 35 | 36 | Scenario Outline: Edit Note 37 | Given I have permission ReadWrite for this document 38 | And I have a Note 39 | When I browse to the document 40 | Then I can edit the Note metadata 41 | And I can edit the Note 42 | 43 | Examples: 44 | | format | 45 | # | HTML | 46 | | XML | 47 | | Markdown | 48 | | Text | 49 | -------------------------------------------------------------------------------- /ftest/features/expired_doc.feature: -------------------------------------------------------------------------------- 1 | Feature: Expired Document 2 | 3 | Background: 4 | Given user "John" exists in group "members" 5 | And I login as "John" 6 | And I have a Workspace document 7 | And I have permission ReadWrite for this document 8 | 9 | Scenario Outline: Expired Document 10 | And I browse to the document 11 | When I click the Create Document button 12 | And I select File from the Document Type menu 13 | Then I create a document with the following properties: 14 | | name | value | 15 | | title | File | 16 | | description | my description | 17 | | nature | Application | 18 | | subjects | Gastronomy,Comics | 19 | | expired | February 28, 2018 | 20 | When I click the "expiredSearch" button 21 | And I switch to filter view 22 | And I perform a fulltext search for File on expiredSearch 23 | Then I can see 1 search results 24 | -------------------------------------------------------------------------------- /ftest/features/favorites.feature: -------------------------------------------------------------------------------- 1 | Feature: Favorites 2 | 3 | Background: 4 | Given user "John" exists in group "members" 5 | And I login as "John" 6 | 7 | Scenario: Favorites 8 | Given I have a HTML Note 9 | When I browse to the document 10 | Then I add the document to the favorites 11 | And I click the "favorites" button 12 | And I can see the document belongs to the favorites 13 | And I can remove the document from the favorites 14 | -------------------------------------------------------------------------------- /ftest/features/group.feature: -------------------------------------------------------------------------------- 1 | Feature: Group 2 | 3 | As an Administrator I can create, edit search for and delete groups. 4 | 5 | Background: 6 | Given I have the following groups 7 | | name | label | 8 | | mana?gers | Managers | 9 | | managers/webui | | 10 | Given user "John" exists in group "powerusers" 11 | And I login as "John" 12 | And I click the "administration" button 13 | And I can see the administration menu 14 | And I click "user-group-management" in the administration menu 15 | And I can see the users and groups page 16 | 17 | Scenario: Create Groups 18 | When I click the new user/group button 19 | And I select group from the dropdown menu 20 | Then I can see the new group form 21 | And I can create a group with the following properties: 22 | | name | value | 23 | | groupName | managers2 | 24 | | groupLabel | Managers2 | 25 | 26 | Scenario: Search Groups 27 | Then I can search for the following groups 28 | | name | label | 29 | | mana?gers | Managers | 30 | 31 | Scenario: Edit Groups 32 | Then I can edit the following groups 33 | | name | newLabel | 34 | | mana?gers | Managers Group | 35 | | managers/webui | Managers Group for web ui | 36 | 37 | Scenario: Delete Groups 38 | Then I can delete the following groups 39 | | name | label | 40 | | mana?gers | Managers | 41 | -------------------------------------------------------------------------------- /ftest/features/history.feature: -------------------------------------------------------------------------------- 1 | Feature: History 2 | 3 | Background: 4 | Given I login as "Administrator" 5 | And I have a Workspace document 6 | 7 | Scenario: Validate entries in history tab 8 | When I have a File document 9 | And This document has file "" for content 10 | And I browse to the document 11 | And I reload the page 12 | Then I can navigate to History pill 13 | And I can see the history table 14 | And I have a non empty history table 15 | And I can see "Document created" entry in history table 16 | And I can see "Download" entry in history table 17 | 18 | Examples: 19 | | file | 20 | | sample.png | 21 | -------------------------------------------------------------------------------- /ftest/features/home.feature: -------------------------------------------------------------------------------- 1 | Feature: Home 2 | 3 | I have a home page 4 | 5 | Background: 6 | Given user "John" exists in group "members" 7 | And I login as "John" 8 | 9 | Scenario: My dashboard 10 | When I click the Nuxeo logo 11 | Then I can see my home 12 | And I have a "latestEditedDocs" card 13 | And I have a "latestViewedDocs" card 14 | And I have a "tasksList" card 15 | And I have a "favoriteDocs" card 16 | -------------------------------------------------------------------------------- /ftest/features/login-logout.feature: -------------------------------------------------------------------------------- 1 | Feature: Login / Logout 2 | 3 | As an user I can login and logout 4 | 5 | @critical 6 | Scenario: Login as Administrator 7 | When I login as "Administrator" 8 | Then I am logged in as "Administrator" 9 | 10 | @critical 11 | Scenario: Login as member user 12 | Given user "John" exists in group "members" 13 | When I login as "John" 14 | Then I am logged in as "John" 15 | 16 | @critical 17 | Scenario: Logout 18 | When I logout 19 | Then I am logged out 20 | -------------------------------------------------------------------------------- /ftest/features/personal.feature: -------------------------------------------------------------------------------- 1 | Feature: Personal Workspace 2 | 3 | Background: 4 | Given user "John" exists in group "members" 5 | And I login as "John" 6 | 7 | Scenario: Personal Workspace 8 | When I click the "personalWorkspace" button 9 | Then I can see my personal workspace 10 | When I click "John" in the personalWorkspace tree 11 | Then I can see the "John" document 12 | -------------------------------------------------------------------------------- /ftest/features/upload.feature: -------------------------------------------------------------------------------- 1 | Feature: Upload 2 | 3 | Background: 4 | Given user "John" exists in group "members" 5 | And I login as "John" 6 | And I have a File document 7 | 8 | Scenario: Blob upload options for Read permission 9 | Given I have permission Read for this document 10 | When I browse to the document 11 | Then I can't see the option to add a main blob 12 | When This document has file "sample.png" for content 13 | And I browse to the document 14 | Then I can't see the blob replace button 15 | And I can't see the option to add new attachments 16 | 17 | Scenario: Blob upload options for WriteProperties permission 18 | Given I have permission WriteProperties for this document 19 | When I browse to the document 20 | Then I can see the option to add a main blob 21 | And I upload file "sample.png" as document content 22 | Then I can see the blob replace button 23 | And I can see the option to add new attachments 24 | -------------------------------------------------------------------------------- /ftest/features/user_cloud.feature: -------------------------------------------------------------------------------- 1 | Feature: User Cloud Services 2 | 3 | Users can manage their OAuth2 provider tokens. 4 | 5 | Background: 6 | Given user "John" exists in group "members" 7 | And I login as "John" 8 | And the following OAuth2 providers exist 9 | | name | 10 | | test-oauth2-provider | 11 | | test-oauth2-provider-2 | 12 | And I have tokens for the following OAuth2 providers 13 | | name | 14 | | test-oauth2-provider | 15 | | test-oauth2-provider-2 | 16 | 17 | Scenario: View provider tokens 18 | When I am on user cloud services page 19 | Then I can only see 2 provider tokens that belong to me 20 | 21 | Scenario: Delete a provider token 22 | When I am on user cloud services page 23 | Then I can delete token for provider "test-oauth2-provider" that belongs to me 24 | And I can only see 1 provider token that belongs to me 25 | -------------------------------------------------------------------------------- /ftest/features/vocabularies.feature: -------------------------------------------------------------------------------- 1 | Feature: Vocabularies 2 | 3 | Vocabularies can be added, edit and removed. 4 | 5 | Background: 6 | Given user "John" exists in group "powerusers" 7 | And I login as "John" 8 | 9 | Scenario: Vocabularies menu on drawer 10 | When I click the "administration" button 11 | Then I can see the administration menu 12 | When I click "vocabulary-management" in the administration menu 13 | Then I can see the vocabulary page 14 | 15 | Scenario: Simple vocabulary create, edit, delete 16 | Given I am on vocabulary page 17 | When I select "continent" vocabulary 18 | Then I can see the vocabulary table 19 | And I have a non empty table 20 | And I cannot see "Brittany" entry 21 | And I cannot see "Breizh" entry 22 | And I can add "Brittany" entry 23 | And I can see "Brittany" entry 24 | And I can edit entry with index 8 and new label "Breizh" 25 | And I can see "Breizh" entry 26 | And I can delete entry with index 8 27 | And I cannot see "Breizh" entry 28 | And I cannot see "Brittany" entry 29 | 30 | Scenario: l10n vocabulary check 31 | Given I am on vocabulary page 32 | When I select "l10ncoverage" vocabulary 33 | Then I can see the vocabulary table 34 | And I can see create dialog 35 | And I can see edit dialog 36 | -------------------------------------------------------------------------------- /ftest/resources/csv-import-sample.csv: -------------------------------------------------------------------------------- 1 | "name","type","dc:title","dc:description","dc:format","dc:source","dc:language","dc:nature","dc:subjects" 2 | "my_folder","Folder","my_folder","This is the description of a folder that will hold some documents",,"Nuxeo CSV import",,, 3 | "my_folder/file1","File","file1","doc in folder",,"Nuxeo CSV Import","English","letter","daily life/gastronomy|society/company" 4 | -------------------------------------------------------------------------------- /ftest/resources/sample.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/ftest/resources/sample.mp3 -------------------------------------------------------------------------------- /ftest/resources/sample.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/ftest/resources/sample.mp4 -------------------------------------------------------------------------------- /ftest/resources/sample.odt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/ftest/resources/sample.odt -------------------------------------------------------------------------------- /ftest/resources/sample.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/ftest/resources/sample.pdf -------------------------------------------------------------------------------- /ftest/resources/sample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/ftest/resources/sample.png -------------------------------------------------------------------------------- /ftest/resources/sample.txt: -------------------------------------------------------------------------------- 1 | Just some text. 2 | -------------------------------------------------------------------------------- /ftest/src/main/resources/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/ftest/src/main/resources/META-INF/MANIFEST.MF -------------------------------------------------------------------------------- /ftest/src/test/java/org/nuxeo/sample/functionaltests/ITLoginLogoutTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ©2023 Hyland Software, Inc. and its affiliates. All rights reserved. 3 | All Hyland product names are registered or unregistered trademarks of Hyland Software, Inc. or its affiliates. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * Contributors: 18 | * Nelson Silva 19 | */ 20 | package org.nuxeo.sample.functionaltests; 21 | 22 | import org.junit.Test; 23 | import org.nuxeo.functionaltests.AbstractTest; 24 | import org.nuxeo.functionaltests.pages.DocumentBasePage.UserNotConnectedException; 25 | 26 | /** 27 | * Simple login, logout test. 28 | */ 29 | public class ITLoginLogoutTest extends AbstractTest { 30 | 31 | @Test 32 | public void testLoginLogout() throws UserNotConnectedException { 33 | login(); 34 | logout(); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /i18n/i18n.js: -------------------------------------------------------------------------------- 1 | /** 2 | @license 3 | ©2023 Hyland Software, Inc. and its affiliates. All rights reserved. 4 | All Hyland product names are registered or unregistered trademarks of Hyland Software, Inc. or its affiliates. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | import { XHRLocaleResolver } from '@nuxeo/nuxeo-ui-elements/nuxeo-i18n-behavior.js'; 19 | 20 | const baseUrl = window.nuxeo.I18n.baseUrl || window.location.origin + window.location.pathname; 21 | const msgFolder = `${baseUrl + (baseUrl.endsWith('/') ? '' : '/')}i18n`; 22 | window.nuxeo.I18n.language = navigator.language || navigator.userLanguage || 'en'; 23 | window.nuxeo.I18n.localeResolver = new XHRLocaleResolver(msgFolder); 24 | window.nuxeo.I18n.loadLocale().then(() => { 25 | /* Set html lang attribute. Required by the better-dateinput element */ 26 | document.getElementsByTagName('html')[0].lang = window.nuxeo.I18n.language; 27 | }); 28 | -------------------------------------------------------------------------------- /images/README.md: -------------------------------------------------------------------------------- 1 | All images, icons, fonts, and videos contained in this folder are copyrighted by Hyland Software, all rights reserved. 2 | -------------------------------------------------------------------------------- /images/blank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/images/blank.png -------------------------------------------------------------------------------- /images/doctypes/README.md: -------------------------------------------------------------------------------- 1 | All images, icons, fonts, and videos contained in this folder are copyrighted by Hyland Software, all rights reserved. 2 | -------------------------------------------------------------------------------- /images/doctypes/audio.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /images/doctypes/collection.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /images/doctypes/collections.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /images/doctypes/document.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /images/doctypes/domain.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /images/doctypes/file.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /images/doctypes/folder.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /images/doctypes/note.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /images/doctypes/orderedfolder.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /images/doctypes/picture.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /images/doctypes/section.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /images/doctypes/video.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /images/gift.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/images/gift.png -------------------------------------------------------------------------------- /images/nuxeo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/images/nuxeo.png -------------------------------------------------------------------------------- /images/sardine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/images/sardine.png -------------------------------------------------------------------------------- /images/touch/README.md: -------------------------------------------------------------------------------- 1 | All images, icons, fonts, and videos contained in this folder are copyrighted by Hyland Software, all rights reserved. 2 | -------------------------------------------------------------------------------- /images/touch/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/images/touch/android-chrome-192x192.png -------------------------------------------------------------------------------- /images/touch/android-chrome-384x384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/images/touch/android-chrome-384x384.png -------------------------------------------------------------------------------- /images/touch/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/images/touch/apple-touch-icon.png -------------------------------------------------------------------------------- /images/touch/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/images/touch/favicon-16x16.png -------------------------------------------------------------------------------- /images/touch/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/images/touch/favicon-32x32.png -------------------------------------------------------------------------------- /images/touch/icon-128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/images/touch/icon-128x128.png -------------------------------------------------------------------------------- /images/touch/ms-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/images/touch/ms-icon-144x144.png -------------------------------------------------------------------------------- /images/touch/ms-touch-icon-144x144-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/images/touch/ms-touch-icon-144x144-precomposed.png -------------------------------------------------------------------------------- /images/touch/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/images/touch/mstile-150x150.png -------------------------------------------------------------------------------- /images/touch/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.11, written by Peter Selinger 2001-2013 9 | 10 | 12 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Nuxeo", 3 | "short_name": "Nuxeo", 4 | "icons": [{ 5 | "src": "images/touch/icon-128x128.png", 6 | "sizes": "128x128", 7 | "type": "image/png" 8 | }, { 9 | "src": "images/touch/apple-touch-icon.png", 10 | "sizes": "180x180", 11 | "type": "image/png" 12 | }, { 13 | "src": "images/touch/ms-touch-icon-144x144-precomposed.png", 14 | "sizes": "144x144", 15 | "type": "image/png" 16 | }, { 17 | "src": "images/touch/android-chrome-192x192.png", 18 | "sizes": "192x192", 19 | "type": "image/png" 20 | },{ 21 | "src": "images/touch/android-chrome-384x384.png", 22 | "sizes": "384x384", 23 | "type": "image/png" 24 | }], 25 | "background_color": "#ffffff", 26 | "display": "standalone", 27 | "theme_color": "#ffffff", 28 | "start_url": "." 29 | } 30 | -------------------------------------------------------------------------------- /packages/nuxeo-designer-catalog/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | package-lock.json 3 | -------------------------------------------------------------------------------- /packages/nuxeo-designer-catalog/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "designer-catalog", 3 | "version": "1.0.0", 4 | "description": "Catalog generator for View Designer", 5 | "license": "Apache-2.0", 6 | "vendor": "Nuxeo", 7 | "engines": { 8 | "node": ">=14.0.0" 9 | }, 10 | "private": true, 11 | "main": "index.js", 12 | "scripts": { 13 | "postinstall": "check-engine --ignore", 14 | "clean-data": "find data/applications/nuxeo/**/ ! -name 'catalog-packages.json' -delete" 15 | }, 16 | "dependencies": { 17 | "async": "^3.2.3", 18 | "async-each": "^1.0.3", 19 | "check-engine": "^1.10.1", 20 | "concat-stream": "^1.6.2", 21 | "decamelize": "^1.2.0", 22 | "del": "^2.2.2", 23 | "end-of-stream": "^1.4.4", 24 | "fancy-log": "^2.0.0", 25 | "from2": "^1.3.0", 26 | "fs-extra": "^11.3.0", 27 | "gulp": "^5.0.0", 28 | "gulp-git": "^2.10.1", 29 | "is-stream": "^1.1.0", 30 | "JSONStream": "^1.3.5", 31 | "lodash": "^4.17.21", 32 | "marked": "^4.0.17", 33 | "merge-stream": "^1.0.1", 34 | "polymer-analyzer": "^3.2.4", 35 | "pumpify": "^1.5.1", 36 | "split": "^1.0.1", 37 | "through2": "^0.6.5", 38 | "through2-asyncmap": "^1.1.0", 39 | "through2-concurrent": "^1.1.1", 40 | "through2-filter": "^1.4.1", 41 | "through2-map": "^1.4.0", 42 | "through2-reduce": "^0.3.0", 43 | "vinyl": "^3.0.0", 44 | "vinyl-buffer": "^1.0.1", 45 | "vinyl-source-stream": "^1.1.2", 46 | "writestreamp": "^0.1.1" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /packages/nuxeo-designer-catalog/src/packages.js: -------------------------------------------------------------------------------- 1 | /** 2 | @license 3 | ©2023 Hyland Software, Inc. and its affiliates. All rights reserved. 4 | All Hyland product names are registered or unregistered trademarks of Hyland Software, Inc. or its affiliates. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | const stream = require('./utils/stream').obj; 19 | 20 | module.exports = () => 21 | // we are interested in all the packages 22 | stream.compose( 23 | stream.parse('packages.*'), 24 | stream.filter(() => true), 25 | stream.asyncMap((pkg, done) => { 26 | done(null, pkg); 27 | }), 28 | ); 29 | -------------------------------------------------------------------------------- /packages/nuxeo-designer-catalog/src/utils/clean-tags.js: -------------------------------------------------------------------------------- 1 | /** 2 | @license 3 | ©2023 Hyland Software, Inc. and its affiliates. All rights reserved. 4 | All Hyland product names are registered or unregistered trademarks of Hyland Software, Inc. or its affiliates. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | const excluded = ['nuxeo', 'web-components', 'polymer', 'web-component', 'gold', 'paper', 'google', 'iron']; 19 | module.exports = (tag) => excluded.indexOf(tag.toLowerCase()) < 0; 20 | -------------------------------------------------------------------------------- /packages/nuxeo-designer-catalog/src/utils/git-branch.js: -------------------------------------------------------------------------------- 1 | /** 2 | @license 3 | ©2023 Hyland Software, Inc. and its affiliates. All rights reserved. 4 | All Hyland product names are registered or unregistered trademarks of Hyland Software, Inc. or its affiliates. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | const fs = require('fs'); 19 | const path = require('path'); 20 | 21 | /** 22 | * Returns the branch of the repository checkout located in `repositoryPath`. 23 | * The `.git/HEAD` file is read and parsed to get the branch name. 24 | */ 25 | module.exports = (repositoryPath) => { 26 | const headFilePath = path.join(repositoryPath, '.git', 'HEAD'); 27 | const match = /ref: refs\/heads\/([^\n]+)/.exec(fs.readFileSync(headFilePath, 'utf8')); 28 | return match ? match[1] : null; 29 | }; 30 | -------------------------------------------------------------------------------- /packages/nuxeo-designer-catalog/src/utils/package-details.js: -------------------------------------------------------------------------------- 1 | /** 2 | @license 3 | ©2023 Hyland Software, Inc. and its affiliates. All rights reserved. 4 | All Hyland product names are registered or unregistered trademarks of Hyland Software, Inc. or its affiliates. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | const path = require('path'); 19 | const fs = require('fs'); 20 | 21 | module.exports = (imports) => { 22 | const { root } = imports; 23 | const { name } = imports; 24 | const { pkgManagement } = imports; 25 | const componentDir = pkgManagement === 'npm' ? 'node_modules' : 'bower_components'; 26 | const dependenciesFile = pkgManagement === 'npm' ? 'package.json' : 'bower.json'; 27 | 28 | const packageFilePath = path.resolve(path.join(root, componentDir, name, dependenciesFile)); 29 | if (fs.existsSync(packageFilePath)) { 30 | // eslint-disable-next-line global-require, import/no-dynamic-require 31 | return require(packageFilePath); 32 | } 33 | return {}; 34 | }; 35 | -------------------------------------------------------------------------------- /packages/nuxeo-designer-catalog/src/utils/package-elements.js: -------------------------------------------------------------------------------- 1 | /** 2 | @license 3 | ©2023 Hyland Software, Inc. and its affiliates. All rights reserved. 4 | All Hyland product names are registered or unregistered trademarks of Hyland Software, Inc. or its affiliates. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | const _ = require('lodash'); 19 | 20 | module.exports = (imports) => { 21 | let { deps } = imports; 22 | 23 | deps = deps || {}; 24 | 25 | return _(deps) 26 | .keys() 27 | .value(); 28 | }; 29 | -------------------------------------------------------------------------------- /packages/nuxeo-designer-catalog/src/utils/parse-version.js: -------------------------------------------------------------------------------- 1 | /** 2 | @license 3 | ©2023 Hyland Software, Inc. and its affiliates. All rights reserved. 4 | All Hyland product names are registered or unregistered trademarks of Hyland Software, Inc. or its affiliates. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | module.exports = (version) => (version.indexOf('#') > 0 ? version.split('#')[1] : version); 19 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "globals": { 3 | "$": true, 4 | "addedVocabularyEntries": true, 5 | "addedComments": true, 6 | "driver": true, 7 | "fixtures": true, 8 | "liveCollections": true, 9 | "liveDocuments": true, 10 | "runningWorkflows": true, 11 | "users": true, 12 | "groups": true, 13 | "browser": true, 14 | "moment": true, 15 | "assert": true, 16 | "expect": true 17 | }, 18 | "overrides": [ 19 | { 20 | "files": ["features/step_definitions/*.js"], 21 | "rules": { 22 | "no-unused-expressions": "off" 23 | } 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/bin/nuxeo-web-ui-ftest.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | require('../scripts/test'); 4 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/features/step_definitions/audit.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/no-extraneous-dependencies 2 | import { Then } from '@cucumber/cucumber'; 3 | 4 | Then('I can see the audit table', async function() { 5 | const isAuditTableDisplay = await this.ui.administration.audit.isAuditTableDisplayed; 6 | isAuditTableDisplay.should.be.true; 7 | }); 8 | 9 | Then('I have a non empty audit table', async function() { 10 | const isAuditTableFilled = await this.ui.administration.audit.isAuditTableFilled; 11 | isAuditTableFilled.should.be.true; 12 | }); 13 | 14 | Then('I can see {string} entry in audit table', async function(performedAction) { 15 | const administration = await this.ui.administration; 16 | const audit = await administration.audit; 17 | const hasEntry = await audit.waitForHasEntry(performedAction); 18 | hasEntry.should.be.true; 19 | }); 20 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/features/step_definitions/compare.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/no-extraneous-dependencies 2 | import { Then, When } from '@cucumber/cucumber'; 3 | 4 | When('I can click on the compare button', async function() { 5 | await this.ui.browser.waitForVisible(); 6 | const toolbarEle = await this.ui.browser.selectionToolbar; 7 | const compareEle = await toolbarEle.compare; 8 | await compareEle.click(); 9 | }); 10 | 11 | Then('I can see compare document page is displayed', function() { 12 | this.ui.browser.comparePage.isDisplayed(); 13 | }); 14 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/features/step_definitions/doc_suggestion.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/no-extraneous-dependencies 2 | import { Then } from '@cucumber/cucumber'; 3 | 4 | Then('I can navigate to the document selected in the {string} single document suggestion widget', async function(name) { 5 | const docpageEle = await this.ui.browser.documentPage('DocSuggestion'); 6 | const docmetaEle = await docpageEle.metadata; 7 | const layoutEle = await docmetaEle.layout(); 8 | const fieldEle = await layoutEle.getField(name); 9 | const singleItemELe = await fieldEle.element('.selectivity-single-selected-item'); 10 | const elementEx = await singleItemELe.element('a'); 11 | elementEx.click(); 12 | }); 13 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/features/step_definitions/favorites.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/no-extraneous-dependencies 2 | import { Then } from '@cucumber/cucumber'; 3 | 4 | Then('I can see the document belongs to the favorites', async function() { 5 | const drawerEle = await this.ui.drawer; 6 | const favEle = await drawerEle.favorites; 7 | await favEle.hasDocument(this.doc); 8 | }); 9 | 10 | Then('I can remove the document from the favorites', async function() { 11 | const drawerEle = await this.ui.drawer; 12 | const favorites = await drawerEle.favorites; 13 | await favorites.removeDocument(this.doc); 14 | }); 15 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/features/step_definitions/history.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/no-extraneous-dependencies 2 | import { Then } from '@cucumber/cucumber'; 3 | 4 | Then('I can see the history table', async function() { 5 | const historyTable = await this.ui.historyTable; 6 | const isHistoryTableDisplayed = await historyTable.isHistoryTableVisible; 7 | if (!isHistoryTableDisplayed) { 8 | throw new Error('History Table not found'); 9 | } 10 | }); 11 | 12 | Then('I have a non empty history table', async function() { 13 | const historyTable = await this.ui.historyTable; 14 | const isTableFilled = await historyTable.isHistoryTableFilled; 15 | 16 | if (!isTableFilled) { 17 | throw new Error('History Table not found'); 18 | } 19 | }); 20 | 21 | Then('I can see {string} entry in history table', async function(performedAction) { 22 | const historyTable = await this.ui.historyTable; 23 | const hasEntry = await historyTable.waitForHasEntry(performedAction); 24 | hasEntry.should.be.true; 25 | }); 26 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/features/step_definitions/home.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/no-extraneous-dependencies 2 | import { Then, When } from '@cucumber/cucumber'; 3 | 4 | When('I click the Nuxeo logo', async function() { 5 | const home = await this.ui.goHome(); 6 | return home; 7 | }); 8 | 9 | Then('I can see my home', async function() { 10 | const check = await this.ui.home.waitForVisible(); 11 | check.should.be.true; 12 | }); 13 | 14 | Then('I have a {string} card', async function(title) { 15 | const card = await this.ui.home.card(title); 16 | const visi = await card.waitForVisible(); 17 | visi.should.be.true; 18 | }); 19 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/features/step_definitions/personal.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/no-extraneous-dependencies 2 | import { Then } from '@cucumber/cucumber'; 3 | 4 | Then('I can see my personal workspace', async function() { 5 | const personalEle = await this.ui.drawer.personal; 6 | await personalEle.waitForVisible(); 7 | if (!personalEle) { 8 | throw new Error(`Expected my personal workspace not be visible`); 9 | } 10 | }); 11 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/features/step_definitions/picture.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/no-extraneous-dependencies 2 | import { Then } from '@cucumber/cucumber'; 3 | 4 | Then('I can see the picture formats panel', async function() { 5 | const uiBrowser = await this.ui.browser; 6 | const page = await uiBrowser.documentPage(this.doc.type); 7 | await page.waitForVisible(); 8 | const additionalPage = await page.el.element('.additional'); 9 | await additionalPage.waitForVisible(); 10 | const pageElement = await additionalPage.waitForVisible('nuxeo-picture-formats'); 11 | await pageElement.should.be.true; 12 | }); 13 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/features/step_definitions/preview.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/no-extraneous-dependencies 2 | import { Then, When } from '@cucumber/cucumber'; 3 | 4 | When('I click the preview button', async function() { 5 | const page = await this.ui.browser.documentPage(this.doc.type); 6 | await page.waitForVisible(); 7 | const buttonEle = await page.previewButton; 8 | await buttonEle.waitForVisible(); 9 | await buttonEle.click(); 10 | }); 11 | 12 | When('I click the preview button for the attachment', async function() { 13 | const page = await this.ui.browser.documentPage(this.doc.type); 14 | await page.waitForVisible(); 15 | const attachEle = await page.metadata.attachments; 16 | await attachEle.waitForVisible(); 17 | const buttonEle = await attachEle.previewButton; 18 | await buttonEle.click(); 19 | }); 20 | 21 | Then(/^I can see the inline ([-\w]+) previewer$/, async function(viewerType) { 22 | const uiBrowser = await this.ui.browser; 23 | const page = await uiBrowser.documentPage(this.doc.type); 24 | await page.waitForVisible(); 25 | const pageView = await page.view; 26 | await pageView.waitForVisible(); 27 | const preview = await pageView.preview; 28 | await preview.waitForVisible(); 29 | if (viewerType === 'plain') { 30 | await preview.waitForVisible(`#${viewerType}`); 31 | return; 32 | } 33 | await preview.waitForVisible(viewerType); 34 | }); 35 | 36 | Then(/^I can see a ([-\w]+) previewer$/, async (viewerType) => { 37 | await $(`#dialog ${viewerType}`).waitForVisible(); 38 | }); 39 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/features/step_definitions/recents.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/no-extraneous-dependencies 2 | import { Then, When } from '@cucumber/cucumber'; 3 | 4 | When('I can click on recently viewed documents item {string}', async function(title) { 5 | await this.ui.drawer.recents.waitForVisible(); 6 | const member = await this.ui.drawer.recents.waitForHasMember(title); 7 | member.should.be.true; 8 | const selectTitle = await this.ui.drawer.recents.select(title); 9 | selectTitle.should.be.true; 10 | }); 11 | 12 | Then('I can see the list of recently viewed documents', function() { 13 | this.ui.drawer.recents.waitForVisible().should.be.true; 14 | }); 15 | 16 | Then('I can see the list of recently viewed documents has {int} item(s)', async function(nb) { 17 | const drawer = await this.ui.drawer; 18 | const recents = await drawer.recents; 19 | await recents.waitForVisible(); 20 | const item = await recents.nbItems; 21 | if (item !== nb) { 22 | throw new Error(`Expected count of ${nb} but found ${item}`); 23 | } 24 | }); 25 | 26 | Then('I can see the list of recently viewed documents has {string} document', async function(title) { 27 | const drawer = await this.ui.drawer; 28 | const recents = await drawer.recents; 29 | await recents.waitForVisible(); 30 | const member = await recents.waitForHasMember(title); 31 | member.should.be.true; 32 | }); 33 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/features/step_definitions/support/fixtures/_fixtures.js: -------------------------------------------------------------------------------- 1 | // global.fixtures = {}; 2 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/features/step_definitions/support/fixtures/blobs.js: -------------------------------------------------------------------------------- 1 | fixtures.blobs = { 2 | get: (file) => `resources/${file}`, 3 | }; 4 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/features/step_definitions/support/fixtures/collections.js: -------------------------------------------------------------------------------- 1 | import nuxeo from '../services/client'; 2 | 3 | fixtures.collections = { 4 | addToNewCollection: (document, colName) => 5 | nuxeo 6 | .operation('Collection.Create') 7 | .params({ 8 | name: colName, 9 | }) 10 | .execute() 11 | .then((col) => 12 | nuxeo 13 | .operation('Document.AddToCollection') 14 | .input(document) 15 | .params({ 16 | collection: col, 17 | }) 18 | .execute(), 19 | ), 20 | addToCollection: (document, colName) => 21 | nuxeo 22 | .repository() 23 | .fetch(`/default-domain/${colName}`) 24 | .then((collection) => 25 | nuxeo 26 | .operation('Document.AddToCollection') 27 | .input(document) 28 | .params({ 29 | collection, 30 | }) 31 | .execute(), 32 | ), 33 | }; 34 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/features/step_definitions/support/fixtures/comments.js: -------------------------------------------------------------------------------- 1 | import Nuxeo from 'nuxeo'; 2 | // eslint-disable-next-line import/no-extraneous-dependencies 3 | import { After } from '@cucumber/cucumber'; 4 | 5 | global.addedComments = []; 6 | 7 | fixtures.comments = { 8 | create: (parentId, author, text) => { 9 | const params = { 10 | body: { 11 | 'entity-type': 'comment', 12 | parentId, 13 | text, 14 | }, 15 | }; 16 | const nuxeo = new Nuxeo({ 17 | auth: { method: 'basic', username: author, password: users[author] }, 18 | baseURL: process.env.NUXEO_URL, 19 | headers: { 'nx-es-sync': 'true' }, 20 | }); 21 | return nuxeo 22 | .request(`/id/${parentId}/@comment`) 23 | .post(params) 24 | .then((response) => { 25 | if (response.ancestorIds.length === 1) { 26 | addedComments.push(response); 27 | } 28 | }); 29 | }, 30 | 31 | get: (author, text) => addedComments.find((item) => item.author === author && item.text === text), 32 | }; 33 | 34 | After(() => { 35 | addedComments = []; 36 | }); 37 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/features/step_definitions/support/fixtures/documents.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/no-extraneous-dependencies 2 | import { After, Before } from '@cucumber/cucumber'; 3 | import documentService from '../services/documentService'; 4 | 5 | fixtures.documents = documentService; 6 | 7 | Before(function() { 8 | return documentService.getDocument('/default-domain').then((doc) => { 9 | this.doc = doc; 10 | }); 11 | }); 12 | 13 | After(() => documentService.reset()); 14 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/features/step_definitions/support/fixtures/localstorage.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/no-extraneous-dependencies 2 | import { After } from '@cucumber/cucumber'; 3 | 4 | /* global document, localStorage */ 5 | // cleans up local storage fo the current user 6 | After({ tags: '@cleanupLocalStorage' }, () => 7 | browser.execute(() => { 8 | const username = document.querySelector('nuxeo-app').currentUser.id; 9 | Object.keys(localStorage).forEach((storage) => { 10 | if (storage.startsWith(`${username}-`)) { 11 | localStorage.removeItem(storage); 12 | } 13 | }); 14 | }), 15 | ); 16 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/features/step_definitions/support/fixtures/notes.js: -------------------------------------------------------------------------------- 1 | fixtures.notes = { 2 | formats: { 3 | HTML: { mimetype: 'text/html', content: '

HTML CONTENT

' }, 4 | XML: { mimetype: 'text/xml', content: 'XML CONTENT' }, 5 | Markdown: { mimetype: 'text/x-web-markdown', content: 'MARKDOWN CONTENT' }, 6 | Text: { mimetype: 'text/plain', content: 'TEXT CONTENT' }, 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/features/step_definitions/support/fixtures/searches.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/no-extraneous-dependencies 2 | import { After } from '@cucumber/cucumber'; 3 | import nuxeo from '../services/client'; 4 | 5 | fixtures.savedSearches = { 6 | create: (name, pageProvider, params) => { 7 | const body = { 8 | 'entity-type': 'savedSearch', 9 | pageProviderName: pageProvider, 10 | params: { 11 | 'cvd:contentViewName': pageProvider, 12 | }, 13 | title: name, 14 | }; 15 | Object.assign(body.params, params); 16 | return nuxeo.request('search/saved').post({ body }); 17 | }, 18 | setPermissions: (savedSearch, permission, username) => 19 | nuxeo 20 | .operation('Document.AddPermission') 21 | .input(typeof savedSearch === 'string' ? savedSearch : savedSearch.id) 22 | .params({ 23 | permission, 24 | username, 25 | }) 26 | .execute(), 27 | }; 28 | 29 | After(() => 30 | nuxeo 31 | .request('/search/saved') 32 | .get() 33 | .then((res) => { 34 | const promises = []; 35 | res.entries.forEach((savedSearch) => { 36 | promises.push(nuxeo.repository().delete(savedSearch.id)); 37 | }); 38 | return Promise.all(promises); 39 | }) 40 | .catch((error) => { 41 | throw new Error(error); 42 | }), 43 | ); 44 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/features/step_definitions/support/fixtures/vocabularies.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/no-extraneous-dependencies 2 | import { After } from '@cucumber/cucumber'; 3 | import nuxeo from '../services/client'; 4 | 5 | global.addedVocabularyEntries = []; 6 | 7 | fixtures.vocabularies = { 8 | createEntry: (directoryName, id, properties) => 9 | nuxeo 10 | .request(`/directory/${directoryName}/${id}`) 11 | .get() 12 | .catch(() => { 13 | const params = { 14 | body: { 15 | 'entity-type': 'directoryEntry', 16 | directoryName, 17 | properties, 18 | }, 19 | }; 20 | return nuxeo 21 | .request(`/directory/${directoryName}`) 22 | .post(params) 23 | .then((response) => { 24 | addedVocabularyEntries.push(response); 25 | }) 26 | .catch(() => {}); 27 | }), 28 | }; 29 | After(() => 30 | Promise.all( 31 | addedVocabularyEntries.map((entry) => 32 | nuxeo 33 | .request(`/directory/${entry.directoryName}/${entry.id}`) 34 | .delete() 35 | .catch(() => {}), 36 | ), 37 | ) // eslint-disable-line arrow-body-style 38 | .then(() => { 39 | addedVocabularyEntries = []; 40 | }), 41 | ); 42 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/features/step_definitions/support/screenshots.js: -------------------------------------------------------------------------------- 1 | import * as path from 'path'; 2 | import * as mkdirp from 'mkdirp'; 3 | // eslint-disable-next-line import/no-extraneous-dependencies 4 | import { After, Status } from '@cucumber/cucumber'; 5 | 6 | After(async function(scenario) { 7 | const { status } = scenario.result; 8 | if (process.env.SCREENSHOTS_PATH && status === Status.FAILED) { 9 | mkdirp.sync(process.env.SCREENSHOTS_PATH); 10 | const filename = path.join(process.env.SCREENSHOTS_PATH, `${scenario.pickle.name} (${status}).png`); 11 | const screenshot = await browser.saveScreenshot(filename); 12 | this.attach(screenshot, 'image/png'); 13 | } 14 | }); 15 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/features/step_definitions/support/services/client.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import path from 'path'; 3 | import Nuxeo, { Blob } from 'nuxeo'; 4 | 5 | export default new Nuxeo({ 6 | auth: { method: 'basic', username: 'Administrator', password: 'Administrator' }, 7 | baseURL: process.env.NUXEO_URL, 8 | headers: { 'nx-es-sync': 'true' }, 9 | }); 10 | 11 | export class BlobHelper { 12 | static fromPath(blobPath) { 13 | const stats = fs.statSync(blobPath); 14 | const file = fs.createReadStream(blobPath); 15 | return new Blob({ 16 | content: file, 17 | name: path.basename(blobPath), 18 | size: stats.size, 19 | }); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/features/step_definitions/support/services/date.js: -------------------------------------------------------------------------------- 1 | import moment from 'moment'; 2 | 3 | global.moment = moment; 4 | global.dateFormat = 'LL'; 5 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/features/step_definitions/support/services/field_registry.js: -------------------------------------------------------------------------------- 1 | export default class FieldRegistry { 2 | constructor() { 3 | this._registry = {}; 4 | } 5 | 6 | contains(fieldType) { 7 | return fieldType in this._registry; 8 | } 9 | 10 | getValFunc(fieldType) { 11 | return this._registry[fieldType].getValue; 12 | } 13 | 14 | setValFunc(fieldType) { 15 | return this._registry[fieldType].setValue; 16 | } 17 | 18 | register(fieldType, getValFunc, setValFunc) { 19 | this._registry[fieldType] = { 20 | getValue: getValFunc, 21 | setValue: setValFunc, 22 | }; 23 | } 24 | 25 | unregister(fieldType) { 26 | delete this._registry[fieldType]; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/features/step_definitions/support/ui_config.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/no-extraneous-dependencies 2 | import { Before } from '@cucumber/cucumber'; 3 | 4 | Before((e) => { 5 | const { tags } = e.pickle; 6 | global.config = tags 7 | .map((tag) => { 8 | const res = tag.name.match(/@config\('(.*)','(.*)'\)/); 9 | return res && { key: res[1], value: res[2] }; 10 | }) 11 | .filter(Boolean); 12 | }); 13 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/features/step_definitions/ui.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/no-extraneous-dependencies 2 | import { Then, When } from '@cucumber/cucumber'; 3 | 4 | When('I click the {string} button', async function(button) { 5 | await driver.pause(1000); 6 | const drawer = await this.ui.drawer; 7 | const buttonToclick = await drawer.open(button); 8 | return buttonToclick; 9 | }); 10 | 11 | When('I select {string} from the View menu', async function(option) { 12 | const ui = await this.ui; 13 | return ui.view(option); 14 | }); 15 | When('I reload the page', async function() { 16 | // XXX temporary fix for async issue with activity feed; will be fixed when NXP-21771 is tackled 17 | await driver.pause(1000); 18 | await this.ui.reload(); 19 | await $('#logo').waitForVisible(); 20 | }); 21 | Then('I can see {string} in the Activity feed', async function(activity) { 22 | // XXX temporary fix for async issue with activity feed; will be fixed when NXP-21771 is tackled 23 | await driver.pause(10000); 24 | const activityFeed = await this.ui.activityFeed; 25 | await activityFeed.waitForVisible(); 26 | const activityTab = await activityFeed.getActivity(activity); 27 | const activityTabVisible = await activityTab.waitForVisible(); 28 | await activityTabVisible.should.be.true; 29 | }); 30 | Then('I click the blob download button', async function() { 31 | const page = await this.ui.browser.documentPage(this.doc.type); 32 | const button = await page.downloadButton; 33 | await button.click(); 34 | }); 35 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/features/step_definitions/video.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/no-extraneous-dependencies 2 | import { Then } from '@cucumber/cucumber'; 3 | 4 | Then('I can see the video conversions panel', async function() { 5 | const uiBrowser = await this.ui.browser; 6 | const page = await uiBrowser.documentPage(this.doc.type); 7 | page.waitForVisible(); 8 | const element = await page.el.$('nuxeo-video-conversions'); 9 | const elementVisible = await element.waitForVisible(); 10 | await elementVisible.should.be.true; 11 | }); 12 | 13 | Then('I can see the video storyboard', async function() { 14 | driver.waitUntil( 15 | async () => { 16 | const uiBrowser = await this.ui.browser; 17 | const page = await uiBrowser.documentPage(this.doc.type); 18 | if (!page.isVisible()) { 19 | return false; 20 | } 21 | const videoViewer = await page.el.element('nuxeo-video-viewer'); 22 | if (!videoViewer.isVisible()) { 23 | return false; 24 | } 25 | const storyBoard = await videoViewer.element('#storyboard'); 26 | const boardVisible = await storyBoard.isVisible(); 27 | if (boardVisible !== true) { 28 | await driver.execute(async () => Nuxeo.UI.app.refresh()); 29 | await driver.pause(1000); 30 | return false; 31 | } 32 | return true; 33 | }, 34 | { 35 | timeoutMsg: 'I cannot see the video storyboard', 36 | }, 37 | ); 38 | }); 39 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/pages/base.js: -------------------------------------------------------------------------------- 1 | export default class BasePage { 2 | constructor(selector) { 3 | this._selector = selector; 4 | } 5 | 6 | get el() { 7 | return $(this._selector); 8 | } 9 | 10 | click(...args) { 11 | return this.el.click(...args); 12 | } 13 | 14 | isVisible(...args) { 15 | return this.el.isVisible(...args); 16 | } 17 | 18 | waitForVisible(...args) { 19 | return this.el.waitForVisible(...args); 20 | } 21 | 22 | async waitForNotVisible(selector) { 23 | if (selector) { 24 | const ele = await this.el.$(...[selector].filter(Boolean).concat([browser.options.waitForTimeout, true])); 25 | const isSelectorVisible = await this.waitForVisible(ele); 26 | return isSelectorVisible; 27 | } 28 | return false; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/pages/helpers.js: -------------------------------------------------------------------------------- 1 | const _flushProperties = () => { 2 | driver.execute((conf) => { 3 | conf.forEach(({ key, value }) => Nuxeo.UI.config.set(key, value)); 4 | document.dispatchEvent(new CustomEvent('automation-ready')); 5 | }, global.config || []); 6 | }; 7 | 8 | const refresh = async () => { 9 | await driver.refresh(); 10 | await _flushProperties(); 11 | }; 12 | 13 | const url = async (...args) => { 14 | await driver.url(...args); 15 | _flushProperties(); 16 | }; 17 | 18 | const clickActionMenu = async (menu, selector) => { 19 | await menu.waitForExist(selector); 20 | const action = await menu.$(selector); 21 | await action.waitForExist(); 22 | if ((await action.getAttribute('show-label')) !== null) { 23 | // if the element is inside the dropdown, we need to expand it 24 | const myButton = await menu.$('#dropdownButton'); 25 | await myButton.click(); 26 | await menu.waitForVisible('paper-listbox'); 27 | await menu.waitForVisible('[slot="dropdown"] .label'); 28 | await menu.waitForEnabled('[slot="dropdown"] .label'); 29 | } 30 | const myClass = await action.$('.action'); 31 | await myClass.waitForVisible(); 32 | await myClass.waitForEnabled(); 33 | await myClass.click(); 34 | }; 35 | 36 | export { clickActionMenu, refresh, url }; 37 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/pages/login.js: -------------------------------------------------------------------------------- 1 | export default class Login { 2 | async username(username) { 3 | const inputUserName = await $('#username'); 4 | await inputUserName.setValue(username); 5 | } 6 | 7 | async password(password) { 8 | const inputPassword = await $('#password'); 9 | await inputPassword.setValue(password); 10 | } 11 | 12 | async submit() { 13 | const submitButton = await $('[name="Submit"]'); 14 | await submitButton.click(); 15 | } 16 | 17 | static get() { 18 | return (async () => { 19 | const baseUrl = process.env.NUXEO_URL || ''; 20 | await driver.pause(1000); 21 | await browser.url(baseUrl ? `${baseUrl}/logout` : 'logout'); 22 | await driver.pause(4000); 23 | return new this(); 24 | })(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/pages/ui/activity_feed.js: -------------------------------------------------------------------------------- 1 | import BasePage from '../base'; 2 | 3 | export default class ActivityFeed extends BasePage { 4 | async getActivity(activity) { 5 | await this.el.waitForExist('.value span'); 6 | const valueSpan = await this.el.$$('.value span').find(async (e) => { 7 | const currentText = await e.getText(); 8 | return currentText === activity; 9 | }); 10 | return valueSpan; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/pages/ui/admin/audit.js: -------------------------------------------------------------------------------- 1 | import BasePage from '../../base'; 2 | 3 | export default class Audit extends BasePage { 4 | get isAuditTableDisplayed() { 5 | return (async () => { 6 | const tableEl = this.el.$('#table').waitForDisplayed(); 7 | return tableEl; 8 | })(); 9 | } 10 | 11 | get isAuditTableFilled() { 12 | return (async () => { 13 | const element = await this.el; 14 | const tableRow = await element.$$('#table nuxeo-data-table-row'); 15 | return !( 16 | tableRow.some(async (row) => { 17 | const text = await row.getText(); 18 | return text.trim().length; 19 | }) === 0 20 | ); 21 | })(); 22 | } 23 | 24 | async waitForHasEntry(action, reverse) { 25 | const el = await this.el; 26 | await driver.waitUntil( 27 | async () => { 28 | const cells = await el.$$('#table nuxeo-data-table-cell'); 29 | if (reverse) { 30 | return cells.every(async (cell) => (await cell.getText()).trim() !== action); 31 | } 32 | return cells.some(async (cell) => (await cell.getText()).trim() === action); 33 | }, 34 | reverse ? 'The audit does have such entry' : 'The audit does not have such entry', 35 | { 36 | timeoutMsg: 'The audit does have such entry', 37 | }, 38 | ); 39 | return true; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/pages/ui/browser/add_to_collection_dialog.js: -------------------------------------------------------------------------------- 1 | import BasePage from '../../base'; 2 | 3 | export default class AddToCollectionDialog extends BasePage { 4 | async addToCollection(collectionName) { 5 | const collectionSelect = await this.el.$('#nxSelect'); 6 | await collectionSelect.waitForVisible(); 7 | await fixtures.layouts.setValue(collectionSelect, collectionName); 8 | await this.el.waitForEnabled('paper-button[name="add"]'); 9 | const addCollection = await this.el.$('paper-button[name = "add"]'); 10 | await addCollection.click(); 11 | } 12 | 13 | waitForVisible() { 14 | return this.el.waitForVisible(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/pages/ui/browser/collapsible_document_page.js: -------------------------------------------------------------------------------- 1 | import DocumentPage from './document_page'; 2 | 3 | export default class CollapsibleDocumentPage extends DocumentPage { 4 | constructor(selector, docType) { 5 | super(selector); 6 | this.docType = docType; 7 | } 8 | 9 | get detailsCard() { 10 | return this.el.element('#detailsCard'); 11 | } 12 | 13 | get metadata() { 14 | this.expandDetailsCard(); 15 | return super.metadata; 16 | } 17 | 18 | get versions() { 19 | this.expandDetailsCard(); 20 | return super.versions; 21 | } 22 | 23 | async expandDetailsCard() { 24 | const detailcardEle = await this.detailsCard; 25 | await detailcardEle.waitForVisible(); 26 | // XXX: getAttribute('opened') returns 'false' instead of null when the attribute is set to false, not sure why 27 | if (detailcardEle.getAttribute('opened') === 'false') { 28 | await detailcardEle.waitForVisible('h5.header'); 29 | await detailcardEle.click('h5.header'); 30 | } 31 | } 32 | 33 | collapseDetailsCard() { 34 | this.detailsCard.waitForVisible(); 35 | // XXX: getAttribute('opened') returns 'false' instead of null when the attribute is set to false, not sure why 36 | if (this.detailsCard.getAttribute('opened') !== 'false') { 37 | this.detailsCard.waitForVisible('h5.header'); 38 | this.detailsCard.click('h5.header'); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/pages/ui/browser/document_attachments.js: -------------------------------------------------------------------------------- 1 | import BasePage from '../../base'; 2 | 3 | export default class DocumentAttachments extends BasePage { 4 | constructor(selector, docType) { 5 | super(selector); 6 | this.docType = docType; 7 | } 8 | 9 | get previewButton() { 10 | return this.el.element('nuxeo-preview-button'); 11 | } 12 | 13 | get preview() { 14 | return this.el.element('nuxeo-document-preview'); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/pages/ui/browser/document_create.js: -------------------------------------------------------------------------------- 1 | import BasePage from '../../base'; 2 | import DocumentLayout from './document_layout'; 3 | 4 | export default class DocumentCreate extends BasePage { 5 | async getDoctypeButton(docType) { 6 | const typeSelection = await this.el.$(`div[name="typeSelection"] paper-button[name="${docType}"]`); 7 | return typeSelection; 8 | } 9 | 10 | layout(docType) { 11 | return new DocumentLayout(`nuxeo-${docType.toLowerCase()}-create-layout`); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/pages/ui/browser/document_form_layout.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-await-in-loop */ 2 | import BasePage from '../../base'; 3 | import DocumentLayout from './document_layout'; 4 | 5 | export default class DocumentFormLayout extends BasePage { 6 | constructor(selector, docType, layout) { 7 | super(selector); 8 | this._docType = docType; 9 | this._layout = layout; 10 | } 11 | 12 | set title(title) { 13 | return this.el.$('.input-element input').setValue(title); 14 | } 15 | 16 | get layout() { 17 | return new DocumentLayout(`nuxeo-${this._docType.toLowerCase()}-${this._layout}-layout`); 18 | } 19 | 20 | get errorMessages() { 21 | return (async () => { 22 | const errorElements = await this.el.elements('#error .error'); 23 | const errorTexts = []; 24 | for (let i = 0; i < errorElements.length; i++) { 25 | const errorElement = errorElements[i]; 26 | const errorText = await errorElement.getText(); 27 | errorTexts.push(errorText); 28 | } 29 | return errorTexts; 30 | })(); 31 | } 32 | 33 | async save() { 34 | const button = await this.el.element('.actions #save'); 35 | await button.waitForVisible(); 36 | await button.click(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/pages/ui/browser/document_layout.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-await-in-loop */ 2 | import BasePage from '../../base'; 3 | 4 | export default class DocumentLayout extends BasePage { 5 | async getField(field) { 6 | await driver.waitForExist(this._selector); 7 | const ele = await this.el; 8 | const result = await ele.$(`[name="${field}"]`); 9 | return result; 10 | } 11 | 12 | async getFieldValue(field) { 13 | const fieldEl = await this.getField(field); 14 | const finalFieldEle = await fixtures.layouts.getValue(fieldEl); 15 | return finalFieldEle; 16 | } 17 | 18 | async setFieldValue(field, value) { 19 | const fieldEl = await this.getField(field); 20 | await fieldEl.waitForVisible(); 21 | const result = await fixtures.layouts.setValue(fieldEl, value); 22 | return result; 23 | } 24 | 25 | async fillMultipleValues(table) { 26 | const rows = table.rows(); 27 | for (let i = 0; i < rows.length; i++) { 28 | const row = rows[i]; 29 | const fieldName = row[0]; 30 | const fieldEl = await this.getField(fieldName); 31 | await fieldEl.waitForVisible(); 32 | await fieldEl.scrollIntoView(); 33 | await fixtures.layouts.setValue(fieldEl, row[1]); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/pages/ui/browser/document_metadata.js: -------------------------------------------------------------------------------- 1 | import BasePage from '../../base'; 2 | import DocumentLayout from './document_layout'; 3 | import DocumentAttachments from './document_attachments'; 4 | 5 | export default class DocumentMetadata extends BasePage { 6 | constructor(selector, docType) { 7 | super(selector); 8 | this._docType = docType; 9 | } 10 | 11 | layout() { 12 | return new DocumentLayout(`nuxeo-${this._docType.toLowerCase()}-metadata-layout`); 13 | } 14 | 15 | get attachments() { 16 | return new DocumentAttachments('nuxeo-document-attachments', this.docType); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/pages/ui/browser/document_view.js: -------------------------------------------------------------------------------- 1 | import BasePage from '../../base'; 2 | import NoteEditor from '../note_editor'; 3 | 4 | export default class DocumentView extends BasePage { 5 | constructor(selector, docType) { 6 | super(selector); 7 | this.docType = docType; 8 | } 9 | 10 | get preview() { 11 | return this.el.element('nuxeo-document-preview'); 12 | } 13 | 14 | get layout() { 15 | return this.el.element(`nuxeo-${this.docType.toLowerCase()}-view-layout`); 16 | } 17 | 18 | get noteEditor() { 19 | return new NoteEditor('nuxeo-note-editor'); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/pages/ui/edit_doc.js: -------------------------------------------------------------------------------- 1 | import BasePage from '../base'; 2 | 3 | export default class EditDoc extends BasePage { 4 | submit() { 5 | this.el.waitForVisible('paper-button.primary'); 6 | this.el.element('paper-button.primary').click(); 7 | } 8 | 9 | editTitle(docType) { 10 | const doctype = docType.toLowerCase(); 11 | if (doctype === 'picture') { 12 | this.el.waitForVisible('input.nuxeo-file-edit'); 13 | this.el.setValue('input.nuxeo-file-edit', `New_Test_${docType}`); 14 | } else { 15 | this.el.waitForVisible(`input.nuxeo-${doctype}-edit`); 16 | this.el.setValue(`input.nuxeo-${doctype}-edit`, `New_Test_${docType}`); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/pages/ui/home.js: -------------------------------------------------------------------------------- 1 | import BasePage from '../base'; 2 | 3 | export default class Home extends BasePage { 4 | async card(contentId) { 5 | const cardEle = await this.el.element(`#${contentId}`); 6 | return cardEle; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/pages/ui/note_editor.js: -------------------------------------------------------------------------------- 1 | import BasePage from '../base'; 2 | 3 | export default class NoteEditor extends BasePage { 4 | setContent(content) { 5 | this.el.element('#editor').waitForVisible(); 6 | this.el.element('#editor').setValue(content); 7 | } 8 | 9 | get textarea() { 10 | return this.el.$('#textarea'); 11 | } 12 | 13 | get editButton() { 14 | return (async () => { 15 | const editButton = await this.el.element('#editNote'); 16 | return editButton; 17 | })(); 18 | } 19 | 20 | async hasContent(content) { 21 | const editor = await this.el.element('#editor'); 22 | await editor.waitForVisible(); 23 | await driver.waitUntil( 24 | async () => { 25 | try { 26 | const result = (await editor.getHTML(false)) === content; 27 | return result; 28 | } catch (e) { 29 | return false; 30 | } 31 | }, 32 | { 33 | timeoutMsg: 'The editor does not have such content', 34 | }, 35 | ); 36 | return true; 37 | } 38 | 39 | async edit() { 40 | const editButtonEle = await this.editButton; 41 | await editButtonEle.waitForVisible(); 42 | await editButtonEle.click(); 43 | } 44 | 45 | async save() { 46 | const button = await this.el.$('paper-button[name="editorSave"]'); 47 | await button.waitForVisible(); 48 | await button.click(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /packages/nuxeo-web-ui-ftest/pages/ui/tasks.js: -------------------------------------------------------------------------------- 1 | import BasePage from '../base'; 2 | 3 | export default class Tasks extends BasePage { 4 | get nbItems() { 5 | return (async () => { 6 | await driver.pause(2000); 7 | const items = await this.el.$$('#list .list-item'); 8 | let count = 0; 9 | for (let i = 0; i < items.length; i++) { 10 | // eslint-disable-next-line no-await-in-loop 11 | const item = await items[i].isVisible(); 12 | if (item) { 13 | count++; 14 | } 15 | } 16 | return count; 17 | })(); 18 | } 19 | 20 | get dashboardLink() { 21 | return this.el.element('.tasks-dashboard #link'); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /plugin/a11y/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "globals": { 3 | "$": true, 4 | "browser": true, 5 | "expect": true 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /plugin/a11y/README.md: -------------------------------------------------------------------------------- 1 | # Nuxeo Web UI - Accessibility 2 | 3 | This project runs automated accessibility tests on Nuxeo Web UI. 4 | 5 | ## Setup 6 | 7 | ``` 8 | npm install 9 | ``` 10 | 11 | ## Run tests 12 | 13 | To run the tests agains a running Nuxeo server: 14 | 15 | ``` 16 | npm run test 17 | ``` 18 | 19 | The server URL can be paremeterized using the `NUXEO_URL` environment variable. In case the instance of Web UI runs on 20 | a separate server, it can be configured using the `NUXEO_WEB_UI_URL` environment variable. E.g.: 21 | 22 | ``` 23 | NUXEO_WEB_UI_URL=http://localhost:5000/ NUXEO_URL=http://localhost:8080/nuxeo/ npm run test 24 | ``` 25 | 26 | The tests can be run in development mode, which assume a nuxeo server running locally (http://localhost:8080/nuxeo/) and 27 | Web UI being served in development mode from port 5000 (http://localhost:5000/): 28 | 29 | ``` 30 | npm run test:dev 31 | ``` 32 | 33 | You can also run a specific spec file, instead of running the whole suite: 34 | 35 | ``` 36 | npm run test -- --spec ./path/to/spec/file 37 | # or 38 | npm run test:dev -- --spec ./path/to/spec/file 39 | ``` 40 | -------------------------------------------------------------------------------- /plugin/a11y/a11y.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /plugin/a11y/getDriverVersion.js: -------------------------------------------------------------------------------- 1 | const { execSync } = require('child_process'); 2 | const chromeLauncher = require('chrome-launcher'); 3 | const fetch = require('node-fetch'); 4 | 5 | const chromePath = chromeLauncher.Launcher.getFirstInstallation(); 6 | let version; 7 | try { 8 | version = execSync(`"${chromePath}" --version`) 9 | .toString() 10 | .trim(); 11 | } catch (e) { 12 | console.error('unable to get Chrome version: ', e); 13 | } 14 | const match = version && version.match(/([0-9]+)\./); 15 | if (match) { 16 | const checkVersion = match[1]; 17 | // we will revert this once driver issue is resolved. 18 | try { 19 | fetch(`https://googlechromelabs.github.io/chrome-for-testing/LATEST_RELEASE_${checkVersion}`).then((response) => { 20 | if (response.ok) { 21 | return response 22 | .text() 23 | .then((newDriverVersion) => { 24 | // eslint-disable-next-line no-console 25 | console.log(newDriverVersion); 26 | }) 27 | .catch((e) => { 28 | console.error('unable to parse ChromeDriver version: ', e); 29 | }); 30 | } 31 | console.error('unable to fetch ChromeDriver version: ', response); 32 | }); 33 | } catch (e) { 34 | console.error('unable to fetch ChromeDriver version: ', e); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /plugin/a11y/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nuxeo/nuxeo-web-ui-a11y", 3 | "version": "1.0.0", 4 | "engines": { 5 | "node": ">=18.0.0" 6 | }, 7 | "scripts": { 8 | "start": "npm run test", 9 | "test": "HEADLESS=true wdio wdio.conf.js", 10 | "test:dev": "NUXEO_WEB_UI_URL=http://localhost:5000/ NUXEO_URL=http://localhost:8080/nuxeo/ wdio wdio.conf.js" 11 | }, 12 | "license": "Apache-2.0", 13 | "dependencies": { 14 | "@babel/core": "^7.15.0", 15 | "@babel/preset-env": "^7.15.0", 16 | "@babel/register": "^7.14.5", 17 | "@nuxeo/nuxeo-web-ui-ftest": "file:../../packages/nuxeo-web-ui-ftest", 18 | "@wdio/cli": "^8.16.11", 19 | "@wdio/local-runner": "^8.16.11", 20 | "@wdio/mocha-framework": "8.16.11", 21 | "@wdio/selenium-standalone-service": "^8.15.0", 22 | "@wdio/spec-reporter": "^8.16.9", 23 | "axe-core": "^4.1.2", 24 | "chrome-launcher": "0.15.2", 25 | "node-fetch": "^2.6.1", 26 | "wdio-chromedriver-service": "^8.1.1" 27 | } 28 | } -------------------------------------------------------------------------------- /plugin/a11y/test/axe-reporter.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/no-unresolved 2 | import { source } from 'axe-core'; 3 | 4 | class AxeCore { 5 | async run() { 6 | await browser.execute(source); 7 | const options = { 8 | runOnly: { 9 | type: 'tag', 10 | values: ['ACT', 'best-practice', 'wcag2a', 'wcag2aa'], 11 | }, 12 | }; 13 | // run inside browser and get results 14 | const results = await browser.executeAsync((opts, done) => { 15 | // eslint-disable-next-line no-undef 16 | axe 17 | .run(opts) 18 | .then((res) => done(res)) 19 | .catch((err) => { 20 | throw err; 21 | }); 22 | }, options); 23 | return this.process(await results); 24 | } 25 | 26 | process(results) { 27 | return { 28 | results, 29 | incomplete: results.incomplete.map((a) => { 30 | return { id: a.id, issues: a.nodes.length }; 31 | }), 32 | violations: results.violations.map((a) => { 33 | return { id: a.id, issues: a.nodes.length }; 34 | }), 35 | }; 36 | } 37 | } 38 | export async function runAxeCore() { 39 | return new AxeCore().run(); 40 | } 41 | -------------------------------------------------------------------------------- /plugin/a11y/test/helpers/login.js: -------------------------------------------------------------------------------- 1 | import Login from '@nuxeo/nuxeo-web-ui-ftest/pages/login'; 2 | import UI from '@nuxeo/nuxeo-web-ui-ftest/pages/ui'; 3 | 4 | const login = async (username = 'Administrator', password = 'Administrator') => { 5 | const logIn = await Login.get(); 6 | await logIn.username(username); 7 | await logIn.password(password); 8 | await logIn.submit(); 9 | const ui = await UI.get(); 10 | await ui.waitForVisible('nuxeo-page'); 11 | }; 12 | export default login; 13 | -------------------------------------------------------------------------------- /plugin/a11y/test/imports.js: -------------------------------------------------------------------------------- 1 | import '@nuxeo/nuxeo-web-ui-ftest/features/step_definitions/support/services/date'; 2 | -------------------------------------------------------------------------------- /plugin/a11y/test/specs/home.js: -------------------------------------------------------------------------------- 1 | import '../imports'; 2 | import documentService from '@nuxeo/nuxeo-web-ui-ftest/features/step_definitions/support/services/documentService'; 3 | import UI from '@nuxeo/nuxeo-web-ui-ftest/pages/ui'; 4 | import login from '../helpers/login'; 5 | import { reportA11y } from '../a11y-reporter.js'; 6 | 7 | const EXPECTED_VIOLATIONS = { 8 | 'aria-command-name': 1, 9 | 'aria-allowed-attr': 4, 10 | 'aria-tooltip-name': 1, 11 | 'landmark-one-main': 1, 12 | 'meta-viewport': 1, 13 | 'page-has-heading-one': 1, 14 | region: 10, 15 | 'nested-interactive': 15, 16 | }; 17 | 18 | const EXPECTED_INCOMPLETE_VIOLATIONS = { 19 | 'aria-allowed-role': 5, 20 | 'color-contrast-enhanced': 2, 21 | 'aria-required-children': 1, 22 | }; 23 | 24 | describe('Nuxeo Home', () => { 25 | before(async () => { 26 | let parent = documentService.init('Workspace', 'My Workspace'); 27 | parent = await documentService.create('/default-domain/workspaces', parent); 28 | const child = documentService.init(); 29 | await documentService.create(parent.path, child); 30 | }); 31 | 32 | reportA11y(EXPECTED_VIOLATIONS, EXPECTED_INCOMPLETE_VIOLATIONS, async () => { 33 | await login(); 34 | const ui = await UI.get(); 35 | const ele = await ui.home.el.$('nuxeo-card[icon="nuxeo:edit"]'); 36 | await ele.waitForDisplayed(); 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /plugin/itests/addon/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | 5 | org.nuxeo.web.ui 6 | nuxeo-web-ui-parent 7 | 3.1.20-SNAPSHOT 8 | ../../../pom.xml 9 | 10 | 11 | org.nuxeo.web.ui 12 | nuxeo-web-ui-itests 13 | Nuxeo Web UI - Web Application Sample for Functional tests 14 | 15 | A Nuxeo Web UI extension which provides doc types, schemas, etc. 16 | leveraging features not available in the default Web UI 17 | for functional testing purpose. 18 | 19 | 20 | 21 | 22 | org.nuxeo.ecm.core 23 | nuxeo-core-api 24 | 25 | 26 | org.nuxeo.ecm.core 27 | nuxeo-core-event 28 | 29 | 30 | -------------------------------------------------------------------------------- /plugin/itests/addon/src/main/resources/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Bundle-Vendor: Nuxeo 3 | Bundle-ActivationPolicy: lazy 4 | Bundle-ClassPath: . 5 | Bundle-Version: 1.0.0 6 | Bundle-Name: Nuxeo Web UI itests 7 | Nuxeo-Component: OSGI-INF/webui-itests-webresources-contrib.xml, 8 | OSGI-INF/extensions.xml 9 | Bundle-ManifestVersion: 2 10 | Bundle-SymbolicName: org.nuxeo.web.ui.itests;singleton:=true 11 | -------------------------------------------------------------------------------- /plugin/itests/addon/src/main/resources/OSGI-INF/deployment-fragment.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | org.nuxeo.web.ui 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /plugin/itests/addon/src/main/resources/OSGI-INF/webui-itests-webresources-contrib.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | /ui/nuxeo-itests.html 8 | 9 | 10 | 11 | 12 | 13 | 14 | nuxeo-itests.html 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /plugin/itests/addon/src/main/resources/data/i18n/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "label.document.type.docsuggestion": "DocSuggestion", 3 | "label.document.type.legacyfile": "Legacy File", 4 | "label.document.type.multistring": "MultiString", 5 | "label.document.type.multicomplex": "MultiComplex", 6 | "label.document.type.validation": "Validation", 7 | "label.schema.constraint.violation.PatternConstraint.validation.letterOnly": "'Letter Only' field can only contain letters", 8 | "sum.of.numbers.must.be.equal.ten": "Sum must be equal 10" 9 | } 10 | -------------------------------------------------------------------------------- /plugin/itests/addon/src/main/resources/web/nuxeo.war/ui/document/bulkedit/nuxeo-bulkedit-view-layout.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 15 | 16 | 28 | 29 | -------------------------------------------------------------------------------- /plugin/itests/addon/src/main/resources/web/nuxeo.war/ui/document/docsuggestion/nuxeo-docsuggestion-view-layout.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 15 | 16 | 30 | 31 | -------------------------------------------------------------------------------- /plugin/itests/addon/src/main/resources/web/nuxeo.war/ui/document/multicomplex/nuxeo-multicomplex-view-layout.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 15 | 16 | 30 | 31 | -------------------------------------------------------------------------------- /plugin/itests/addon/src/main/resources/web/nuxeo.war/ui/document/multistring/nuxeo-multistring-create-layout.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 33 | 34 | 48 | 49 | -------------------------------------------------------------------------------- /plugin/itests/addon/src/main/resources/web/nuxeo.war/ui/document/multistring/nuxeo-multistring-edit-layout.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 27 | 28 | 42 | 43 | -------------------------------------------------------------------------------- /plugin/itests/addon/src/main/resources/web/nuxeo.war/ui/document/multistring/nuxeo-multistring-metadata-layout.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 22 | 23 | 37 | 38 | -------------------------------------------------------------------------------- /plugin/itests/addon/src/main/resources/web/nuxeo.war/ui/document/multistring/nuxeo-multistring-view-layout.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 15 | 16 | 30 | 31 | -------------------------------------------------------------------------------- /plugin/itests/addon/src/main/resources/web/nuxeo.war/ui/document/validation/nuxeo-validation-metadata-layout.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | 11 | 25 | 26 | -------------------------------------------------------------------------------- /plugin/itests/addon/src/main/resources/web/nuxeo.war/ui/document/validation/nuxeo-validation-view-layout.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 15 | 16 | 30 | 31 | -------------------------------------------------------------------------------- /plugin/itests/addon/src/main/resources/web/nuxeo.war/ui/search/test_search/nuxeo-test_search-search-form.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 21 | 22 | 44 | 45 | -------------------------------------------------------------------------------- /plugin/itests/marketplace/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | org.nuxeo.web.ui 5 | nuxeo-web-ui-parent 6 | 3.1.20-SNAPSHOT 7 | ../../../pom.xml 8 | 9 | 10 | nuxeo-web-ui-marketplace-itests 11 | zip 12 | Nuxeo Web UI - Marketplace Package Sample for Functional tests 13 | 14 | 15 | 16 | org.nuxeo.web.ui 17 | nuxeo-web-ui-itests 18 | 19 | 20 | 21 | 22 | 23 | 24 | org.nuxeo.build 25 | ant-assembly-maven-plugin 26 | 27 | 28 | ${basedir}/src/main/assemble/assembly.xml 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /plugin/itests/marketplace/src/main/assemble/assembly.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /plugin/itests/marketplace/src/main/resources/install.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /plugin/itests/marketplace/src/main/resources/package.xml: -------------------------------------------------------------------------------- 1 | 2 | Nuxeo Web UI 3 | 4 |

Web UI sample extension for functional tests

5 |
6 | https://github.com/nuxeo/nuxeo-web-ui 7 | Nuxeo 8 | 9 | 10 | nuxeo_certified 11 | proto 12 | false 13 | 14 | @DISTRIBUTION_NAME@-@NUXEO_TARGET_VERSION@ 15 | 16 | 17 | nuxeo-web-ui 18 | 19 | Apache License, Version 2.0 20 | http://www.apache.org/licenses/LICENSE-2.0.html 21 | PRIVATE 22 |
23 | -------------------------------------------------------------------------------- /plugin/metrics/index.js: -------------------------------------------------------------------------------- 1 | const webdriverio = require('webdriverio'); 2 | const sauce = require('./lib/sauce.js'); 3 | const { capabilities } = require('./wdio.conf.js'); 4 | const fs = require('fs'); 5 | 6 | function bench() { 7 | var client = webdriverio.multiremote(capabilities); 8 | 9 | return client.init() 10 | .url('http://localhost:8080/nuxeo/ui') 11 | .setValue('#username', 'Administrator') 12 | .setValue('#password', 'Administrator') 13 | .click('[name="Submit"]') 14 | .waitUntil(() => client.execute(() => document.readyState === 'complete')) 15 | .pause(10000) // wait 10s before gathering all the metrics 16 | .execute(() => Nuxeo.Performance.report()) 17 | .then((data) => { 18 | let res = {}; 19 | Object.keys(data).forEach((browser) => { 20 | res[browser] = data[browser].value; 21 | }); 22 | fs.writeFileSync(`target/report/metrics.json`, JSON.stringify(res)); 23 | }) 24 | .end() 25 | .catch((err) => console.log(err)); 26 | } 27 | 28 | sauce.connect(capabilities) 29 | .then(bench) 30 | .then(() => sauce.close()) 31 | .catch((e) => console.error(e)); 32 | -------------------------------------------------------------------------------- /plugin/metrics/metrics.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /plugin/metrics/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nuxeo-web-ui-metrics", 3 | "version": "1.0.0", 4 | "scripts": { 5 | "start": "node ." 6 | }, 7 | "license": "Apache-2.0", 8 | "overrides": { 9 | "ws": "8.17.1" 10 | }, 11 | "dependencies": { 12 | "chalk": "^2.4.1", 13 | "cleankill": "^2.0.0", 14 | "sauce-connect-launcher": "^1.2.4", 15 | "uuid": "^3.3.2", 16 | "webdriverio": "^4.13.0" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /plugin/metrics/wdio.conf.js: -------------------------------------------------------------------------------- 1 | exports.capabilities = { 2 | chrome: { 3 | desiredCapabilities: { 4 | browserName: 'chrome', 5 | platform: 'Windows 10', 6 | version: '', 7 | } 8 | }, 9 | firefox: { 10 | desiredCapabilities: { 11 | browserName: 'firefox', 12 | platform: 'Windows 10', 13 | version: '', 14 | } 15 | }, 16 | safari: { 17 | desiredCapabilities: { 18 | browserName: 'safari', 19 | version: '', 20 | } 21 | }, 22 | edge: { 23 | desiredCapabilities: { 24 | browserName: 'microsoftedge', 25 | version: '' 26 | } 27 | } 28 | }; -------------------------------------------------------------------------------- /plugin/web-ui/addon/src/main/resources/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Bundle-Vendor: Nuxeo 3 | Nuxeo-RequiredBy: org.nuxeo.ecm.war 4 | Bundle-Version: 0.0.1 5 | Bundle-Name: Nuxeo Web UI 6 | Bundle-ManifestVersion: 1 7 | Bundle-SymbolicName: org.nuxeo.web.ui;singleton:=true 8 | Nuxeo-Component: OSGI-INF/auth-config.xml, 9 | OSGI-INF/actions-contrib.xml, 10 | OSGI-INF/login-startup-page-web-contrib.xml, 11 | OSGI-INF/url-codecs-web-contrib.xml, 12 | OSGI-INF/browser-cache-contrib.xml, 13 | OSGI-INF/web-ui-properties.xml 14 | -------------------------------------------------------------------------------- /plugin/web-ui/addon/src/main/resources/OSGI-INF/actions-contrib.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | MAIN_TABS 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /plugin/web-ui/addon/src/main/resources/OSGI-INF/auth-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ui 6 | repo 7 | 8 | 9 | 10 | 11 | 12 | 13 | ${org.nuxeo.ecm.contextPath}/ui/images/.* 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /plugin/web-ui/addon/src/main/resources/OSGI-INF/browser-cache-contrib.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | org.nuxeo.ecm.platform.web.common.requestcontroller.service.RequestControllerService.defaultContrib 5 | 6 | 8 | 9 | 10 | ${org.nuxeo.ecm.contextPath}/ui/.*\\?.*ts=.+ 11 | 12 | 13 | 14 | 15 | ${org.nuxeo.ecm.contextPath}/ui/.*\.(?!(html|js|jsp)$).* 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /plugin/web-ui/addon/src/main/resources/OSGI-INF/login-startup-page-web-contrib.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | ui/ 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /plugin/web-ui/addon/src/main/resources/OSGI-INF/url-codecs-web-contrib.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /plugin/web-ui/addon/src/test/resources/log4j2-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /plugin/web-ui/marketplace/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | org.nuxeo.web.ui 5 | nuxeo-web-ui-parent 6 | 3.1.20-SNAPSHOT 7 | ../../../pom.xml 8 | 9 | 10 | nuxeo-web-ui-marketplace 11 | zip 12 | Nuxeo Web UI - Marketplace Package 13 | 14 | 15 | ${project.version} 16 | 17 | 18 | 19 | 20 | org.nuxeo.web.ui 21 | nuxeo-web-ui 22 | 23 | 24 | 25 | 26 | 27 | 28 | org.nuxeo.build 29 | ant-assembly-maven-plugin 30 | 31 | 32 | ${basedir}/src/main/assemble/assembly.xml 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /plugin/web-ui/marketplace/src/main/resources/install.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /plugin/web-ui/marketplace/src/main/resources/package.xml: -------------------------------------------------------------------------------- 1 | 2 | Nuxeo Web UI 3 | 4 |

Web UI is the primary UI for the Nuxeo Platform. It is an ideal starting point for any Digital Asset Management, Case Management or Document Management project. 5 |

6 |
7 | https://github.com/nuxeo/nuxeo-web-ui 8 | Nuxeo 9 | 10 | 11 | nuxeo_certified 12 | production_ready 13 | true 14 | 15 | @DISTRIBUTION_NAME@ 16 | [2023.0,2025) 17 | 18 | Apache License, Version 2.0 19 | http://www.apache.org/licenses/LICENSE-2.0.html 20 | PUBLIC 21 |
22 | -------------------------------------------------------------------------------- /polymer.json: -------------------------------------------------------------------------------- 1 | { 2 | "entrypoint": "index.html", 3 | "lint": { 4 | "rules": ["polymer-3"] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = Object.assign(require('@open-wc/prettier-config'), { 2 | printWidth: 120, 3 | arrowParens: 'always', 4 | }); 5 | -------------------------------------------------------------------------------- /robots.txt: -------------------------------------------------------------------------------- 1 | # www.robotstxt.org 2 | 3 | User-agent: * 4 | Disallow: 5 | -------------------------------------------------------------------------------- /scripts/merge-messages.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const { mkdirSync, existsSync, writeFileSync } = require('fs'); 3 | const glob = require('glob'); 4 | 5 | const DEST = '.tmp/i18n'; 6 | const CWD = process.cwd(); 7 | 8 | mkdirSync(DEST, { recursive: true }); 9 | 10 | const BUNDLES = (process.env.NUXEO_PACKAGES || '') 11 | .split(/[\s,]+/) 12 | .filter(Boolean) 13 | .filter((p) => existsSync(`addons/${p}`)); 14 | 15 | const SOURCES = [...BUNDLES.map((b) => `addons/${b}/i18n`), 'node_modules/@nuxeo/nuxeo-ui-elements/i18n']; 16 | 17 | glob('i18n/messages*.json', (_, files) => 18 | files.forEach((file) => { 19 | const messages = require(`${CWD}/${file}`); 20 | const filename = path.basename(file); 21 | 22 | SOURCES.forEach((s) => { 23 | const p = `${CWD}/${s}/${filename}`; 24 | if (existsSync(p)) { 25 | Object.assign(messages, require(p)); 26 | } 27 | }); 28 | 29 | writeFileSync(`${DEST}/${filename}`, JSON.stringify(messages, null, 2)); 30 | }), 31 | ); 32 | -------------------------------------------------------------------------------- /scripts/test-runner.js: -------------------------------------------------------------------------------- 1 | const { spawnSync } = require('child_process'); 2 | const fs = require('fs'); 3 | const path = require('path'); 4 | const args = require('minimist')(process.argv.slice(2)); 5 | const { removeSync } = require('fs-extra'); 6 | 7 | // read .env file and assign to process.env 8 | require('dotenv').config(); 9 | 10 | const FTEST = path.join(__dirname, '../ftest'); 11 | 12 | function runFunctionalTests(project, dir) { 13 | if (!fs.existsSync(dir)) { 14 | console.warn(`The directory "${dir}" doesn't exist, no tests will run for "${project}".`); 15 | return; 16 | } 17 | console.info(`Starting Functional Tests for "${project}" on "${dir}" location.`); 18 | const ftestArgs = [...process.argv, '--cucumberReport', path.join(FTEST, 'target/cucumber-reports')]; 19 | const run = spawnSync('nuxeo-web-ui-ftest', ftestArgs, { cwd: dir, stdio: 'inherit' }); 20 | if (run.status !== 0) { 21 | console.error(`An error was returned by the process running the Functional Tests for "${project}".`); 22 | process.exit(run.status); 23 | } 24 | } 25 | 26 | if (fs.existsSync(path.join(FTEST, 'target/cucumber-reports')) && process.env.CUCUMBER_REPORT_PATH) { 27 | removeSync(process.env.CUCUMBER_REPORT_PATH); 28 | } 29 | 30 | if (!args.skipWebUi) { 31 | runFunctionalTests('WebUI', FTEST); 32 | } 33 | (process.env.NUXEO_PACKAGES || '') 34 | .split(/[\s,]+/) 35 | .filter(Boolean) 36 | .forEach((addon) => runFunctionalTests(addon, path.join(__dirname, `../addons/${addon}/ftest`))); 37 | -------------------------------------------------------------------------------- /server/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM docker.packages.nuxeo.com/nuxeo/nginx-centos7:0.0.1 2 | 3 | COPY nginx.conf /etc/nginx/nginx.conf -------------------------------------------------------------------------------- /server/nginx.conf: -------------------------------------------------------------------------------- 1 | worker_processes 1; 2 | 3 | events { 4 | worker_connections 1024; 5 | } 6 | 7 | http { 8 | server { 9 | listen 80; 10 | server_name localhost; 11 | 12 | root /ui; 13 | index index.html index.htm; 14 | include /etc/nginx/mime.types; 15 | 16 | gzip on; 17 | gzip_types application/javascript application/json text/css image/svg+xml image/png application/octet-stream; 18 | gzip_proxied no-cache no-store private expired auth; 19 | 20 | location / { 21 | try_files $uri $uri/ =404; 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /server/nginx.proxy.conf: -------------------------------------------------------------------------------- 1 | worker_processes 1; 2 | 3 | events { worker_connections 1024; } 4 | 5 | http { 6 | 7 | upstream ui_servers { 8 | server webui:80; 9 | # server webui_2:80; 10 | } 11 | 12 | upstream nuxeo_servers { 13 | server nuxeo_1:8080; 14 | # server nuxeo_2:8080; 15 | } 16 | 17 | server { 18 | listen 80; 19 | 20 | location / { 21 | proxy_set_header Host $host; 22 | proxy_set_header X-Real-IP $remote_addr; 23 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 24 | proxy_set_header X-Forwarded-Host $server_name; 25 | proxy_pass http://ui_servers/; 26 | } 27 | 28 | location /nuxeo/ { 29 | proxy_set_header Host $host; 30 | proxy_set_header X-Real-IP $remote_addr; 31 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 32 | proxy_set_header X-Forwarded-Host $server_name; 33 | proxy_set_header nuxeo-virtual-host "http://localhost:8080/"; 34 | proxy_pass http://nuxeo_servers; 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /sw.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-restricted-globals, no-return-await */ 2 | /* global importScripts, workbox */ 3 | importScripts('workbox/workbox-sw.js'); 4 | workbox.setConfig({ 5 | modulePathPrefix: 'workbox/', 6 | }); 7 | workbox.loadModule('workbox-routing'); 8 | workbox.loadModule('workbox-strategies'); 9 | 10 | const params = new URL(self.location.href).searchParams; 11 | if (params.has('ts')) { 12 | workbox.routing.registerRoute( 13 | ({ url, request }) => /\.*\.(html|js)$/.test(url) && request.headers.get('Content-Type') !== 'application/json', 14 | new workbox.strategies.NetworkFirst({ 15 | plugins: [ 16 | { 17 | requestWillFetch: async ({ request }) => 18 | new Request(`${request.url}?ts=${params.get('ts')}`, { credentials: 'same-origin' }), 19 | }, 20 | ], 21 | }), 22 | ); 23 | } 24 | 25 | self.addEventListener('install', () => { 26 | self.skipWaiting(); 27 | }); 28 | -------------------------------------------------------------------------------- /themes/dark/README.md: -------------------------------------------------------------------------------- 1 | All images, icons, fonts, and videos contained in this folder are copyrighted by Hyland Software, all rights reserved. 2 | -------------------------------------------------------------------------------- /themes/dark/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/themes/dark/logo.png -------------------------------------------------------------------------------- /themes/dark/preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/themes/dark/preview.jpg -------------------------------------------------------------------------------- /themes/default/README.md: -------------------------------------------------------------------------------- 1 | All images, icons, fonts, and videos contained in this folder are copyrighted by Hyland Software, all rights reserved. 2 | -------------------------------------------------------------------------------- /themes/default/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/themes/default/logo.png -------------------------------------------------------------------------------- /themes/default/preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/themes/default/preview.jpg -------------------------------------------------------------------------------- /themes/kawaii/README.md: -------------------------------------------------------------------------------- 1 | All images, icons, fonts, and videos contained in this folder are copyrighted by Hyland Software, all rights reserved. 2 | -------------------------------------------------------------------------------- /themes/kawaii/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/themes/kawaii/background.png -------------------------------------------------------------------------------- /themes/kawaii/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/themes/kawaii/logo.png -------------------------------------------------------------------------------- /themes/kawaii/preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/themes/kawaii/preview.jpg -------------------------------------------------------------------------------- /themes/light/README.md: -------------------------------------------------------------------------------- 1 | All images, icons, fonts, and videos contained in this folder are copyrighted by Hyland Software, all rights reserved. 2 | -------------------------------------------------------------------------------- /themes/light/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/themes/light/logo.png -------------------------------------------------------------------------------- /themes/light/preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuxeo/nuxeo-web-ui/8ea2215db9418bd2c65de76669b7d4f6da64afbb/themes/light/preview.jpg -------------------------------------------------------------------------------- /themes/loader.js: -------------------------------------------------------------------------------- 1 | /** 2 | @license 3 | ©2023 Hyland Software, Inc. and its affiliates. All rights reserved. 4 | All Hyland product names are registered or unregistered trademarks of Hyland Software, Inc. or its affiliates. 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | const url = `themes/${localStorage.getItem('theme') || 'default'}/theme.html`; 19 | const xhr = new XMLHttpRequest(); 20 | xhr.open('HEAD', url, false); 21 | xhr.onreadystatechange = function() { 22 | if (xhr.readyState === 4) { 23 | if (xhr.status === 404) { 24 | console.warn(`"${localStorage.getItem('theme')}" theme not found, fallback to "default".`); 25 | localStorage.setItem('theme', 'default'); 26 | } 27 | const link = document.createElement('link'); 28 | link.setAttribute('rel', 'import'); 29 | link.setAttribute('href', `themes/${localStorage.getItem('theme') || 'default'}/theme.html`); 30 | document.head.appendChild(link); 31 | } 32 | }; 33 | xhr.send(null); 34 | -------------------------------------------------------------------------------- /wct.conf.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | const rootPath = __dirname.split(path.sep).slice(-1)[0]; 4 | 5 | const mapping = {}; 6 | mapping[`/components/${rootPath}/app/bower_components`] = 'bower_components'; 7 | 8 | module.exports = { 9 | suites: ['test'], 10 | webserver: { 11 | pathMappings: [mapping], 12 | }, 13 | }; 14 | --------------------------------------------------------------------------------