Skip to content

feat(ui5-upload-collection): implement new webcomponent #1316

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 47 commits into from
Apr 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
b4656a5
WIP(ui5-upload-collection): implement new webcomponent
dimovpetar Mar 19, 2020
911bb3f
add property "file" to UploadCollectionItem
dimovpetar Mar 19, 2020
eac9c13
remove icon and image properties and add thumbnail slot
dimovpetar Mar 19, 2020
106aa55
make file name clickable if property is set
dimovpetar Mar 19, 2020
34f352d
add withDnd property
dimovpetar Mar 20, 2020
eaa8df7
rename withDnd property to noDnd
dimovpetar Mar 20, 2020
aa7dda3
rename property deleteDisabled to noDelete
dimovpetar Mar 20, 2020
e6a4207
add edit functionality
dimovpetar Mar 23, 2020
eaa23d6
Merge branch 'master' of github.com:SAP/ui5-webcomponents into upload…
dimovpetar Mar 23, 2020
96c2ba0
add event listeners for drag and drop on the body only once
dimovpetar Mar 23, 2020
2690d0c
Merge branch 'master' of github.com:SAP/ui5-webcomponents into upload…
dimovpetar Mar 23, 2020
56a666f
make all texts translatable
dimovpetar Mar 23, 2020
7cdba4d
add missing css vars
dimovpetar Mar 24, 2020
cfda15b
make borders correct in belize_hcb/hcw
dimovpetar Mar 24, 2020
f7a16ee
added fileNameClick event on UploadCollectionItem
dimovpetar Mar 24, 2020
74331e0
add jsdoc and missing dependencies
dimovpetar Mar 24, 2020
1309612
move BodyDragAndDrop to fiori/src/upload-utils/BodyDragAndDrop.js
dimovpetar Mar 24, 2020
fbcaebe
combined noDnd with return statements for readability
dimovpetar Mar 24, 2020
0605ac4
fix BodyDragAndDrop import path and append file extension after edit
dimovpetar Mar 24, 2020
066232a
fix IE11 flex issues
dimovpetar Mar 24, 2020
6850bb0
improve _fileNameWithoutExtension method
dimovpetar Mar 24, 2020
594440d
use data-sap-focus-ref for focusing input
dimovpetar Mar 24, 2020
fd4c91d
add tests
dimovpetar Mar 25, 2020
f99c33e
rename uploadCollectionDemoHelper to uploadCollectionScript
dimovpetar Mar 25, 2020
797d145
use correct css vars for belize hcb/hcw
dimovpetar Mar 25, 2020
ae878d1
use correct css var for dnd icon and text
dimovpetar Mar 25, 2020
b6f3157
select input's text after edit button is pressed
dimovpetar Mar 25, 2020
72a56a8
implement design when media with is lower than 30rem
dimovpetar Mar 25, 2020
e2c4390
add progress indicator
dimovpetar Mar 26, 2020
2bc17ae
add tests for progress indicator
dimovpetar Mar 26, 2020
062b138
fix overflow issues
dimovpetar Mar 27, 2020
10eccec
make span for file extension inline-block
dimovpetar Mar 27, 2020
aa7a75e
add playground sample
dimovpetar Mar 27, 2020
3883c6d
Merge branch 'master' of github.com:SAP/ui5-webcomponents into upload…
dimovpetar Mar 27, 2020
f59fe6a
use @ui5/webcomponents-fiori messagebundle
dimovpetar Apr 1, 2020
99d0c20
subscribe UploadCollection's dnd listeners in the hbs
dimovpetar Apr 1, 2020
f052932
Merge branch 'master' of github.com:SAP/ui5-webcomponents into upload…
dimovpetar Apr 1, 2020
8b72a56
use publish-subscribe pattern for drag and drop events on the body
dimovpetar Apr 1, 2020
142a019
Merge branch 'master' of github.com:SAP/ui5-webcomponents into upload…
dimovpetar Apr 2, 2020
0cccd75
adopt global css vars
dimovpetar Apr 2, 2020
a1f7099
set correct opacities
dimovpetar Apr 2, 2020
e6edcdf
add missing jsdoc tags - defaultvalue, type, public
dimovpetar Apr 3, 2020
db596a8
consider hidden attribute
dimovpetar Apr 3, 2020
2eb644a
introduce base/util/getFileExtension and consider hidden files
dimovpetar Apr 3, 2020
43d2dfc
fix jsdoc typos and add new badge
dimovpetar Apr 3, 2020
ef5cd45
simplify playground sample
dimovpetar Apr 3, 2020
a1d2918
remove es6 from snippets in the playground
dimovpetar Apr 3, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions packages/base/src/util/getFileExtension.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* "" -> ""
* "noExtension" -> ""
* "file.txt" -> ".txt"
* "file.with.many.dots.doc" -> ".doc"
* ".gitignore" -> ""
*
* @param fileName - the file name
* @returns {string}
*/
const getFileExtension = fileName => {
const dotPos = fileName.lastIndexOf(".");

if (dotPos < 1) {
return "";
}

return fileName.slice(dotPos);
};

export default getFileExtension;
2 changes: 2 additions & 0 deletions packages/fiori/bundle.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ import ProductSwitch from "./dist/ProductSwitch.js";
import ProductSwitchItem from "./dist/ProductSwitchItem.js";
import ShellBar from "./dist/ShellBar.js";
import ShellBarItem from "./dist/ShellBarItem.js";
import UploadCollection from "./dist/UploadCollection.js";
import UploadCollectionItem from "./dist/UploadCollectionItem.js";
35 changes: 35 additions & 0 deletions packages/fiori/src/UploadCollection.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@

<div class="ui5-uc-root">
<div class="ui5-uc-header">
<slot name="header"></slot>
</div>
<div class="ui5-uc-content">
<ui5-list
mode="{{mode}}"
@ui5-selectionChange="{{_onSelectionChange}}"
@ui5-itemDelete="{{_onItemDelete}}"
>
<slot></slot>
</ui5-list>
{{#if _showNoData}}
<div class="uc-no-files">
<div class="icon-container">
<ui5-icon name="document"></ui5-icon>
</div>
<ui5-title level="H2">{{_noDataText}}</ui5-title>
<ui5-label class="subtitle">{{_noDataDescription}}</ui5-label>
</div>
{{else if _showDndOverlay}}
<div
class="{{classes.dndOverlay}}"
@dragenter="{{_ondragenter}}"
@dragleave="{{_ondragleave}}"
@dragover="{{_ondragover}}"
@drop="{{_ondrop}}"
>
<ui5-icon name="upload-to-cloud"></ui5-icon>
<span class="dnd-overlay-text">{{_dndOverlayText}}</span>
</div>
{{/if}}
</div>
</div>
319 changes: 319 additions & 0 deletions packages/fiori/src/UploadCollection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,319 @@
import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js";
import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js";
import { getI18nBundle, fetchI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js";
import Icon from "@ui5/webcomponents/dist/Icon.js";
import Label from "@ui5/webcomponents/dist/Label.js";
import List from "@ui5/webcomponents/dist/List.js";
import ListMode from "@ui5/webcomponents/dist/types/ListMode.js";
import Title from "@ui5/webcomponents/dist/Title.js";
import "@ui5/webcomponents-icons/dist/icons/upload-to-cloud.js";
import "@ui5/webcomponents-icons/dist/icons/document.js";
import {
UPLOADCOLLECTION_NO_DATA_TEXT,
UPLOADCOLLECTION_NO_DATA_DESCRIPTION,
UPLOADCOLLECTION_DRAG_FILE_INDICATOR,
UPLOADCOLLECTION_DROP_FILE_INDICATOR,
} from "./generated/i18n/i18n-defaults.js";
import {
attachBodyDnDHandler,
detachBodyDnDHandler,
draggingFiles,
} from "./upload-utils/UploadCollectionBodyDnD.js";
import UploadCollectionDnDOverlayMode from "./types/UploadCollectionDnDMode.js";

// Template
import UploadCollectionTemplate from "./generated/templates/UploadCollectionTemplate.lit.js";

// Styles
import UploadCollectionCss from "./generated/themes/UploadCollection.css.js";

/**
* @public
*/
const metadata = {
tag: "ui5-upload-collection",
properties: /** @lends sap.ui.webcomponents.fiori.UploadCollection.prototype */ {
/**
* Defines the mode of the <code>ui5-upload-collection</code>.
* <br><br>
* <b>Note:</b> Available options are <code>None</code>, <code>SingleSelect</code>,
* <code>MultiSelect</code>, and <code>Delete</code>.
*
* @type {ListMode}
* @defaultvalue "None"
* @public
*/
mode: {
type: ListMode,
defaultValue: ListMode.None,
},

/**
* Allows you to set your own text for the 'No data' description.
*
* @type {string}
* @defaultvalue ""
* @public
*/
noDataDescription: {
type: String,
},

/**
* Allows you to set your own text for the 'No data' text.
*
* @type {string}
* @defaultvalue ""
* @public
*/
noDataText: {
type: String,
},

/**
* By default there will be drag and drop overlay shown over the <code>ui5-upload-collection</code> when files
* are dragged. If you don't intend to use drag and drop, set this property to <code>true</code>
* <br><br>
* <b>Note:</b> It is up to the application developer to add handler for <code>drop</code> event and handle it.
* <code>ui5-upload-collection</code> only shows an overlay.
*
* @type {boolean}
* @defaultvalue false
* @public
*/
noDnd: {
type: Boolean,
},

/**
* Indicates what overlay to show when files are being dragged.
*
* @type {UploadCollectionDnDOverlayMode}
* @defaultvalue "None"
* @private
*/
_dndOverlayMode: {
type: String,
defaultValue: UploadCollectionDnDOverlayMode.None,
},
},
managedSlots: true,
slots: /** @lends sap.ui.webcomponents.fiori.UploadCollection.prototype */ {
/**
* Defines the items of the <code>ui5-upload-collection</code>.
* <br><b>Note:</b> Use <code>ui5-upload-collection-item</code> for the intended design.
*
* @type {HTMLElement[]}
* @slot
* @public
*/
"default": {
propertyName: "items",
type: HTMLElement,
},

/**
* Defines the <code>ui5-upload-collection</code> header.
*
* @type {HTMLElement[]}
* @slot
* @public
*/
header: {
type: HTMLElement,
},
},
events: /** @lends sap.ui.webcomponents.fiori.UploadCollection.prototype */ {
/**
* Fired when the Delete button of any item is pressed.
* <br><br>
* <b>Note:</b> A Delete button is displayed on each item,
* when the <code>ui5-upload-collection</code> <code>mode</code> property is set to <code>Delete</code>.
* @event
* @param {HTMLElement} item The <code>ui5-upload-collection-item</code> which was renamed.
* @public
*/
fileDeleted: {
detail: {
item: { type: HTMLElement },
},
},

/**
* Fired when selection is changed by user interaction
* in <code>SingleSelect</code> and <code>MultiSelect</code> modes.
*
* @event
* @param {Array} selectedItems An array of the selected items.
* @public
*/
selectionChange: {
detail: {
selectedItems: { type: Array },
},
},
},
};

/**
* @class
*
* <h3 class="comment-api-title">Overview</h3>
* This component allows you to represent files before uploading them to a server, with the help of <code>ui5-upload-collection-item</code>.
* It also allows you to show already uploaded files.
*
* <h3>ES6 Module Import</h3>
* <code>import @ui5/webcomponents-fiori/dist/UploadCollection.js";</code>
*
* @constructor
* @author SAP SE
* @alias sap.ui.webcomponents.fiori.UploadCollection
* @extends UI5Element
* @tagname ui5-upload-collection
* @appenddocs UploadCollectionItem
* @public
* @since 1.0.0-rc.7
*/
class UploadCollection extends UI5Element {
static get metadata() {
return metadata;
}

static get render() {
return litRender;
}

static get styles() {
return UploadCollectionCss;
}

static get template() {
return UploadCollectionTemplate;
}

static async onDefine() {
await Promise.all([
Icon.define(),
Label.define(),
List.define(),
Title.define(),
fetchI18nBundle("@ui5/webcomponents-fiori"),
]);
}

constructor() {
super();
this.i18nBundle = getI18nBundle("@ui5/webcomponents-fiori");
this._bodyDnDHandler = event => {
if (this._dndOverlayMode !== UploadCollectionDnDOverlayMode.Drop) {
this._dndOverlayMode = event.mode;
}
};
}

onEnterDOM() {
if (this.noDnd) {
return;
}

attachBodyDnDHandler(this._bodyDnDHandler);
}

onExitDOM() {
if (this.noDnd) {
return;
}

detachBodyDnDHandler(this._bodyDnDHandler);
}

_ondragenter(event) {
if (this.noDnd) {
return;
}

if (!draggingFiles(event)) {
return;
}

this._dndOverlayMode = UploadCollectionDnDOverlayMode.Drop;
}

_ondrop(event) {
if (this.noDnd) {
return;
}

this._dndOverlayMode = UploadCollectionDnDOverlayMode.None;
}

_ondragover(event) {
if (this.noDnd) {
return;
}

event.preventDefault();
}

_ondragleave(event) {
if (this.noDnd) {
return;
}

this._dndOverlayMode = UploadCollectionDnDOverlayMode.Drag;
}

_onItemDelete(event) {
this.fireEvent("fileDeleted", { item: event.detail.item });
}

_onSelectionChange(event) {
this.fireEvent("selectionChange", { selectedItems: event.detail.selectedItems });
}

get classes() {
return {
dndOverlay: {
"uc-dnd-overlay": true,
"uc-drag-overlay": this._dndOverlayMode === UploadCollectionDnDOverlayMode.Drag,
"uc-drop-overlay": this._dndOverlayMode === UploadCollectionDnDOverlayMode.Drop,
},
};
}

get _root() {
return this.shadowRoot.querySelector(".ui5-uc-root");
}

get _dndOverlay() {
return this._root.querySelector(".uc-dnd-overlay");
}

get _showDndOverlay() {
return this._dndOverlayMode !== UploadCollectionDnDOverlayMode.None;
}

get _showNoData() {
return this.items.length === 0 && !this._showDndOverlay;
}

get _noDataText() {
return this.noDataText || this.i18nBundle.getText(UPLOADCOLLECTION_NO_DATA_TEXT);
}

get _noDataDescription() {
return this.noDataDescription || this.i18nBundle.getText(UPLOADCOLLECTION_NO_DATA_DESCRIPTION);
}

get _dndOverlayText() {
if (this._dndOverlayMode === UploadCollectionDnDOverlayMode.Drag) {
return this.i18nBundle.getText(UPLOADCOLLECTION_DRAG_FILE_INDICATOR);
}

return this.i18nBundle.getText(UPLOADCOLLECTION_DROP_FILE_INDICATOR);
}
}

UploadCollection.define();

export default UploadCollection;
Loading