mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-22 06:30:59 +01:00
WIP VFS Select: split off dialog and made button its own component for easier backward compatability
This commit is contained in:
parent
23ec5ee796
commit
379729daff
@ -90,8 +90,9 @@ export function inputBasicTests(before : Function, test_value : string, value_se
|
||||
// Shows as empty / no value
|
||||
let value = (<Element><unknown>element).querySelector(value_selector) || (<Element><unknown>element).shadowRoot.querySelector(value_selector);
|
||||
assert.isDefined(value, "Bad value selector '" + value_selector + "'");
|
||||
assert.isNotNull(value, "Bad value selector '" + value_selector + "'");
|
||||
|
||||
assert.equal(value.textContent.trim(), "", "Displaying something when there is no value");
|
||||
assert.equal(value.innerText.trim(), "", "Displaying something when there is no value");
|
||||
if(element.multiple)
|
||||
{
|
||||
assert.isEmpty(element.get_value());
|
||||
|
@ -15,7 +15,7 @@ import {property} from "lit/decorators/property.js";
|
||||
import {state} from "lit/decorators/state.js";
|
||||
import {classMap} from "lit/directives/class-map.js";
|
||||
import {repeat} from "lit/directives/repeat.js";
|
||||
import {FileInfo} from "./Et2VfsSelect";
|
||||
import {FileInfo} from "./Et2VfsSelectDialog";
|
||||
import {SlBreadcrumbItem} from "@shoelace-style/shoelace";
|
||||
import {HasSlotController} from "../Et2Widget/slot";
|
||||
|
||||
|
154
api/js/etemplate/Et2Vfs/Et2VfsSelectButton.ts
Normal file
154
api/js/etemplate/Et2Vfs/Et2VfsSelectButton.ts
Normal file
@ -0,0 +1,154 @@
|
||||
/**
|
||||
* EGroupware eTemplate2 - Button to open a vfs select dialog
|
||||
*
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @package api
|
||||
* @link https://www.egroupware.org
|
||||
* @author Nathan Gray
|
||||
*/
|
||||
|
||||
import {Et2InputWidget} from "../Et2InputWidget/Et2InputWidget";
|
||||
import {html, LitElement, nothing} from "lit";
|
||||
import {HasSlotController} from "../Et2Widget/slot";
|
||||
import {property} from "lit/decorators/property.js";
|
||||
import {FileInfo} from "./Et2VfsSelectDialog";
|
||||
|
||||
/**
|
||||
* @summary Button to open a file selection dialog, and return the selected path(s) as a value
|
||||
* @since 23.1
|
||||
*
|
||||
* @dependency et2-vfs-select-dialog
|
||||
* @dependency et2-button
|
||||
*
|
||||
* @slot prefix - Before the toolbar
|
||||
* @slot suffix - Like prefix, but after
|
||||
*
|
||||
* @event change - Emitted when the control's value changes.
|
||||
*
|
||||
* @csspart form-control-input - The textbox's wrapper.
|
||||
* @csspart form-control-help-text - The help text's wrapper.
|
||||
* @csspart prefix - The container that wraps the prefix slot.
|
||||
* @csspart suffix - The container that wraps the suffix slot.
|
||||
*
|
||||
*/
|
||||
|
||||
export class Et2VfsSelectButton extends Et2InputWidget(LitElement)
|
||||
{
|
||||
/** Icon for the button */
|
||||
@property() image : string;
|
||||
|
||||
/** Currently selected files */
|
||||
@property() value : string[] | FileInfo[] = [];
|
||||
|
||||
/**
|
||||
* The dialog’s label as displayed in the header.
|
||||
* You should always include a relevant label, as it is required for proper accessibility.
|
||||
*/
|
||||
@property() title : string = "Select";
|
||||
|
||||
/**
|
||||
* Dialog mode
|
||||
* Quickly sets button label, multiple, selection and for "select-dir", mime-type
|
||||
**/
|
||||
@property({type: String}) mode : "open" | "open-multiple" | "saveas" | "select-dir";
|
||||
|
||||
/** Button label */
|
||||
@property({type: String}) buttonLabel : string = "Select";
|
||||
|
||||
/** Provide a suggested filename for saving */
|
||||
@property() filename : string = "";
|
||||
|
||||
/** Allow selecting multiple files */
|
||||
@property({type: Boolean}) multiple = false;
|
||||
|
||||
/** Start path in VFS. Leave unset to use the last used path. */
|
||||
@property() path : string = "";
|
||||
|
||||
/** Limit display to the given mime-type */
|
||||
@property() mime : string | string[] | RegExp = "";
|
||||
|
||||
/** Server side callback to process selected value(s) in
|
||||
* app.class.method or class::method format. The first parameter will
|
||||
* be Method ID, the second the file list. 'download' is reserved and it
|
||||
* means it should use download_baseUrl instead of path in value (no method
|
||||
* will be actually executed).
|
||||
*/
|
||||
@property() method : string = "";
|
||||
/** ID passed to method */
|
||||
@property() method_id : string;
|
||||
|
||||
protected readonly hasSlotController = new HasSlotController(this, '');
|
||||
|
||||
//private _dialog : Et2VfsSelectDialog = this.shadowRoot.querySelector("et2-vfs-select-dialog") ?? null;
|
||||
|
||||
constructor()
|
||||
{
|
||||
super();
|
||||
this.handleClick = this.handleClick.bind(this);
|
||||
this.handleDialogClose = this.handleDialogClose.bind(this);
|
||||
}
|
||||
|
||||
protected handleClick(event)
|
||||
{
|
||||
const dialog : any = this.shadowRoot.querySelector("et2-vfs-select-dialog");
|
||||
if(dialog && typeof dialog.show == "function")
|
||||
{
|
||||
dialog.show();
|
||||
}
|
||||
}
|
||||
|
||||
protected handleDialogClose(event)
|
||||
{
|
||||
debugger;
|
||||
this.value = dialog.value ?? [];
|
||||
|
||||
if(this.method && this.method == "download")
|
||||
{
|
||||
// download
|
||||
}
|
||||
else if(this.method)
|
||||
{
|
||||
this.sendFiles();
|
||||
}
|
||||
}
|
||||
|
||||
protected sendFiles()
|
||||
|
||||
protected dialogTemplate()
|
||||
{
|
||||
return html`
|
||||
<et2-vfs-select-dialog
|
||||
.title=${this.title ?? nothing}
|
||||
.value=${this.value ?? nothing}
|
||||
.mode=${this.mode ?? nothing}
|
||||
.multiple=${this.multiple ?? nothing}
|
||||
.path=${this.path ?? nothing}
|
||||
.filename=${this.filename ?? nothing}
|
||||
.mime=${this.mime ?? nothing}
|
||||
.buttonLabel=${this.buttonLabel ?? nothing}
|
||||
@close=${this.handleDialogClose}
|
||||
>
|
||||
|
||||
</et2-vfs-select-dialog>
|
||||
`;
|
||||
}
|
||||
|
||||
|
||||
render()
|
||||
{
|
||||
const hasUserDialog = this.hasSlotController.test("[default]");
|
||||
|
||||
return html`
|
||||
<et2-button image=${this.image || "filemanager/navbar"}
|
||||
?disabled=${this.disabled}
|
||||
?readonly=${this.readonly}
|
||||
.noSubmit=${true}
|
||||
@click=${this.handleClick}
|
||||
>
|
||||
</et2-button>
|
||||
<slot>${hasUserDialog ? nothing : this.dialogTemplate()}</slot>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("et2-vfs-select", Et2VfsSelectButton);
|
@ -23,6 +23,7 @@ import {HasSlotController} from "../Et2Widget/slot";
|
||||
import {IegwAppLocal} from "../../jsapi/egw_global";
|
||||
import {Et2Select} from "../Et2Select/Et2Select";
|
||||
import {Et2VfsSelectRow} from "./Et2VfsSelectRow";
|
||||
import {Et2VfsPath} from "./Et2VfsPath";
|
||||
|
||||
/**
|
||||
* @summary Select files (including directories) from the VFS
|
||||
@ -32,7 +33,7 @@ import {Et2VfsSelectRow} from "./Et2VfsSelectRow";
|
||||
* @dependency et2-select
|
||||
* @dependency et2-vfs-select-row
|
||||
*
|
||||
* @slot title - Optional additions to title. Works best with `et2-button-icon`.
|
||||
* @slot title - Optional additions to title.
|
||||
* @slot toolbar - Toolbar containing controls for search & navigation
|
||||
* @slot prefix - Before the toolbar
|
||||
* @slot suffix - Like prefix, but after
|
||||
@ -48,7 +49,7 @@ import {Et2VfsSelectRow} from "./Et2VfsSelectRow";
|
||||
*
|
||||
*/
|
||||
|
||||
export class Et2VfsSelect extends Et2InputWidget(LitElement) implements SearchMixinInterface
|
||||
export class Et2VfsSelectDialog extends Et2InputWidget(LitElement) implements SearchMixinInterface
|
||||
{
|
||||
static get styles()
|
||||
{
|
||||
@ -145,7 +146,7 @@ export class Et2VfsSelect extends Et2InputWidget(LitElement) implements SearchMi
|
||||
|
||||
get _searchNode() : HTMLInputElement { return this.shadowRoot.querySelector("#search");}
|
||||
|
||||
get _pathNode() : HTMLElement { return this.shadowRoot.querySelector("#path");}
|
||||
get _pathNode() : Et2VfsPath { return this.shadowRoot.querySelector("#path");}
|
||||
|
||||
get _listNode() : HTMLElement { return this.shadowRoot.querySelector("#listbox");}
|
||||
|
||||
@ -194,7 +195,7 @@ export class Et2VfsSelect extends Et2InputWidget(LitElement) implements SearchMi
|
||||
mime: this.mime || null,
|
||||
name: this.title
|
||||
};
|
||||
return this.egw().request(this.egw().link(this.egw().ajaxUrl(this.egw().decodePath(Et2VfsSelect.SERVER_URL))),
|
||||
return this.egw().request(this.egw().link(this.egw().ajaxUrl(this.egw().decodePath(Et2VfsSelectDialog.SERVER_URL))),
|
||||
[content, attrs]).then((results) =>
|
||||
{
|
||||
debugger;
|
||||
@ -579,7 +580,7 @@ export class Et2VfsSelect extends Et2InputWidget(LitElement) implements SearchMi
|
||||
// -1 because we're in keyDown handler, and value is from _before_ this key was pressed
|
||||
if(this._searchNode.value.length - 1 > 0)
|
||||
{
|
||||
this._searchTimeout = window.setTimeout(() => {this.startSearch()}, Et2VfsSelect.SEARCH_TIMEOUT);
|
||||
this._searchTimeout = window.setTimeout(() => {this.startSearch()}, Et2VfsSelectDialog.SEARCH_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
@ -605,7 +606,7 @@ export class Et2VfsSelect extends Et2InputWidget(LitElement) implements SearchMi
|
||||
@click=${() => this.setPath("/apps/favorites")}
|
||||
></et2-button>
|
||||
<et2-select id="app" emptyLabel="Applications" noLang="1"
|
||||
.select_options=${this.appList}
|
||||
.select_options=${this._appList}
|
||||
@change=${(e) => this.setPath("/apps/" + e.target.value)}
|
||||
>
|
||||
</et2-select>
|
||||
@ -733,10 +734,10 @@ export class Et2VfsSelect extends Et2InputWidget(LitElement) implements SearchMi
|
||||
<div
|
||||
part="path"
|
||||
>
|
||||
<input id="path"
|
||||
value=${this.path}
|
||||
@onchange=${this.startSearch}
|
||||
/>
|
||||
<et2-vfs-path id="path"
|
||||
.value=${this.path}
|
||||
@change=${() => {this.setPath(this._pathNode.value)}}
|
||||
></et2-vfs-path>
|
||||
</div>
|
||||
<div
|
||||
id="listbox"
|
||||
@ -784,7 +785,7 @@ export class Et2VfsSelect extends Et2InputWidget(LitElement) implements SearchMi
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("et2-vfs-select", Et2VfsSelect);
|
||||
customElements.define("et2-vfs-select-dialog", Et2VfsSelectDialog);
|
||||
|
||||
export interface FileInfo
|
||||
{
|
@ -1,6 +1,6 @@
|
||||
import {html, LitElement} from "lit";
|
||||
import {Et2Widget} from "../Et2Widget/Et2Widget";
|
||||
import {FileInfo} from "./Et2VfsSelect";
|
||||
import {FileInfo} from "./Et2VfsSelectDialog";
|
||||
import {property} from "lit/decorators/property.js";
|
||||
import {state} from "lit/decorators/state.js";
|
||||
import {classMap} from "lit/directives/class-map.js";
|
||||
|
@ -98,7 +98,8 @@ import "./Layout/Et2Split/Et2Split";
|
||||
import "./Layout/RowLimitedMixin";
|
||||
import "./Et2Vfs/Et2VfsMime";
|
||||
import "./Et2Vfs/Et2VfsPath";
|
||||
import "./Et2Vfs/Et2VfsSelect";
|
||||
import "./Et2Vfs/Et2VfsSelectButton";
|
||||
import "./Et2Vfs/Et2VfsSelectDialog";
|
||||
import "./Et2Vfs/Et2VfsSelectRow";
|
||||
import "./Et2Vfs/Et2VfsUid";
|
||||
import "./Et2Textbox/Et2Password";
|
||||
|
Loading…
Reference in New Issue
Block a user