Asset Selector Wrapper
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/examples/angular/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "extends": "./tsconfig.json",
4 | "compilerOptions": {
5 | "outDir": "./out-tsc/spec",
6 | "types": [
7 | "jasmine"
8 | ]
9 | },
10 | "files": [
11 | "src/test.ts",
12 | "src/polyfills.ts"
13 | ],
14 | "include": [
15 | "src/**/*.spec.ts",
16 | "src/**/*.d.ts"
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/examples/vanilla-js/destination-selector-integration/destination-selector-wrapper.css:
--------------------------------------------------------------------------------
1 | #integration-properties-guide-dialog {
2 | border: 0;
3 | border-radius: 4px;
4 | background-color: white;
5 | z-index: 99999;
6 | overflow: hidden;
7 | padding: 0;
8 | box-shadow: 0 0 10px 10px rgba(0, 0, 0, 0.1);
9 | }
10 |
11 | #destination-selector-dialog-content {
12 | display: flex;
13 | flex-direction: column;
14 | height: 100%;
15 | }
16 |
--------------------------------------------------------------------------------
/examples/vanilla-js/destination-selector-integration/destination-selector-wrapper.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Destination Selector Wrapper
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/examples/vanilla-js/asset-selector-integration/asset-selector-wrapper.css:
--------------------------------------------------------------------------------
1 | #integration-properties-guide-dialog {
2 | width: 80vw;
3 | height: 80vh;
4 | border: 0;
5 | border-radius: 4px;
6 | background-color: white;
7 | z-index: 99999;
8 | overflow: hidden;
9 | padding: 0;
10 | box-shadow: 0 0 10px 10px rgba(0, 0, 0, 0.1);
11 | }
12 |
13 | #asset-selector-dialog-content {
14 | display: flex;
15 | flex-direction: column;
16 | height: 100%;
17 | }
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Build Output folders
2 | **/dist
3 | **/lib
4 |
5 | # Documentation folders
6 | **/jsdocs
7 |
8 | # Dev and Build Dependencies
9 | **/node_modules
10 |
11 | # Files commonly generated by IDEs
12 | **/.idea
13 | **/.vscode
14 | **/.classpath
15 | **/.project
16 | **/.settings
17 | **/*.iml
18 |
19 | # Operating System Artifacts
20 | **/.DS_Store
21 |
22 | # Unit test coverage reports from intellij
23 | **/coverage
24 |
25 | # Other
26 | compilation-stats.json
27 | junit.xml
28 | .cache
29 | yarn-error.log
30 | .env
31 | .angular
--------------------------------------------------------------------------------
/examples/angular/src/app/app.component.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Adobe. All rights reserved.
3 | * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License. You may obtain a copy
5 | * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 | *
7 | * Unless required by applicable law or agreed to in writing, software distributed under
8 | * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 | * OF ANY KIND, either express or implied. See the License for the specific language
10 | * governing permissions and limitations under the License.
11 | */
--------------------------------------------------------------------------------
/examples/react/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "vite build",
9 | "preview": "vite preview"
10 | },
11 | "dependencies": {
12 | "@adobe/react-spectrum": "^3.25.1",
13 | "@spectrum-icons/workflow": "^4.1.0",
14 | "react": "^18.2.0",
15 | "react-code-blocks": "^0.0.9-0",
16 | "react-dom": "^18.2.0"
17 | },
18 | "devDependencies": {
19 | "@types/react": "^18.0.27",
20 | "@types/react-dom": "^18.0.10",
21 | "@vitejs/plugin-basic-ssl": "^1.0.1",
22 | "@vitejs/plugin-react": "^3.1.0",
23 | "vite": "^4.1.0"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ### Expected Behaviour
5 |
6 | ### Actual Behaviour
7 |
8 | ### Reproduce Scenario (including but not limited to)
9 |
10 | #### Steps to Reproduce
11 |
12 | #### Platform and Version
13 |
14 | #### Sample Code that illustrates the problem
15 |
16 | #### Logs taken while reproducing problem
--------------------------------------------------------------------------------
/examples/angular/src/environments/environment.ts:
--------------------------------------------------------------------------------
1 | // This file can be replaced during build by using the `fileReplacements` array.
2 | // `ng build` replaces `environment.ts` with `environment.prod.ts`.
3 | // The list of file replacements can be found in `angular.json`.
4 |
5 | export const environment = {
6 | production: false
7 | };
8 |
9 | /*
10 | * For easier debugging in development mode, you can import the following file
11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
12 | *
13 | * This import should be commented out in production mode because it will have a negative impact
14 | * on performance if an error is thrown.
15 | */
16 | // import 'zone.js/plugins/zone-error'; // Included with Angular CLI.
17 |
--------------------------------------------------------------------------------
/examples/angular/src/app/app.component.html:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
15 |
16 |
Assets Selectors - Angular
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/examples/react/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite';
2 | import react from '@vitejs/plugin-react';
3 | import basicSsl from '@vitejs/plugin-basic-ssl';
4 |
5 | // externals
6 | const externals = {
7 | react: 'React',
8 | 'react-dom': 'ReactDOM',
9 | '@assets/selectors':
10 | 'https://experience.adobe.com/solutions/CQ-assets-selectors/static-assets/resources/@assets/selectors/index.js',
11 | };
12 |
13 | // https://vitejs.dev/config/
14 | export default defineConfig({
15 | build: {
16 | rollupOptions: {
17 | external: Object.keys(externals),
18 | },
19 | },
20 | plugins: [react(), basicSsl()],
21 | server: {
22 | port: 8080,
23 | },
24 | define: {
25 | global: {},
26 | },
27 | resolve: {
28 | alias: {
29 | '@assets/selectors': externals['@assets/selectors'],
30 | },
31 | },
32 | });
33 |
--------------------------------------------------------------------------------
/examples/angular/src/test.ts:
--------------------------------------------------------------------------------
1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files
2 |
3 | import 'zone.js/testing';
4 | import { getTestBed } from '@angular/core/testing';
5 | import {
6 | BrowserDynamicTestingModule,
7 | platformBrowserDynamicTesting
8 | } from '@angular/platform-browser-dynamic/testing';
9 |
10 | declare const require: {
11 | context(path: string, deep?: boolean, filter?: RegExp): {
12 | (id: string): T;
13 | keys(): string[];
14 | };
15 | };
16 |
17 | // First, initialize the Angular testing environment.
18 | getTestBed().initTestEnvironment(
19 | BrowserDynamicTestingModule,
20 | platformBrowserDynamicTesting(),
21 | );
22 |
23 | // Then we find all the tests.
24 | const context = require.context('./', true, /\.spec\.ts$/);
25 | // And load the modules.
26 | context.keys().forEach(context);
27 |
--------------------------------------------------------------------------------
/examples/react/src/Main.jsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Adobe. All rights reserved.
3 | * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License. You may obtain a copy
5 | * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 | *
7 | * Unless required by applicable law or agreed to in writing, software distributed under
8 | * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 | * OF ANY KIND, either express or implied. See the License for the specific language
10 | * governing permissions and limitations under the License.
11 | */
12 |
13 | import React from 'react'
14 | import ReactDOM from 'react-dom/client'
15 | import App from './App'
16 |
17 | ReactDOM.createRoot(document.getElementById('root')).render(
18 |
19 |
20 | ,
21 | )
22 |
--------------------------------------------------------------------------------
/examples/angular/src/app/app-routing.module.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Adobe. All rights reserved.
3 | * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License. You may obtain a copy
5 | * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 | *
7 | * Unless required by applicable law or agreed to in writing, software distributed under
8 | * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 | * OF ANY KIND, either express or implied. See the License for the specific language
10 | * governing permissions and limitations under the License.
11 | */
12 |
13 | import { NgModule } from '@angular/core';
14 | import { RouterModule, Routes } from '@angular/router';
15 |
16 | const routes: Routes = [];
17 |
18 | @NgModule({
19 | imports: [RouterModule.forRoot(routes)],
20 | exports: [RouterModule]
21 | })
22 | export class AppRoutingModule { }
23 |
--------------------------------------------------------------------------------
/examples/react/src/App.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Adobe. All rights reserved.
3 | * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License. You may obtain a copy
5 | * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 | *
7 | * Unless required by applicable law or agreed to in writing, software distributed under
8 | * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 | * OF ANY KIND, either express or implied. See the License for the specific language
10 | * governing permissions and limitations under the License.
11 | */
12 |
13 | body{
14 | margin: 0;
15 | height: 100%;
16 | }
17 |
18 | .no-bullets{
19 | list-style-type: none;
20 | padding: 0px;
21 | }
22 |
23 | #root{
24 | padding: 0;
25 | margin: 0;
26 | }
27 |
28 | html {
29 | height: 100%;
30 | }
31 |
32 | .content-padding{
33 | padding: -2px;
34 | height: 100%;
35 | }
36 |
--------------------------------------------------------------------------------
/examples/angular/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Adobe. All rights reserved.
3 | * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License. You may obtain a copy
5 | * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 | *
7 | * Unless required by applicable law or agreed to in writing, software distributed under
8 | * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 | * OF ANY KIND, either express or implied. See the License for the specific language
10 | * governing permissions and limitations under the License.
11 | */
12 |
13 | import { Component, AfterViewInit } from '@angular/core';
14 | @Component({
15 | selector: 'app-root',
16 | templateUrl: './app.component.html',
17 | styleUrls: ['./app.component.css']
18 | })
19 | export class AppComponent implements AfterViewInit{
20 | title = 'angular';
21 | ngAfterViewInit() {
22 | console.log("angular after view init");
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/examples/vanilla-js/guide.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Adobe. All rights reserved.
3 | * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License. You may obtain a copy
5 | * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 | *
7 | * Unless required by applicable law or agreed to in writing, software distributed under
8 | * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 | * OF ANY KIND, either express or implied. See the License for the specific language
10 | * governing permissions and limitations under the License.
11 | */
12 |
13 | function onLoad() {
14 | const integrationGuideDialogCloseButton = document.getElementById("integration-guide-dialog-close-button");
15 | const integrationPropertiesGuideDialog = document.getElementById('integration-properties-guide-dialog');
16 |
17 | integrationGuideDialogCloseButton.addEventListener("click", () => {
18 | integrationPropertiesGuideDialog.close();
19 | });
20 | }
21 | onLoad();
--------------------------------------------------------------------------------
/examples/angular/src/main.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Adobe. All rights reserved.
3 | * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License. You may obtain a copy
5 | * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 | *
7 | * Unless required by applicable law or agreed to in writing, software distributed under
8 | * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 | * OF ANY KIND, either express or implied. See the License for the specific language
10 | * governing permissions and limitations under the License.
11 | */
12 |
13 | import { enableProdMode } from '@angular/core';
14 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
15 |
16 | import { AppModule } from './app/app.module';
17 | import { environment } from './environments/environment';
18 |
19 | if (environment.production) {
20 | enableProdMode();
21 | }
22 |
23 | platformBrowserDynamic().bootstrapModule(AppModule)
24 | .catch(err => console.error(err));
25 |
--------------------------------------------------------------------------------
/examples/angular/tsconfig.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "compileOnSave": false,
4 | "compilerOptions": {
5 | "baseUrl": "./",
6 | "outDir": "./dist/out-tsc",
7 | "forceConsistentCasingInFileNames": true,
8 | "strict": false,
9 | "noImplicitOverride": true,
10 | "noPropertyAccessFromIndexSignature": true,
11 | "noImplicitReturns": true,
12 | "noFallthroughCasesInSwitch": true,
13 | "sourceMap": true,
14 | "declaration": false,
15 | "downlevelIteration": true,
16 | "experimentalDecorators": true,
17 | "moduleResolution": "node",
18 | "importHelpers": true,
19 | "target": "es2020",
20 | "module": "es2020",
21 | "allowSyntheticDefaultImports": true,
22 | "esModuleInterop": true,
23 | "skipLibCheck": true,
24 | "lib": [
25 | "es2020",
26 | "dom"
27 | ]
28 | },
29 | "angularCompilerOptions": {
30 | "enableI18nLegacyMessageIdFormat": false,
31 | "strictInjectionParameters": true,
32 | "strictInputAccessModifiers": true,
33 | "strictTemplates": true
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/examples/angular/src/index.html:
--------------------------------------------------------------------------------
1 |
12 |
13 |
14 |
15 |
16 |
17 | Assets Selectors Example
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/examples/angular/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular",
3 | "version": "0.0.0",
4 | "scripts": {
5 | "ng": "ng",
6 | "start": "ng serve",
7 | "build": "ng build",
8 | "watch": "ng build --watch --configuration development",
9 | "test": "ng test"
10 | },
11 | "private": true,
12 | "dependencies": {
13 | "@adobe/react-spectrum": "^3.26.0",
14 | "@angular/animations": "^14.2.0",
15 | "@angular/cdk": "^14.2.6",
16 | "@angular/common": "^14.2.0",
17 | "@angular/compiler": "^14.2.0",
18 | "@angular/core": "^14.2.0",
19 | "@angular/forms": "^14.2.0",
20 | "@angular/material": "latest",
21 | "@angular/platform-browser": "^14.2.0",
22 | "@angular/platform-browser-dynamic": "^14.2.0",
23 | "@angular/router": "^14.2.0",
24 | "rxjs": "~7.5.0",
25 | "tslib": "^2.3.0",
26 | "zone.js": "~0.11.4"
27 | },
28 | "devDependencies": {
29 | "@angular-devkit/build-angular": "^14.2.7",
30 | "@angular/cli": "~14.2.7",
31 | "@angular/compiler-cli": "^14.2.0",
32 | "@types/jasmine": "~4.0.0",
33 | "jasmine-core": "~4.3.0",
34 | "karma": "~6.4.0",
35 | "karma-chrome-launcher": "~3.1.0",
36 | "karma-coverage": "~2.2.0",
37 | "karma-jasmine": "~5.1.0",
38 | "karma-jasmine-html-reporter": "~2.0.0",
39 | "typescript": "~4.7.2"
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/examples/angular/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Adobe. All rights reserved.
3 | * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License. You may obtain a copy
5 | * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 | *
7 | * Unless required by applicable law or agreed to in writing, software distributed under
8 | * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 | * OF ANY KIND, either express or implied. See the License for the specific language
10 | * governing permissions and limitations under the License.
11 | */
12 |
13 | import { NgModule } from '@angular/core';
14 | import { BrowserModule } from '@angular/platform-browser';
15 | import { CommonModule } from '@angular/common';
16 |
17 | import { AppRoutingModule } from './app-routing.module';
18 | import { AppComponent } from './app.component';
19 |
20 | import { AssetSelectorComponent } from 'src/app/asset-selector/asset-selector.component';
21 |
22 | @NgModule({
23 | declarations: [
24 | AppComponent,
25 | AssetSelectorComponent,
26 | ],
27 | imports: [
28 | CommonModule,
29 | BrowserModule,
30 | AppRoutingModule,
31 | ],
32 | providers: [],
33 | bootstrap: [AppComponent],
34 | exports: [AssetSelectorComponent]
35 | })
36 | export class AppModule { }
37 |
--------------------------------------------------------------------------------
/examples/react/index.html:
--------------------------------------------------------------------------------
1 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | Assets Selectors Consumer Example
19 |
20 |
21 |
22 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/examples/vanilla-js/asset-selector-integration/asset-selector-wrapper.js:
--------------------------------------------------------------------------------
1 | function init() {
2 | renderAssetSelectorWithAuthFlow();
3 | function renderAssetSelectorWithAuthFlow(props) {
4 | const defaultImsAuthInfo = window['assetsSelectorsAuthService'];
5 | const assetsSelectorsProps = {
6 | onClose: onClose,
7 | handleSelection: handleSelection,
8 | env: defaultImsAuthInfo.env === 'stg1' ? 'stage' : 'prod',
9 | imsOrg: defaultImsAuthInfo.imsOrg || null,
10 | };
11 |
12 | const container = document.getElementById(
13 | 'asset-selector-dialog-content'
14 | );
15 |
16 | PureJSSelectors.renderAssetSelectorWithAuthFlow(
17 | container,
18 | assetsSelectorsProps,
19 | () => {
20 | // callback function to be called after the asset selector is rendered
21 | }
22 | );
23 | }
24 |
25 | function onClose() {
26 | const integrationPropertiesGuideDialog = document.getElementById(
27 | 'integration-properties-guide-dialog'
28 | );
29 | integrationPropertiesGuideDialog.close();
30 | }
31 |
32 | async function handleSelection(assets) {
33 | const onAssetsSelectedEvent = new CustomEvent('onAssetsSelectedEvent', {
34 | detail: assets,
35 | });
36 |
37 | window.dispatchEvent(onAssetsSelectedEvent);
38 | }
39 | }
40 |
41 | init();
42 |
--------------------------------------------------------------------------------
/examples/vanilla-js/destination-selector-integration/destination-selector-wrapper.js:
--------------------------------------------------------------------------------
1 | function init() {
2 | renderDestinationSelectorWithAuthFlow();
3 | function renderDestinationSelectorWithAuthFlow(props) {
4 | const defaultImsAuthInfo = window['assetsSelectorsAuthService'];
5 | const destinationSelectorsProps = {
6 | onClose: onClose,
7 | onConfirm: onConfirm,
8 | env: defaultImsAuthInfo.env === 'stg1' ? 'stage' : 'prod',
9 | imsOrg: defaultImsAuthInfo.imsOrg || null,
10 | };
11 |
12 | const container = document.getElementById(
13 | 'destination-selector-dialog-content'
14 | );
15 |
16 | PureJSSelectors.renderDestinationSelectorWithAuthFlow(
17 | container,
18 | destinationSelectorsProps,
19 | () => {
20 | // callback function to be called after the asset selector is rendered
21 | }
22 | );
23 | }
24 |
25 | function onClose() {
26 | const integrationPropertiesGuideDialog = document.getElementById(
27 | 'integration-properties-guide-dialog'
28 | );
29 | integrationPropertiesGuideDialog.close();
30 | }
31 |
32 | async function onConfirm(destination) {
33 | const event = new CustomEvent('onDestinationSelectedEvent', {
34 | detail: destination,
35 | });
36 |
37 | window.dispatchEvent(event);
38 | }
39 | }
40 |
41 | init();
42 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Description
4 |
5 |
6 |
7 | ## Related Issue
8 |
9 |
10 |
11 |
12 |
13 |
14 | ## Motivation and Context
15 |
16 |
17 |
18 | ## Screenshots (if appropriate)
19 |
20 | ## Types of changes
21 |
22 |
23 |
24 | - [ ] Bug fix (non-breaking change which fixes an issue)
25 | - [ ] New feature (non-breaking change which adds functionality)
26 | - [ ] Breaking change (fix or feature that would cause existing functionality to change)
27 |
28 | ## Checklist
29 |
30 |
31 |
32 |
33 | - [ ] I have signed the [Adobe Open Source CLA](https://opensource.adobe.com/cla.html).
34 | - [ ] My code follows the code style of this project.
35 | - [ ] My change requires a change to the documentation.
36 | - [ ] I have updated the documentation accordingly.
37 | - [ ] I have read the **CONTRIBUTING** document.
38 |
--------------------------------------------------------------------------------
/docs/FilterFormProps.md:
--------------------------------------------------------------------------------
1 | # FilterFormProps Reference
2 |
3 | This document provides a formal reference for the `filterFormProps` property in Asset Selector, detailing its structure and supported properties.
4 |
5 | ## Overview
6 |
7 | The `filterFormProps` object configures the behavior of the filter form UI in Asset Selector.
8 |
9 | ## Type Definition
10 |
11 | The `FilterFormProps` interface has the following structure:
12 |
13 | ```typescript
14 | interface FilterFormProps {
15 | defaultExpanded?: string[];
16 | [key: string]: any;
17 | }
18 | ```
19 |
20 | ## Core Properties
21 |
22 | | Property | Type | Required | Default | Description |
23 | |----------|------|----------|---------|-------------|
24 | | `defaultExpanded` | string[] | No | [] | Array of `groupKey` strings that will be expanded by default when the filter UI renders |
25 |
26 | ## Usage Considerations
27 |
28 | 1. **Group Expansion**: The `defaultExpanded` property is the most commonly used property. It controls which filter groups are expanded when the filter UI is first rendered.
29 |
30 | 2. **Additional Properties**: The component may accept other configuration properties for advanced customization. These properties depend on the implementation and should be used with caution.
31 |
32 | ## Example
33 |
34 | ```typescript
35 | const filterFormProps = {
36 | defaultExpanded: ["FileTypeGroup", "MimeTypeGroup"]
37 | };
38 | ```
39 |
40 | This configuration will cause the filter groups with the keys "FileTypeGroup" and "MimeTypeGroup" to be expanded by default when the filter UI is rendered.
--------------------------------------------------------------------------------
/examples/react/src/App.jsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Adobe. All rights reserved.
3 | * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License. You may obtain a copy
5 | * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 | *
7 | * Unless required by applicable law or agreed to in writing, software distributed under
8 | * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 | * OF ANY KIND, either express or implied. See the License for the specific language
10 | * governing permissions and limitations under the License.
11 | */
12 |
13 | import './App.css';
14 | import {Provider, defaultTheme} from '@adobe/react-spectrum'
15 | import {useState} from 'react'
16 |
17 | import EnvironmentProvider from './EnvironmentProvider'
18 |
19 | import DesignerView from './Designer';
20 |
21 | function App() {
22 | let [selectedTheme, setTheme] = useState("light");
23 |
24 | const onThemeChange = () => {
25 | let selected = selectedTheme === "light" ? "dark" : "light";
26 | setTheme(selected);
27 | }
28 |
29 | return (
30 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | );
40 | }
41 |
42 | export default App;
--------------------------------------------------------------------------------
/examples/angular/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration file, see link for more information
2 | // https://karma-runner.github.io/1.0/config/configuration-file.html
3 |
4 | module.exports = function (config) {
5 | config.set({
6 | basePath: '',
7 | frameworks: ['jasmine', '@angular-devkit/build-angular'],
8 | plugins: [
9 | require('karma-jasmine'),
10 | require('karma-chrome-launcher'),
11 | require('karma-jasmine-html-reporter'),
12 | require('karma-coverage'),
13 | require('@angular-devkit/build-angular/plugins/karma')
14 | ],
15 | client: {
16 | jasmine: {
17 | // you can add configuration options for Jasmine here
18 | // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
19 | // for example, you can disable the random execution with `random: false`
20 | // or set a specific seed with `seed: 4321`
21 | },
22 | clearContext: false // leave Jasmine Spec Runner output visible in browser
23 | },
24 | jasmineHtmlReporter: {
25 | suppressAll: true // removes the duplicated traces
26 | },
27 | coverageReporter: {
28 | dir: require('path').join(__dirname, './coverage/angular'),
29 | subdir: '.',
30 | reporters: [
31 | { type: 'html' },
32 | { type: 'text-summary' }
33 | ]
34 | },
35 | reporters: ['progress', 'kjhtml'],
36 | port: 9876,
37 | colors: true,
38 | logLevel: config.LOG_INFO,
39 | autoWatch: true,
40 | browsers: ['Chrome'],
41 | singleRun: false,
42 | restartOnFileChange: true
43 | });
44 | };
45 |
--------------------------------------------------------------------------------
/examples/angular/src/app/app.component.spec.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Adobe. All rights reserved.
3 | * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License. You may obtain a copy
5 | * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 | *
7 | * Unless required by applicable law or agreed to in writing, software distributed under
8 | * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 | * OF ANY KIND, either express or implied. See the License for the specific language
10 | * governing permissions and limitations under the License.
11 | */
12 |
13 | import { TestBed } from '@angular/core/testing';
14 | import { RouterTestingModule } from '@angular/router/testing';
15 | import { AppComponent } from './app.component';
16 |
17 | describe('AppComponent', () => {
18 | beforeEach(async () => {
19 | await TestBed.configureTestingModule({
20 | imports: [
21 | RouterTestingModule
22 | ],
23 | declarations: [
24 | AppComponent
25 | ],
26 | }).compileComponents();
27 | });
28 |
29 | it('should create the app', () => {
30 | const fixture = TestBed.createComponent(AppComponent);
31 | const app = fixture.componentInstance;
32 | expect(app).toBeTruthy();
33 | });
34 |
35 | it(`should have as title 'angular'`, () => {
36 | const fixture = TestBed.createComponent(AppComponent);
37 | const app = fixture.componentInstance;
38 | expect(app.title).toEqual('angular');
39 | });
40 |
41 | it('should render title', () => {
42 | const fixture = TestBed.createComponent(AppComponent);
43 | fixture.detectChanges();
44 | const compiled = fixture.nativeElement as HTMLElement;
45 | expect(compiled.querySelector('.content span')?.textContent).toContain('angular app is running!');
46 | });
47 | });
48 |
--------------------------------------------------------------------------------
/examples/react/src/DestinationSelectorWrapper.jsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Adobe. All rights reserved.
3 | * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License. You may obtain a copy
5 | * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 | *
7 | * Unless required by applicable law or agreed to in writing, software distributed under
8 | * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 | * OF ANY KIND, either express or implied. See the License for the specific language
10 | * governing permissions and limitations under the License.
11 | */
12 |
13 | import React, { useContext } from 'react';
14 |
15 | import { useDialogContainer } from '@adobe/react-spectrum';
16 | import { DestinationSelectorWithAuthFlow } from '@assets/selectors';
17 | import { EnvironmentContext } from './EnvironmentProvider';
18 |
19 | export const DestinationSelectorWrapper = (props) => {
20 | const dialog = useDialogContainer();
21 | const { imsAuthInfo } = useContext(EnvironmentContext);
22 |
23 | const destinationSelectorsProps = {
24 | ...props,
25 | onClose: () => {
26 | dialog.dismiss?.();
27 | },
28 | onConfirm: (selectedDestination) => {
29 | props?.onConfirm(selectedDestination);
30 | dialog.dismiss?.();
31 | },
32 | env: imsAuthInfo.env,
33 | imsOrg: imsAuthInfo.imsOrg,
34 | };
35 |
36 | // DestinationSelectorWithAuthFlow adds authentication flow to DestinationSelector
37 | // If you already have an imsToken, you can use DestinationSelector directly instead
38 | return (
39 |
45 |
48 |
49 | );
50 | };
51 |
--------------------------------------------------------------------------------
/examples/angular/src/app/asset-selector/asset-selector.component.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Adobe. All rights reserved.
3 | * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License. You may obtain a copy
5 | * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 | *
7 | * Unless required by applicable law or agreed to in writing, software distributed under
8 | * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 | * OF ANY KIND, either express or implied. See the License for the specific language
10 | * governing permissions and limitations under the License.
11 | */
12 |
13 | import { Component, OnInit, AfterViewInit } from '@angular/core';
14 |
15 | @Component({
16 | selector: 'asset-selector',
17 | template: ''
18 | })
19 | export class AssetSelectorComponent implements OnInit, AfterViewInit {
20 | ngOnInit() {
21 | // 1. Register the Assets Selectors Auth Service on component load
22 | // Note: it is recommended that you call registerAssetsSelectorsAuthService before calling renderAssetSelectorWithAuthFlow
23 |
24 | const imsAuthProps = {
25 | imsClientId: '',
26 | imsScope: 'additional_info.projectedProductContext,openid,read_organizations',
27 | redirectUri: window.location.href
28 | };
29 | // @ts-ignore
30 | // make sure to add `declare const PureJSSelectors: any;` to your type declaration file
31 | PureJSSelectors.registerAssetsSelectorsAuthService(imsAuthProps);
32 | }
33 |
34 | handleSelection(assets) {
35 | console.log("Selected assets", assets)
36 | }
37 |
38 | ngAfterViewInit() {
39 | // 2. Render the AssetSelector component with built in auth flow
40 | const props = {
41 | imsOrg: "9D0725C05E44FE1A0A49411C@AdobeOrg",
42 | handleSelection: this.handleSelection,
43 | }
44 | // @ts-ignore
45 | PureJSSelectors.renderAssetSelectorWithAuthFlow(document.getElementById('asset-selector'), props);
46 | }
47 | }
--------------------------------------------------------------------------------
/examples/react/src/utils.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Adobe. All rights reserved.
3 | * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License. You may obtain a copy
5 | * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 | *
7 | * Unless required by applicable law or agreed to in writing, software distributed under
8 | * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 | * OF ANY KIND, either express or implied. See the License for the specific language
10 | * governing permissions and limitations under the License.
11 | */
12 |
13 | export const doFetch = (url, token = null, method = "GET") => {
14 | const header = new Headers();
15 | if(!token) {
16 | // get the bearer token either from window/wherever you are storing it from registerAssetsSelectorsAuthService
17 | header.append("Authorization", `Bearer ${window['assetsSelectorsAuthService'].imsToken}`);
18 | }
19 | const requestOptions = {
20 | method: method,
21 | headers: header,
22 | };
23 | return fetch(url, requestOptions);
24 | };
25 |
26 | // fetch the asset rendition and return the blob url
27 | export const getRenditionBlob = async (renditionUrl) => {
28 | const response = await doFetch(renditionUrl);
29 | const buffer = await response.arrayBuffer();
30 | return URL.createObjectURL(new Blob([new Uint8Array(buffer)]));
31 | };
32 |
33 | // Very basic way to get the optimal rendition link based on the height x width
34 | export const getOptimalRenditionLink = (renditions) => {
35 | return renditions.reduce((optimalRendition, currentRendition) => {
36 | const optimalResolution = optimalRendition.width * optimalRendition.height;
37 | const currentResolution = currentRendition.width * currentRendition.height;
38 | return currentResolution > optimalResolution ? currentRendition : optimalRendition;
39 | });
40 | }
41 |
42 | export const getAssetRenditionLinks = (selectedAssets) => {
43 | const asset = selectedAssets?.[0];
44 | return asset?._links?.['http://ns.adobe.com/adobecloud/rel/rendition'];
45 | };
--------------------------------------------------------------------------------
/examples/react/src/AssetSelectorWrapper.jsx:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright 2023 Adobe. All rights reserved.
4 | * This file is licensed to you under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License. You may obtain a copy
6 | * of the License at http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software distributed under
9 | * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
10 | * OF ANY KIND, either express or implied. See the License for the specific language
11 | * governing permissions and limitations under the License.
12 | */
13 |
14 | import React, {useContext } from "react";
15 |
16 | import { useDialogContainer } from "@adobe/react-spectrum";
17 | import { registerAssetsSelectorsAuthService as registerAssetsSelectorsAuthServiceInternal, AssetSelectorWithAuthFlow} from "@assets/selectors";
18 | import { EnvironmentContext } from "./EnvironmentProvider";
19 |
20 | export const registerAssetsSelectorsAuthService = (imsAuthProps, changeEnvironment = false) => {
21 | if(imsAuthProps){
22 | return registerAssetsSelectorsAuthServiceInternal(imsAuthProps, changeEnvironment);
23 | }
24 | };
25 |
26 | export const AssetSelectorWrapper = (props) => {
27 | const dialog = useDialogContainer();
28 | const { imsAuthInfo} = useContext(EnvironmentContext);
29 |
30 | const assetsSelectorsProps = {
31 | ...props,
32 | onClose: () => {
33 | dialog.dismiss?.();
34 | },
35 | handleSelection: (assets) => {
36 | props?.handleSelection(assets);
37 | },
38 | env: imsAuthInfo.env,
39 | imsOrg: imsAuthInfo.imsOrg,
40 | }
41 |
42 | // AssetSelectorWithAuthFlow adds authentication flow to AssetSelector
43 | // If you already have an imsToken, you can use AssetSelector directly instead
44 | return (
45 |
51 |
52 |
53 | );
54 | };
55 |
--------------------------------------------------------------------------------
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | Thanks for choosing to contribute!
4 |
5 | The following are a set of guidelines to follow when contributing to this project.
6 |
7 | ## Code Of Conduct
8 |
9 | This project adheres to the Adobe [code of conduct](../CODE_OF_CONDUCT.md). By participating,
10 | you are expected to uphold this code. Please report unacceptable behavior to
11 | [Grp-opensourceoffice@adobe.com](mailto:Grp-opensourceoffice@adobe.com).
12 |
13 | ## Have A Question?
14 |
15 | Start by filing an issue. The existing committers on this project work to reach
16 | consensus around project direction and issue solutions within issue threads
17 | (when appropriate).
18 |
19 | ## Contributor License Agreement
20 |
21 | All third-party contributions to this project must be accompanied by a signed contributor
22 | license agreement. This gives Adobe permission to redistribute your contributions
23 | as part of the project. [Sign our CLA](https://opensource.adobe.com/cla.html). You
24 | only need to submit an Adobe CLA one time, so if you have submitted one previously,
25 | you are good to go!
26 |
27 | ## Code Reviews
28 |
29 | All submissions should come in the form of pull requests and need to be reviewed
30 | by project committers. Read [GitHub's pull request documentation](https://help.github.com/articles/about-pull-requests/)
31 | for more information on sending pull requests.
32 |
33 | Lastly, please follow the [pull request template](PULL_REQUEST_TEMPLATE.md) when
34 | submitting a pull request!
35 |
36 | ## From Contributor To Committer
37 |
38 | We love contributions from our community! If you'd like to go a step beyond contributor
39 | and become a committer with full write access and a say in the project, you must
40 | be invited to the project. The existing committers employ an internal nomination
41 | process that must reach lazy consensus (silence is approval) before invitations
42 | are issued. If you feel you are qualified and want to get more deeply involved,
43 | feel free to reach out to existing committers to have a conversation about that.
44 |
45 | ## Security Issues
46 |
47 | Security issues shouldn't be reported on this issue tracker. Instead, [file an issue to our security experts](https://helpx.adobe.com/security/alertus.html).
--------------------------------------------------------------------------------
/examples/angular/README.md:
--------------------------------------------------------------------------------
1 | # Angular
2 |
3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 14.2.7.
4 |
5 | ## Pre-requisites
6 |
7 | :warning: This repository is intended to serve as a supplemental documentation describing the available APIs and usage examples for integrating Assets Selectors. Before attempting to install or use the Assets Selectors, ensure that your organization has been provisioned to access the Assets Selectors as part of the AEM Assets as a Cloud Service (CS) profile. If you have not been provisioned, you will not be able to successfully integrate or use these components. To request provisioning, your program admin should raise a support ticket marked as P2 from Admin Console and include the following information:
8 |
9 | - Program ID and Environment ID for the AEM CS instance
10 | - Domain names where the integrating application is hosted
11 |
12 | After provisioning, your organization will be provided with an `imsClientId`, `imsScope`, and a `redirectUrl` corresponding to the environment that you request —which are essential for the configuration of Assets Selectors to work end-to-end. Without those valid properties, you will not be able to run this example
13 |
14 | ---
15 |
16 | ## Development server
17 |
18 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files.
19 |
20 | ## Code scaffolding
21 |
22 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
23 |
24 | ## Build
25 |
26 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory.
27 |
28 | ## Running unit tests
29 |
30 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
31 |
32 | ## Running end-to-end tests
33 |
34 | Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities.
35 |
36 | ## Further help
37 |
38 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
39 |
--------------------------------------------------------------------------------
/docs/SelectedDestinationType.md:
--------------------------------------------------------------------------------
1 | # Selected Destination Type
2 |
3 | Selected Destination Type is an object that contains the details of the destination asset when using `onConfirm` `onItemSelect`, `onTreeToggleItem`, or `onTreeSelectionChange` functions. The following table describes some of the important properties of the Selected Destination object.
4 |
5 | | Property | Type | Explanation |
6 | |---------------------|----------------------------------|-----------------------------------------------------------------------|
7 | | *repo:repositoryId* | string | Unique identifier for the repository where the asset is stored. |
8 | | *repo:id* | string | Unique identifier for the asset. |
9 | | *repo:assetClass* | string | The classification of the asset (e.g., image, video, document). |
10 | | *repo:name* | string | The name of the asset, including the file extension. |
11 | | *repo:size* | number | The size of the asset in bytes. |
12 | | *repo:path* | string | The location of the asset within the repository. |
13 | | *repo:ancestors* | `Array` | An array of ancestor items for the asset in the repository. |
14 | | *repo:state* | string | Current state of the asset in the repository (e.g., active, deleted). |
15 | | *repo:createdBy* | string | The user or system that created the asset. |
16 | | *repo:createDate* | string | The date and time when the asset was created. |
17 | | *repo:modifiedBy* | string | The user or system that last modified the asset. |
18 | | *repo:modifyDate* | string | The date and time when the asset was last modified. |
19 | | *dc:format* | string | The format of the asset. |
20 | | *children* | `Array` | Assets that are available under the selected destination. |
21 |
--------------------------------------------------------------------------------
/examples/angular/src/polyfills.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This file includes polyfills needed by Angular and is loaded before the app.
3 | * You can add your own extra polyfills to this file.
4 | *
5 | * This file is divided into 2 sections:
6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main
8 | * file.
9 | *
10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
11 | * automatically update themselves. This includes recent versions of Safari, Chrome (including
12 | * Opera), Edge on the desktop, and iOS and Chrome on mobile.
13 | *
14 | * Learn more in https://angular.io/guide/browser-support
15 | */
16 |
17 | /***************************************************************************************************
18 | * BROWSER POLYFILLS
19 | */
20 |
21 | /**
22 | * By default, zone.js will patch all possible macroTask and DomEvents
23 | * user can disable parts of macroTask/DomEvents patch by setting following flags
24 | * because those flags need to be set before `zone.js` being loaded, and webpack
25 | * will put import in the top of bundle, so user need to create a separate file
26 | * in this directory (for example: zone-flags.ts), and put the following flags
27 | * into that file, and then add the following code before importing zone.js.
28 | * import './zone-flags';
29 | *
30 | * The flags allowed in zone-flags.ts are listed here.
31 | *
32 | * The following flags will work for all browsers.
33 | *
34 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
35 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
36 | * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
37 | *
38 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
39 | * with the following flag, it will bypass `zone.js` patch for IE/Edge
40 | *
41 | * (window as any).__Zone_enable_cross_context_check = true;
42 | *
43 | */
44 |
45 | /***************************************************************************************************
46 | * Zone JS is required by default for Angular itself.
47 | */
48 | import 'zone.js'; // Included with Angular CLI.
49 |
50 |
51 | /***************************************************************************************************
52 | * APPLICATION IMPORTS
53 | */
54 |
--------------------------------------------------------------------------------
/docs/ImsAuthService.md:
--------------------------------------------------------------------------------
1 | # ImsAuthService
2 |
3 | `ImsAuthService` class handles the authentication flow for the Asset Selector. It is responsible for obtaining an `imsToken` from the Adobe IMS authentication service. The `imsToken` is used to authenticate the user and authorize access to the Adobe Experience Manager (AEM) CS Assets repository. ImsAuthService uses the `ImsAuthProps` properties to control the authentication flow and register listeners for various authentication events. You can use the convenient [`registerAssetsSelectorsAuthService`](#purejsselectorsregisterassetsselectorsauthservice) function to register the _ImsAuthService_ instance with the Asset Selector. The following functions are available on the `ImsAuthService` class. However, if you're using the _registerAssetsSelectorsAuthService_ function, you do not need to call these functions directly.
4 |
5 | | Function Name | Description |
6 | |------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
7 | | `isSignedInUser` | Determines whether the user is currently signed in to the service and returns a boolean value accordingly. |
8 | | `getImsToken` | Retrieves the authentication `imsToken` for the currently signed-in user, which can be used to authenticate requests to other services such as generating asset _rendition._ |
9 | | `signIn` | Initiates the sign-in process for the user. This function uses the `ImsAuthProps` to show authentication in either a pop-up or a full page reload. |
10 | | `signOut` | Signs the user out of the service, invalidating their authentication token and requiring them to sign in again to access protected resources. Invoking this function will reload the current page. |
11 | | `refreshToken` | Refreshes the authentication token for the currently signed-in user, preventing it from expiring and ensuring uninterrupted access to protected resources. Returns a new authentication token that can be used for subsequent requests. |
12 |
--------------------------------------------------------------------------------
/examples/react/README.md:
--------------------------------------------------------------------------------
1 | ## README
2 |
3 | This example showcases how to integrate the AssetSelector in a React app.
4 |
5 | ### Launching the React Example
6 |
7 | :warning: This repository is intended to serve as a supplemental documentation describing the available APIs and usage examples for integrating Assets Selectors. Before attempting to install or use the Assets Selectors, ensure that your organization has been provisioned to access the Assets Selectors as part of the AEM Assets as a Cloud Service (CS) profile. If you have not been provisioned, you will not be able to successfully integrate or use these components. To request provisioning, your program admin should raise a support ticket marked as P2 from Admin Console and include the following information:
8 |
9 | - Program ID and Environment ID for the AEM CS instance
10 | - Domain names where the integrating application is hosted
11 |
12 | After provisioning, your organization will be provided with an `imsClientId`, `imsScope`, and a `redirectUrl` corresponding to the environment that you request —which are essential for the configuration of Assets Selectors to work end-to-end. Without those valid properties, you will not be able to run this example
13 |
14 | ---
15 |
16 | The React example app in the can be launched using the following steps:
17 |
18 | 1. Make sure you have `npm` or `yarn` installed on your system.
19 | 2. Install the dependencies
20 |
21 | ``` bash
22 | yarn install
23 | # OR
24 | npm install
25 | ```
26 |
27 | 3. Start the app:
28 |
29 | ``` bash
30 | yarn dev --host localhost
31 | # OR
32 | npm run dev --host localhost
33 | ```
34 |
35 | This will start a local HTTP server on port 8080.
36 | 4. Open a web browser and navigate to `http://localhost:8080` to view the app.
37 |
38 | ### Using the Web App
39 |
40 | 1. Once the app is launched, click on the "+ placeholder" button to launch the AssetSelector dialog with auth flow.
41 | 2. If the user is signed in, the AssetSelector dialog will be rendered.
42 | 3. If the user is not signed in, the app will open a popup/full page reload to prompt the user to sign in before accessing the AssetSelector dialog.
43 | - Note: By default, if the user is not signed in, we show a popup for the user to login. However, the popup must be enabled for this to work. Alternatively, you can check if the user's browser popup is disabled and instead trigger the full page reload to sign in. You can control that flow by passing the prop `modalMode: false` to `registerAssetsSelectorsAuthService`.
44 | 4. You can now select the desired assets, and the app will render your selected assets in place of the "+ placeholder" icon.
45 |
46 | ### View Deployed Example
47 |
48 | Visit the following URL to test out the deployed example that is showcased in [integration.html][selectors-vanillajs-demo]:
49 |
50 | [selectors-vanillajs-demo]: https://experience.adobe.com/solutions/CQ-assets-selectors/static-assets/resources/integration/integration.html
51 |
--------------------------------------------------------------------------------
/examples/vanilla-js/index.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Adobe. All rights reserved.
3 | * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License. You may obtain a copy
5 | * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 | *
7 | * Unless required by applicable law or agreed to in writing, software distributed under
8 | * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 | * OF ANY KIND, either express or implied. See the License for the specific language
10 | * governing permissions and limitations under the License.
11 | */
12 |
13 | body {
14 | font-family: Arial, Helvetica, sans-serif;
15 | font-size: 16px;
16 | background-color: #f3f3f3;
17 | }
18 | h3 {
19 | margin-top: 0;
20 | }
21 | .asset-selectors {
22 | padding: 20px;
23 | }
24 | #asset-selector-dialog {
25 | position: fixed;
26 | top: 30px;
27 | left: 30px;
28 | /* width: 100%; */
29 | height: 80%;
30 | border: 0;
31 | border-radius: 4px;
32 | background-color: white;
33 | z-index: 99999;
34 | overflow: hidden;
35 | padding: 0;
36 | margin: 0;
37 | box-shadow: 0 0 10px 10px rgba(0, 0, 0, 0.1);
38 | }
39 |
40 | #destination-selector-dialog {
41 | position: fixed;
42 | top: 30px;
43 | left: 30px;
44 | width: 640px;
45 | height: 700px;
46 | border: 0;
47 | border-radius: 4px;
48 | background-color: white;
49 | z-index: 99999;
50 | overflow: hidden;
51 | padding: 0;
52 | margin: 0;
53 | box-shadow: 0 0 10px 10px rgba(0, 0, 0, 0.1);
54 | }
55 |
56 | #asset-selector-dialog::backdrop,
57 | #destination-selector-dialog::backdrop {
58 | background-color: rgba(0, 0, 0, 0.5);
59 | }
60 | .asset-selectors {
61 | display: flex;
62 | flex-direction: column;
63 | align-items: center;
64 | justify-content: center;
65 | height: 100vh;
66 | width: 100vw;
67 | background: #f2f2f2;
68 | }
69 | .asset-selectors > div {
70 | margin-bottom: 20px;
71 | }
72 | .asset-selectors > div > button {
73 | padding: 10px 20px;
74 | font-size: 1.5em;
75 | background: #f2f2f2;
76 | border: 2px solid #000;
77 | }
78 | .asset-selectors > div > button:hover {
79 | background: #000;
80 | color: #fff;
81 | }
82 |
83 | html, body {
84 | height: 100%;
85 | width: 100%;
86 | margin: 0;
87 | padding: 0;
88 | font-family: Arial, Helvetica, sans-serif;
89 | font-size: 14px;
90 | }
91 |
92 | .asset-selectors {
93 | display: flex;
94 | flex-direction: column;
95 | align-items: center;
96 | justify-content: center;
97 | height: 100%;
98 | }
99 |
100 | .asset-selector-rail {
101 | height: 75vh;
102 | border-right: 1px solid #DDD;
103 | overflow-y: auto;
104 | overflow-x:hidden;
105 | width:30vh;
106 | }
107 |
108 | .dropzone {
109 | height: 75vh;
110 | background-color: aliceblue;
111 | display:none;
112 | text-align: center;
113 | list-style: inside;
114 | border: solid;
115 | flex-direction: column;
116 | justify-content: center;
117 | }
118 |
--------------------------------------------------------------------------------
/examples/vanilla-js/README.md:
--------------------------------------------------------------------------------
1 | ## JavaScript Example
2 |
3 | This example showcases how to integrate the AssetSelector in a JavaScript app.
4 |
5 | ### Launching the JavaScript App
6 |
7 | :warning: This repository is intended to serve as a supplemental documentation describing the available APIs and usage examples for integrating Assets Selectors. Before attempting to install or use the Assets Selectors, ensure that your organization has been provisioned to access the Assets Selectors as part of the AEM Assets as a Cloud Service (CS) profile. If you have not been provisioned, you will not be able to successfully integrate or use these components. To request provisioning, your program admin should raise a support ticket marked as P2 from Admin Console and include the following information:
8 |
9 | - Program ID and Environment ID for the AEM CS instance
10 | - Domain names where the integrating application is hosted
11 |
12 | After provisioning, your organization will be provided with an `imsClientId`, `imsScope`, and a `redirectUrl` corresponding to the environment that you request —which are essential for the configuration of Assets Selectors to work end-to-end. Without those valid properties, you will not be able to run this example
13 |
14 | ---
15 |
16 | The JavaScript app includes two different examples that you can use:
17 |
18 | 1. `index.html` - showcases a simple version of the AssetSelector example.
19 | 2. `integration.html` - showcases a complex end-to-end example of the AssetSelector.
20 |
21 | To launch the JavaScript app, follow these steps:
22 |
23 | 1. Make sure you have `npx` or `python` installed on your system.
24 | 2. Run the following command in your command line interface:
25 |
26 | ``` bash
27 | npx http-server -a localhost -p 8080
28 |
29 | # OR
30 | python -m http.server 8080
31 | ```
32 |
33 | This will start a local HTTP server on port 8080.
34 |
35 | 3. Open a web browser and navigate to `localhost:8080` to view the app.
36 |
37 | ### Using simple example (index.html)
38 |
39 | 1. Once the app is launched, click on the "Select Assets with Ims Flow" button to launch the AssetSelector dialog with built in auth flow.
40 | 2. If the user is signed in, the AssetSelector dialog will be rendered.
41 | 3. If the user is not signed in, the app will open a popup/full page reload to prompt the user to sign in before accessing the AssetSelectors dialog.
42 | - Note: By default, if the user is not signed in, we show a popup for the user to login. However, the popup must be enabled for this to work. Alternatively, you can check if the user's browser popup is disabled and instead trigger the full page reload to sign in. You can control that flow by passing the prop `modalMode: false` to `registerAssetsSelectorsAuthService`.
43 | 4. You can now select the desired assets, and the app will save your selected assets.
44 |
45 | ### Using complex example (integration.html)
46 |
47 | 1. Once the app is launched, navigate to [`integration.html`](https://localhost:8080:integration.html) to view the end-to-end integration example.
48 | 2. Click on the "+ placeholder" button to launch the AssetSelector dialog with built in auth flow.
49 | 3. If the user is signed in, the AssetSelector dialog will be rendered with assets.
50 | 4. When you select an asset, the app will render the selected asset.
51 |
52 | Visit the following URL to test out the deployed example that is showcased in [integration.html][selectors-vanillajs-demo]
53 |
54 | [selectors-vanillajs-demo]: https://experience.adobe.com/solutions/CQ-assets-selectors/static-assets/resources/integration/integration.html
55 |
--------------------------------------------------------------------------------
/examples/react/src/Settings.jsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Adobe. All rights reserved.
3 | * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License. You may obtain a copy
5 | * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 | *
7 | * Unless required by applicable law or agreed to in writing, software distributed under
8 | * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 | * OF ANY KIND, either express or implied. See the License for the specific language
10 | * governing permissions and limitations under the License.
11 | */
12 |
13 | import React, { useContext, useState, useEffect } from 'react';
14 | import {
15 | useDialogContainer,
16 | Dialog,
17 | Heading,
18 | Content,
19 | ButtonGroup,
20 | Button,
21 | Divider,
22 | RadioGroup,
23 | Radio,
24 | Form,
25 | TextField,
26 | Footer,
27 | } from '@adobe/react-spectrum';
28 |
29 | import { EnvironmentContext } from './EnvironmentProvider';
30 |
31 | export const Settings = () => {
32 | const dialog = useDialogContainer();
33 |
34 | const {
35 | environment,
36 | setEnvironment,
37 | imsAuthInfo,
38 | applyImsAuthChange,
39 | cancelImsAuthChange,
40 | signOut,
41 | } = useContext(EnvironmentContext);
42 | const [imsClientId, setImsClientId] = useState(imsAuthInfo.imsClientId);
43 | const [imsOrg, setImsOrg] = useState(imsAuthInfo.imsOrg);
44 |
45 | useEffect(() => {
46 | setImsClientId(imsAuthInfo.imsClientId);
47 | setImsOrg(imsAuthInfo.imsOrg);
48 | }, [imsAuthInfo]);
49 |
50 | const handleOnConfirm = () => {
51 | applyImsAuthChange({
52 | imsOrg,
53 | imsClientId,
54 | });
55 | dialog.dismiss();
56 | };
57 |
58 | const handleOnCancel = () => {
59 | cancelImsAuthChange();
60 | dialog.dismiss();
61 | };
62 |
63 | const handleSignOut = () => {
64 | signOut();
65 | dialog.dismiss();
66 | };
67 |
68 | return (
69 |
111 | );
112 | };
113 |
114 | export default Settings;
115 |
--------------------------------------------------------------------------------
/examples/angular/angular.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3 | "version": 1,
4 | "newProjectRoot": "projects",
5 | "projects": {
6 | "angular": {
7 | "projectType": "application",
8 | "schematics": {},
9 | "root": "",
10 | "sourceRoot": "src",
11 | "prefix": "app",
12 | "architect": {
13 | "build": {
14 | "builder": "@angular-devkit/build-angular:browser",
15 | "options": {
16 | "outputPath": "dist/angular",
17 | "index": "src/index.html",
18 | "main": "src/main.ts",
19 | "polyfills": "src/polyfills.ts",
20 | "tsConfig": "tsconfig.app.json",
21 | "assets": [
22 | "src/favicon.ico",
23 | "src/assets"
24 | ],
25 | "styles": [
26 | "src/styles.css",
27 | {
28 | "input": "./node_modules/@react-spectrum/theme-light/dist/main.css"
29 | }
30 | ],
31 | "scripts": [],
32 | "allowedCommonJsDependencies": [
33 | "@react-spectrum"
34 | ]
35 | },
36 | "configurations": {
37 | "production": {
38 | "budgets": [
39 | {
40 | "type": "initial",
41 | "maximumWarning": "500kb",
42 | "maximumError": "1mb"
43 | },
44 | {
45 | "type": "anyComponentStyle",
46 | "maximumWarning": "2kb",
47 | "maximumError": "4kb"
48 | }
49 | ],
50 | "fileReplacements": [
51 | {
52 | "replace": "src/environments/environment.ts",
53 | "with": "src/environments/environment.prod.ts"
54 | }
55 | ],
56 | "outputHashing": "all"
57 | },
58 | "development": {
59 | "buildOptimizer": false,
60 | "optimization": false,
61 | "vendorChunk": true,
62 | "extractLicenses": false,
63 | "sourceMap": true,
64 | "namedChunks": true
65 | }
66 | },
67 | "defaultConfiguration": "production"
68 | },
69 | "serve": {
70 | "builder": "@angular-devkit/build-angular:dev-server",
71 | "configurations": {
72 | "production": {
73 | "browserTarget": "angular:build:production"
74 | },
75 | "development": {
76 | "browserTarget": "angular:build:development"
77 | }
78 | },
79 | "defaultConfiguration": "development"
80 | },
81 | "extract-i18n": {
82 | "builder": "@angular-devkit/build-angular:extract-i18n",
83 | "options": {
84 | "browserTarget": "angular:build"
85 | }
86 | },
87 | "test": {
88 | "builder": "@angular-devkit/build-angular:karma",
89 | "options": {
90 | "main": "src/test.ts",
91 | "polyfills": "src/polyfills.ts",
92 | "tsConfig": "tsconfig.spec.json",
93 | "karmaConfig": "karma.conf.js",
94 | "assets": [
95 | "src/favicon.ico",
96 | "src/assets"
97 | ],
98 | "styles": [
99 | "src/styles.css"
100 | ],
101 | "scripts": []
102 | }
103 | }
104 | }
105 | }
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/examples/react/src/EnvironmentProvider.jsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Adobe. All rights reserved.
3 | * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License. You may obtain a copy
5 | * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 | *
7 | * Unless required by applicable law or agreed to in writing, software distributed under
8 | * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 | * OF ANY KIND, either express or implied. See the License for the specific language
10 | * governing permissions and limitations under the License.
11 | */
12 |
13 | import React, { useEffect, useState } from 'react';
14 |
15 | import { registerAssetsSelectorsAuthService } from './AssetSelectorWrapper';
16 |
17 | export const EnvironmentContext = React.createContext({});
18 |
19 | const stageImsClientId = '';
20 | const stageImsOrg = '9D0725C05E44FE1A0A49411C@AdobeOrg';
21 |
22 | const prodImsClientId = '';
23 | const prodImsOrg = '999F6D0B617C10B80A495E2E@AdobeOrg';
24 |
25 | const initImsAuthInfo = {
26 | env: 'prod',
27 | imsClientId: prodImsClientId,
28 | imsScope:
29 | 'AdobeID,openid,additional_info.projectedProductContext,read_organizations',
30 | redirectUrl: window.location.href,
31 | imsOrg: prodImsOrg,
32 | imsAuthService: undefined,
33 | };
34 |
35 | export const EnvironmentProvider = ({ children }) => {
36 | const [environment, setEnvironment] = useState('prod');
37 | const [imsAuthInfo, setImsAuthInfo] = useState(initImsAuthInfo);
38 |
39 | const applyImsAuthChange = (props) => {
40 | // update the token service
41 | // you can also access the tokenService from window.assetsSelectorsAuthService
42 | const tokenService = registerAssetsSelectorsAuthService(
43 | {
44 | ...imsAuthInfo,
45 | ...props,
46 | },
47 | true
48 | );
49 | setImsAuthInfo((prevInfo) => {
50 | return {
51 | ...prevInfo,
52 | ...props,
53 | imsAuthService: tokenService,
54 | };
55 | });
56 | };
57 |
58 | const cancelImsAuthChange = () => {
59 | setImsAuthInfo({
60 | ...initImsAuthInfo,
61 | });
62 | setEnvironment('prod');
63 | };
64 |
65 | const signOut = () => {
66 | const tokenService =
67 | imsAuthInfo?.imsAuthService || window.assetsSelectorsAuthService;
68 | tokenService.signOut();
69 | };
70 |
71 | useEffect(() => {
72 | setImsAuthInfo((prevInfo) => {
73 | if (environment === 'stage') {
74 | return {
75 | ...prevInfo,
76 | env: 'stage',
77 | imsClientId: stageImsClientId,
78 | imsOrg: stageImsOrg,
79 | };
80 | }
81 | return initImsAuthInfo;
82 | });
83 | }, [environment]);
84 |
85 | // you must register the token service before using the asset selector
86 | useEffect(() => {
87 | // you can also access the tokenService from window.assetsSelectorsAuthService
88 | const tokenService = registerAssetsSelectorsAuthService(imsAuthInfo);
89 | setImsAuthInfo((prevInfo) => {
90 | return {
91 | ...prevInfo,
92 | imsAuthService: tokenService,
93 | };
94 | });
95 | }, []);
96 |
97 | return (
98 |
109 | {children}
110 |
111 | );
112 | };
113 |
114 | export default EnvironmentProvider;
115 |
--------------------------------------------------------------------------------
/examples/react/src/svg/Placeholder.js:
--------------------------------------------------------------------------------
1 | /*************************************************************************
2 | * ADOBE CONFIDENTIAL
3 | * ___________________
4 | *
5 | * Copyright 2022 Adobe
6 | * All Rights Reserved.
7 | *
8 | * NOTICE: All information contained herein is, and remains
9 | * the property of Adobe and its suppliers, if any. The intellectual
10 | * and technical concepts contained herein are proprietary to Adobe
11 | * and its suppliers and are protected by all applicable intellectual
12 | * property laws, including trade secret and copyright laws.
13 | * Dissemination of this information or reproduction of this material
14 | * is strictly forbidden unless prior written permission is obtained
15 | * from Adobe.
16 | **************************************************************************/
17 | export default 'data:image/svg+xml;base64,PHN2ZyBkYXRhLW5hbWU9IkRlc2lnbiBmcm9tIHNjcmF0Y2giIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDEwMCA2NiI+PGcgZGF0YS1uYW1lPSJHcm91cCAxNzI1MzUiIGZpbGw9IiNiM2IzYjMiPjxwYXRoIGRhdGEtbmFtZT0iUGF0aCAxMDE5MTgiIGQ9Ik04OSA2NkgxOGE0IDQgMCAwIDEtNC00IDEgMSAwIDAgMSAxLTFoNzZhMSAxIDAgMCAxIDEgMSA0IDQgMCAwIDEtMyA0bS03My0zYTIgMiAwIDAgMCAyIDFoNzFhMiAyIDAgMCAwIDItMVoiLz48cGF0aCBkYXRhLW5hbWU9IlBhdGggMTAxOTE5IiBkPSJNMjMgNjFhMSAxIDAgMCAxLTEgMFYyNWEzIDMgMCAwIDEgMy0zaDU3YTMgMyAwIDAgMSAyIDN2NWExIDEgMCAxIDEtMSAwdi01YTEgMSAwIDAgMC0xLTFIMjVhMSAxIDAgMCAwLTEgMXYzNmExIDEgMCAwIDEtMSAwIi8+PHBhdGggZGF0YS1uYW1lPSJQYXRoIDEwMTkyMCIgZD0iTTgzIDYxVjQ2YTEgMSAwIDEgMSAxIDB2MTVhMSAxIDAgMCAxLTEgMCIvPjxwYXRoIGRhdGEtbmFtZT0iUGF0aCAxMDE5MjEiIGQ9Ik01MyA1MmExIDEgMCAwIDEtMS0xVjM2YTEgMSAwIDEgMSAyIDB2MTVhMSAxIDAgMCAxLTEgMSIvPjxwYXRoIGRhdGEtbmFtZT0iUGF0aCAxMDE5MjIiIGQ9Ik02MSA0NEg0NmExIDEgMCAwIDEgMC0yaDE1YTEgMSAwIDAgMSAwIDIiLz48cGF0aCBkYXRhLW5hbWU9IlBhdGggMTAxOTIzIiBkPSJNODkgNTNhMSAxIDAgMCAxLTEtMVY0MGExIDEgMCAwIDEgMS0xIDEgMSAwIDAgMSAxIDBsOSA5YTEgMSAwIDAgMSAwIDEgMSAxIDAgMCAxIDAgMSAxIDEgMCAwIDEtMSAwbC01LTEtMyA0YTEgMSAwIDAgMS0xIDBabTEtMTN2MTJsMi00YTEgMSAwIDAgMSAxIDBoNVoiLz48cGF0aCBkYXRhLW5hbWU9IlBhdGggMTAxOTI0IiBkPSJNODEgNDRhNSA1IDAgMCAxLTEtMTFsMTQtMWE1IDUgMCAwIDEgNCAxIDUgNSAwIDAgMS0yIDkgMSAxIDAgMCAxIDAtMSA0IDQgMCAwIDAgMS03IDQgNCAwIDAgMC0zLTFsLTEzIDFhNCA0IDAgMCAwIDAgOWw1LTFhMSAxIDAgMCAxIDAgMWwtNCAxYTUgNSAwIDAgMS0xIDAiLz48cGF0aCBkYXRhLW5hbWU9IlBhdGggMTAxOTI1IiBkPSJNNTYgMjBhMTAgMTAgMCAwIDEgMC0yYzAtNSA0LTggMTEtOGgzVjljMC0xIDAtNC01LTRhMTMgMTMgMCAwIDAtNiAxIDEgMSAwIDAgMS0xIDBWMmExNyAxNyAwIDAgMSA4LTJjNiAwIDkgNCA5IDEwdjEwYTEgMSAwIDEgMS0xIDBWMTBjMC02LTMtOS04LTlhMTYgMTYgMCAwIDAtNyAydjJhMTQgMTQgMCAwIDEgNi0xYzQgMCA2IDMgNiA1djFhMSAxIDAgMCAxIDAgMSAxIDEgMCAwIDEtMSAwaC0zYy02IDAtMTAgMy0xMCA3YTggOCAwIDAgMCAwIDIgMSAxIDAgMCAxLTEgMG0xNSAwYTEgMSAwIDAgMS0xIDB2LTZhMjMgMjMgMCAwIDAtMyAwYy0zIDAtNiAxLTYgNGE0IDQgMCAwIDAgMCAxIDEgMSAwIDAgMSAwIDEgMSAxIDAgMCAxLTEgMCA1IDUgMCAwIDEgMC0yYzAtMiAxLTUgNy01YTI0IDI0IDAgMCAxIDQgMCAxIDEgMCAwIDEgMCAxdjYiLz48cGF0aCBkYXRhLW5hbWU9IlBhdGggMTAxOTI2IiBkPSJNOSA0MWExIDEgMCAwIDEtMS0xTDAgMjVhMSAxIDAgMCAxIDAtMSAxIDEgMCAwIDEgMS0xbDMtMmExIDEgMCAwIDEgMSAwIDEgMSAwIDAgMSAwIDFsLTQgMiA4IDE1IDEwLTVhMSAxIDAgMCAxIDEgMCAxIDEgMCAwIDEgMCAxTDkgNDBhMSAxIDAgMCAxIDAgMSIvPjxwYXRoIGRhdGEtbmFtZT0iUGF0aCAxMDE5MjciIGQ9Ik05IDMyYTEgMSAwIDAgMS0xLTFMMyAxNGExIDEgMCAwIDEgMC0xIDEgMSAwIDAgMSAxIDBsMjUtN2ExIDEgMCAwIDEgMSAwbDQgMTRhMSAxIDAgMSAxLTEgMEwyOSA3IDQgMTRsNSAxNiAxMC0zYTEgMSAwIDAgMSAxIDAgMSAxIDAgMCAxIDAgMUw5IDMxYTEgMSAwIDAgMSAwIDEiLz48cGF0aCBkYXRhLW5hbWU9IlBhdGggMTAxOTI4IiBkPSJNMjYgMTVhMyAzIDAgMCAxLTMtMiAzIDMgMCAwIDEgMC0yIDMgMyAwIDAgMSAyLTEgMyAzIDAgMCAxIDIgMCAzIDMgMCAwIDEgMCA1IDMgMyAwIDAgMS0xIDBtMC00YTIgMiAwIDAgMC0yIDEgMiAyIDAgMCAwIDAgMSAyIDIgMCAwIDAgMiAxIDIgMiAwIDAgMCAxLTEgMiAyIDAgMCAwIDAtMiAyIDIgMCAwIDAtMSAwIi8+PHBhdGggZGF0YS1uYW1lPSJQYXRoIDEwMTkyOSIgZD0iTTIyIDIyYTEgMSAwIDAgMSAwLTFsMS0zYTIgMiAwIDAgMSAyLTFsNSAzYTEgMSAwIDAgMSAwIDEgMSAxIDAgMCAxLTEgMGwtNC0yaC0xbC0xIDNhMSAxIDAgMCAxLTEgMCIvPjxwYXRoIGRhdGEtbmFtZT0iUGF0aCAxMDE5MzAiIGQ9Ik05IDMwYTEgMSAwIDAgMSAwLTFsNi0xMWExIDEgMCAwIDEgMiAwbDUgM2ExIDEgMCAwIDEgMSAxIDEgMSAwIDAgMS0xIDBsLTYtMy02IDExYTEgMSAwIDAgMS0xIDAiLz48L2c+PC9zdmc+';
18 |
--------------------------------------------------------------------------------
/docs/ImsAuthProps.md:
--------------------------------------------------------------------------------
1 | # ImsAuthProps
2 |
3 | The `ImsAuthProps` properties define the authentication information and flow that the Asset Selector uses to obtain an `imsToken`. By setting these properties, you can control how the authentication flow should behave and register listeners for various authentication events.
4 |
5 | | Property Name | Description |
6 | |---------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
7 | | `imsClientId` | A string value representing the IMS client ID used for authentication purposes. This value is provided by Adobe and is specific to your Adobe AEM CS organization. |
8 | | `imsScope` | Describes the scopes used in authentication. The scopes determine the level of access that the application has to your organization resources. Multiple scopes can be separated by commas. |
9 | | `redirectUrl` | Represents the URL where the user is redirected after authentication. This value is typically set to the current URL of the application. If a `redirectUrl` is not supplied, `ImsAuthService` will use the redirectUrl used to register the `imsClientId` |
10 | | `modalMode` | A boolean indicating whether the authentication flow should be displayed in a modal (pop-up) or not. If set to `true`, the authentication flow is displayed in a pop-up. If set to `false`, the authentication flow is displayed in a full page reload. _Note:_ for better UX, you can dynamically control this value if the user has browser pop-up disabled. |
11 | | `onImsServiceInitialized` | A callback function that is called when the Adobe IMS authentication service is initialized. This function takes one parameter, `service`, which is an object representing the Adobe IMS service. See [`ImsAuthService`](#imsauthservice-ims-auth-service) for more details. |
12 | | `onAccessTokenReceived` | A callback function that is called when an `imsToken` is received from the Adobe IMS authentication service. This function takes one parameter, `imsToken`, which is a string representing the access token. |
13 | | `onAccessTokenExpired` | A callback function that is called when an access token has expired. This function is typically used to trigger a new authentication flow to obtain a new access token. |
14 | | `onErrorReceived` | A callback function that is called when an error occurs during authentication. This function takes two parameters: the error type and error message. The error type is a string representing the type of error and the error message is a string representing the error message. |
15 |
--------------------------------------------------------------------------------
/examples/vanilla-js/environment.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Adobe. All rights reserved.
3 | * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License. You may obtain a copy
5 | * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 | *
7 | * Unless required by applicable law or agreed to in writing, software distributed under
8 | * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 | * OF ANY KIND, either express or implied. See the License for the specific language
10 | * governing permissions and limitations under the License.
11 | */
12 |
13 | function init(){
14 |
15 | const environmentProperties = document.getElementById('environment-radio-group');
16 | const environmentPropertiesButtonSignOut = document.getElementById('environment-properties-button-signOut');
17 | const environmentPropertiesButtonConfirm = document.getElementById('environment-properties-button-confirm');
18 | const environmentPropertiesButtonCancel = document.getElementById('environment-properties-button-cancel');
19 |
20 | environmentProperties.addEventListener('change', onEnvironmentPropertiesChange);
21 | environmentPropertiesButtonSignOut.addEventListener('click', onSignOutClick);
22 | environmentPropertiesButtonConfirm.addEventListener('click', onConfirmClick);
23 | environmentPropertiesButtonCancel.addEventListener('click', onCancelClick);
24 | }
25 |
26 |
27 | function onEnvironmentPropertiesChange(event) {
28 |
29 | const stageImsClientId = "";
30 | const stageImsOrg = "9D0725C05E44FE1A0A49411C@AdobeOrg";
31 |
32 | const prodImsClientId = "";
33 | const prodImsOrg = "999F6D0B617C10B80A495E2E@AdobeOrg";
34 |
35 | const environmentPropertiesInputImsClientId = document.getElementById('environment-properties-input-ims-client-id');
36 | const environmentPropertiesInputImsOrgId = document.getElementById('environment-properties-input-ims-org-id');
37 | const environmentRadioItemProd = document.getElementById("environment-radio-group-prod");
38 | const environmentRadioItemStage = document.getElementById("environment-radio-group-stage");
39 |
40 | if(event.target.value === 'stage') {
41 | environmentPropertiesInputImsClientId.value = stageImsClientId;
42 | environmentPropertiesInputImsOrgId.value = stageImsOrg;
43 | environmentRadioItemStage.checked = true;
44 | } else {
45 | environmentRadioItemProd.checked = true;
46 | environmentPropertiesInputImsClientId.value = prodImsClientId;
47 | environmentPropertiesInputImsOrgId.value = prodImsOrg;
48 | };
49 | };
50 |
51 | function onConfirmClick() {
52 | const environmentPropertiesInputImsClientId = document.getElementById('environment-properties-input-ims-client-id');
53 | const environmentPropertiesInputImsOrgId = document.getElementById('environment-properties-input-ims-org-id');
54 | const environmentRadioItemStage = document.getElementById("environment-radio-group-stage");
55 |
56 | const initImsAuthInfo = {
57 | env: environmentRadioItemStage.checked ? "stage" : "prod",
58 | imsClientId: environmentPropertiesInputImsClientId.value,
59 | imsScope:
60 | "AdobeID,openid,additional_info.projectedProductContext,read_organizations",
61 | redirectUrl: window.location.href,
62 | imsOrg: environmentPropertiesInputImsOrgId.value,
63 | imsTokenService: undefined,
64 | };
65 |
66 | const environmentPropertiesEvent = new CustomEvent('environmentProperties', {
67 | detail: initImsAuthInfo
68 | });
69 |
70 | window.dispatchEvent(environmentPropertiesEvent);
71 | onCancelClick();
72 | }
73 |
74 | function onCancelClick() {
75 | const integrationPropertiesGuideDialog = document.getElementById('integration-properties-guide-dialog');
76 | integrationPropertiesGuideDialog.close();
77 | };
78 |
79 | function onSignOutClick() {
80 | window.assetsSelectorsAuthService && window.assetsSelectorsAuthService.signOut();
81 | onCancelClick();
82 | };
83 |
84 | init();
--------------------------------------------------------------------------------
/examples/react/src/Guide.jsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Adobe. All rights reserved.
3 | * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License. You may obtain a copy
5 | * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 | *
7 | * Unless required by applicable law or agreed to in writing, software distributed under
8 | * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 | * OF ANY KIND, either express or implied. See the License for the specific language
10 | * governing permissions and limitations under the License.
11 | */
12 |
13 | import React from "react";
14 | import {
15 | Dialog,
16 | Heading,
17 | Content,
18 | Divider,
19 | Text,
20 | View,
21 | } from "@adobe/react-spectrum";
22 |
23 | import { CodeBlock, dracula } from "react-code-blocks";
24 |
25 |
26 | const step1Code = `import { registerAssetsSelectorsAuthService, AssetSelectorWithAuthFlow } from "https://experience.adobe.com/solutions/CQ-assets-selectors/assets/resources/@assets/selectors"`
27 |
28 | const step2Code = `const imsAuthProps = {
29 | imsClientId: "",
30 | imsScope: "AdobeID,openid,additional_info.projectedProductContext,read_organizations",
31 | redirectUrl: window.location.href,
32 | };
33 | // must be called on page load
34 | registerAssetsSelectorsAuthService(imsAuthProps);
35 | `;
36 |
37 | const step3Code = `function App() {
38 | //selectedAssets returned with extensive asset metadata
39 | const [selectedAssets, setSelectedAssets] = useState([]);
40 |
41 | const onClose = () => {
42 | // Handle closing the AssetSelectorWithAuthFlow
43 | };
44 |
45 | return (
46 |
50 | );
51 | }
52 | `;
53 |
54 | export const Guide = () => {
55 | return (
56 |
109 | );
110 | };
111 |
112 | export default Guide;
113 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Adobe Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | We as members, contributors, and leaders pledge to make participation in our project and community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation.
6 |
7 | We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
8 |
9 | ## Our Standards
10 |
11 | Examples of behavior that contribute to a positive environment for our project and community include:
12 |
13 | * Demonstrating empathy and kindness toward other people
14 | * Being respectful of differing opinions, viewpoints, and experiences
15 | * Giving and gracefully accepting constructive feedback
16 | * Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
17 | * Focusing on what is best, not just for us as individuals but for the overall community
18 |
19 | Examples of unacceptable behavior include:
20 |
21 | * The use of sexualized language or imagery, and sexual attention or advances of any kind
22 | * Trolling, insulting or derogatory comments, and personal or political attacks
23 | * Public or private harassment
24 | * Publishing others’ private information, such as a physical or email address, without their explicit permission
25 | * Other conduct which could reasonably be considered inappropriate in a professional setting
26 |
27 | ## Our Responsibilities
28 |
29 | Project maintainers are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any instances of unacceptable behavior.
30 |
31 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for behaviors that they deem inappropriate, threatening, offensive, or harmful.
32 |
33 | ## Scope
34 |
35 | This Code of Conduct applies when an individual is representing the project or its community both within project spaces and in public spaces. Examples of representing a project or community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
36 |
37 | ## Enforcement
38 |
39 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by first contacting the project team. Oversight of Adobe projects is handled by the Adobe Open Source Office, which has final say in any violations and enforcement of this Code of Conduct and can be reached at Grp-opensourceoffice@adobe.com. All complaints will be reviewed and investigated promptly and fairly.
40 |
41 | The project team must respect the privacy and security of the reporter of any incident.
42 |
43 | Project maintainers who do not follow or enforce the Code of Conduct may face temporary or permanent repercussions as determined by other members of the project's leadership or the Adobe Open Source Office.
44 |
45 | ## Enforcement Guidelines
46 |
47 | Project maintainers will follow these Community Impact Guidelines in determining the consequences for any action they deem to be in violation of this Code of Conduct:
48 |
49 | **1. Correction**
50 |
51 | Community Impact: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.
52 |
53 | Consequence: A private, written warning from project maintainers describing the violation and why the behavior was unacceptable. A public apology may be requested from the violator before any further involvement in the project by violator.
54 |
55 | **2. Warning**
56 |
57 | Community Impact: A relatively minor violation through a single incident or series of actions.
58 |
59 | Consequence: A written warning from project maintainers that includes stated consequences for continued unacceptable behavior. Violator must refrain from interacting with the people involved for a specified period of time as determined by the project maintainers, including, but not limited to, unsolicited interaction with those enforcing the Code of Conduct through channels such as community spaces and social media. Continued violations may lead to a temporary or permanent ban.
60 |
61 | **3. Temporary Ban**
62 |
63 | Community Impact: A more serious violation of community standards, including sustained unacceptable behavior.
64 |
65 | Consequence: A temporary ban from any interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Failure to comply with the temporary ban may lead to a permanent ban.
66 |
67 | **4. Permanent Ban**
68 |
69 | Community Impact: Demonstrating a consistent pattern of violation of community standards or an egregious violation of community standards, including, but not limited to, sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
70 |
71 | Consequence: A permanent ban from any interaction with the community.
72 |
73 | ## Attribution
74 |
75 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.1,
76 | available at [http://contributor-covenant.org/version/2/1][version]
77 |
78 | [homepage]: http://contributor-covenant.org
79 | [version]: http://contributor-covenant.org/version/2/1
80 |
--------------------------------------------------------------------------------
/docs/FilterSchema.md:
--------------------------------------------------------------------------------
1 | # FilterSchema Reference
2 |
3 | This document provides a formal reference for the `filterSchema` property in Asset Selector, including all supported types, field properties, and their descriptions.
4 |
5 | ## Type Definitions
6 |
7 | ### FilterSchema
8 |
9 | The `filterSchema` is an array of `FilterGroup` objects:
10 |
11 | ```typescript
12 | type FilterSchema = FilterGroup[];
13 | ```
14 |
15 | ### FilterGroup
16 |
17 | Each `FilterGroup` represents a section of filters in the UI:
18 |
19 | | Property | Type | Required | Default | Description |
20 | |----------|------|----------|---------|-------------|
21 | | `header` | string | Yes | - | The display title of the filter group |
22 | | `groupKey` | string | Yes | - | Unique identifier for the group, used for referencing in `filterFormProps.defaultExpanded` |
23 | | `fields` | FilterField[] | Yes | - | Array of field definitions for this group |
24 |
25 | ### FilterField
26 |
27 | The `FilterField` type defines a single filter field:
28 |
29 | | Property | Type | Required | Default | Description |
30 | |----------|------|----------|---------|-------------|
31 | | `element` | string | Yes | - | Type of field. Valid values: "checkbox", "radiogroup", "Number", "taggroup" |
32 | | `name` | string | Yes | - | Parameter name used in filter queries |
33 | | `defaultValue` | DefaultValue | No | - | Pre-selected values when filter initializes |
34 | | `options` | FilterFieldOption[] | Yes (for checkbox/radiogroup) | - | Array of option objects for selection fields |
35 | | `orientation` | string | No | "horizontal" | Layout orientation. Valid values: "horizontal", "vertical" |
36 | | `columns` | number | No | 1 | Number of columns for layout |
37 | | `readOnly` | boolean | No | false | Makes the entire field read-only if true |
38 | | `excludeTags` | string[] | No | [] | Values to exclude from filtering |
39 | | `range` | boolean | No | false | For Number fields, enables min/max range selection |
40 | | `quiet` | boolean | No | false | For Number fields, applies a quieter visual style |
41 | | `label` | string | No | - | Display label for the field |
42 | | `hideArrows` | boolean | No | false | For Number fields, hides increment/decrement arrows |
43 | | `fieldType` | string | No | - | For taggroup, must be "tag-group" |
44 |
45 | ### FilterFieldOption
46 |
47 | Options used within checkbox and radiogroup fields:
48 |
49 | | Property | Type | Required | Default | Description |
50 | |----------|------|----------|---------|-------------|
51 | | `label` | string | Yes | - | Display text shown to users |
52 | | `value` | string | Yes | - | Value used in filter queries |
53 | | `readOnly` | boolean | No | false | Makes this specific option read-only |
54 | | `disabled` | boolean | No | false | Disables this specific option |
55 |
56 | ### DefaultValue
57 |
58 | The `defaultValue` type can take different forms depending on the field type:
59 |
60 | For checkbox/radiogroup fields:
61 | ```typescript
62 | type DefaultValue = string[];
63 | ```
64 |
65 | For Number fields with range:
66 | ```typescript
67 | type DefaultValueObject = {
68 | min?: number;
69 | max?: number;
70 | };
71 |
72 | type DefaultValue = DefaultValueObject[];
73 | ```
74 |
75 | For date range fields:
76 | ```typescript
77 | type DefaultValueDateRange = {
78 | start: string;
79 | end: string;
80 | };
81 |
82 | type DefaultValue = DefaultValueDateRange;
83 | ```
84 |
85 | ## Element Type-Specific Properties
86 |
87 | ### Checkbox Field
88 |
89 | A field with multiple selectable options.
90 |
91 | **Required Properties:**
92 | - `element`: "checkbox"
93 | - `name`: string
94 | - `options`: FilterFieldOption[]
95 |
96 | **Optional Properties:**
97 | - `defaultValue`: string[] - Array of pre-selected values
98 | - `orientation`: "horizontal" | "vertical"
99 | - `columns`: number
100 | - `readOnly`: boolean
101 | - `excludeTags`: string[]
102 |
103 | ### Radio Group Field
104 |
105 | A field with single selection from a list of options.
106 |
107 | **Required Properties:**
108 | - `element`: "radiogroup"
109 | - `name`: string
110 | - `options`: FilterFieldOption[]
111 |
112 | **Optional Properties:**
113 | - `defaultValue`: string[] - Array containing a single pre-selected value
114 | - `orientation`: "horizontal" | "vertical"
115 | - `excludeTags`: string[]
116 |
117 | ### Number Field
118 |
119 | A numeric input field, optionally with range selection.
120 |
121 | **Required Properties:**
122 | - `element`: "Number"
123 | - `name`: string
124 |
125 | **Optional Properties:**
126 | - `range`: boolean - Enables min/max range selection
127 | - `label`: string
128 | - `orientation`: "horizontal" | "vertical"
129 | - `quiet`: boolean
130 | - `hideArrows`: boolean
131 | - `columns`: number
132 | - `defaultValue`: DefaultValueObject[] - Default range values with min/max properties
133 |
134 | ### Tag Group Field
135 |
136 | A field for selecting tags from the AEM tag hierarchy.
137 |
138 | **Required Properties:**
139 | - `element`: "taggroup"
140 | - `name`: string (typically "property=xcm:keywords=")
141 | - `fieldType`: "tag-group"
142 |
143 | ## FilterSchema Example Shape
144 |
145 | ```typescript
146 | // Complete schema structure example
147 | const filterSchema: FilterSchema = [
148 | {
149 | header: string,
150 | groupKey: string,
151 | fields: [
152 | {
153 | element: "checkbox" | "radiogroup" | "Number" | "taggroup",
154 | name: string,
155 | defaultValue?: string[] | DefaultValueObject[] | DefaultValueDateRange,
156 | options?: FilterFieldOption[],
157 | orientation?: "horizontal" | "vertical",
158 | columns?: number,
159 | readOnly?: boolean,
160 | excludeTags?: string[],
161 | range?: boolean,
162 | quiet?: boolean,
163 | label?: string,
164 | hideArrows?: boolean,
165 | fieldType?: string
166 | }
167 | ]
168 | }
169 | ];
170 | ```
--------------------------------------------------------------------------------
/docs/SelectedAssetType.md:
--------------------------------------------------------------------------------
1 | # Selected Asset Type
2 |
3 | Selected Asset Type is an array of objects that contains the asset information when using the `handleSelection`, `handleAssetSelection`, or `onDrop` functions. The following table describes some of the important properties of the Selected Asset object.
4 |
5 | > You can find an example of the complete list of properties in [Selected Asset Type data file][asset-type-data-example].
6 |
7 | | Property | Type | Explanation |
8 | |---------------------------------------------------------------------|-----------------------|-------------------------------------------------------------------------------------------------------------------------------|
9 | | `repo:repositoryId` | string | Unique identifier for the repository where the asset is stored. |
10 | | `repo:id` | string | Unique identifier for the asset. |
11 | | `repo:assetClass` | string | The classification of the asset (e.g., image, video, document). |
12 | | `repo:name` | string | The name of the asset, including the file extension. |
13 | | `repo:size` | number | The size of the asset in bytes. |
14 | | `repo:path` | string | The location of the asset within the repository. |
15 | | `repo:ancestors` | `Array` | An array of ancestor items for the asset in the repository. |
16 | | `repo:state` | string | Current state of the asset in the repository (e.g., active, deleted). |
17 | | `repo:createdBy` | string | The user or system that created the asset. |
18 | | `repo:createDate` | string | The date and time when the asset was created. |
19 | | `repo:modifiedBy` | string | The user or system that last modified the asset. |
20 | | `repo:modifyDate` | string | The date and time when the asset was last modified. |
21 | | `dc:format` | string | The format of the asset, such as the file type (e.g., JPEG, PNG, etc.). |
22 | | `tiff:imageWidth` | number | The asset's width. |
23 | | `tiff:imageLength` | number | The asset's height. |
24 | | `computedMetadata` | `Record` | An object which represents a bucket for all the asset's metadata of all kinds (repository, application or embedded metadata). |
25 | | `_links` | `Record` | Represents hypermedia links for the associated asset. Includes links for resources such as metadata and renditions. |
26 | | `_links.http://ns.adobe.com/adobecloud/rel/rendition` | `Array