Compare commits

...

6 Commits

Author SHA1 Message Date
67065b1ffb 1.0.186 2023-09-07 02:57:31 +02:00
783c10479f fix(core): update 2023-09-07 02:57:30 +02:00
d4eae1cd9e 1.0.185 2023-09-04 19:29:39 +02:00
4e674f67c5 fix(core): update 2023-09-04 19:29:39 +02:00
889a543780 1.0.184 2023-09-04 19:28:50 +02:00
fc5f3a9576 fix(core): update 2023-09-04 19:28:50 +02:00
10 changed files with 668 additions and 197 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "@design.estate/dees-catalog", "name": "@design.estate/dees-catalog",
"version": "1.0.183", "version": "1.0.186",
"private": false, "private": false,
"description": "website for lossless.com", "description": "website for lossless.com",
"main": "dist_ts_web/index.js", "main": "dist_ts_web/index.js",
@ -15,18 +15,18 @@
"author": "Lossless GmbH", "author": "Lossless GmbH",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@design.estate/dees-domtools": "^2.0.38", "@design.estate/dees-domtools": "^2.0.39",
"@design.estate/dees-element": "^2.0.25", "@design.estate/dees-element": "^2.0.27",
"@design.estate/dees-wcctools": "^1.0.78", "@design.estate/dees-wcctools": "^1.0.78",
"@fortawesome/fontawesome-svg-core": "^6.4.2", "@fortawesome/fontawesome-svg-core": "^6.4.2",
"@fortawesome/free-brands-svg-icons": "^6.4.2", "@fortawesome/free-brands-svg-icons": "^6.4.2",
"@fortawesome/free-regular-svg-icons": "^6.4.2", "@fortawesome/free-regular-svg-icons": "^6.4.2",
"@fortawesome/free-solid-svg-icons": "^6.4.2", "@fortawesome/free-solid-svg-icons": "^6.4.2",
"@push.rocks/smartpromise": "^4.0.3", "@push.rocks/smartpromise": "^4.0.3",
"@push.rocks/smartstring": "^4.0.8", "@push.rocks/smartstring": "^4.0.9",
"@tsclass/tsclass": "^4.0.42", "@tsclass/tsclass": "^4.0.42",
"highlight.js": "11.8.0", "highlight.js": "11.8.0",
"pdfjs-dist": "^2.16.105" "pdfjs-dist": "^3.10.111"
}, },
"devDependencies": { "devDependencies": {
"@gitzone/tsbuild": "^2.1.66", "@gitzone/tsbuild": "^2.1.66",
@ -35,7 +35,7 @@
"@gitzone/tswatch": "^2.0.7", "@gitzone/tswatch": "^2.0.7",
"@push.rocks/projectinfo": "^5.0.2", "@push.rocks/projectinfo": "^5.0.2",
"@push.rocks/tapbundle": "^5.0.15", "@push.rocks/tapbundle": "^5.0.15",
"@types/node": "^20.5.1" "@types/node": "^20.5.9"
}, },
"files": [ "files": [
"ts/**/*", "ts/**/*",

478
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@design.estate/dees-catalog', name: '@design.estate/dees-catalog',
version: '1.0.183', version: '1.0.186',
description: 'website for lossless.com' description: 'website for lossless.com'
} }

View File

@ -81,12 +81,17 @@ export class DeesContextmenu extends DeesElement {
eventArg.preventDefault(); eventArg.preventDefault();
const contextMenu = new DeesContextmenu(); const contextMenu = new DeesContextmenu();
contextMenu.style.position = 'absolute'; contextMenu.style.position = 'absolute';
contextMenu.style.zIndex = '2000';
contextMenu.style.top = `${eventArg.clientY.toString()}px`; contextMenu.style.top = `${eventArg.clientY.toString()}px`;
contextMenu.style.left = `${eventArg.clientX.toString()}px`; contextMenu.style.left = `${eventArg.clientX.toString()}px`;
contextMenu.style.opacity = '0'; contextMenu.style.opacity = '0';
contextMenu.style.transform = 'scale(0.95,0.95)'; contextMenu.style.transform = 'scale(0.95,0.95)';
contextMenu.style.transformOrigin = 'top left'; contextMenu.style.transformOrigin = 'top left';
contextMenu.menuItems = menuItemsArg; contextMenu.menuItems = menuItemsArg;
contextMenu.windowLayer = await DeesWindowLayer.createAndShow();
contextMenu.windowLayer.addEventListener('click', async () => {
await contextMenu.destroy();
})
document.body.append(contextMenu); document.body.append(contextMenu);
await domtools.plugins.smartdelay.delayFor(0); await domtools.plugins.smartdelay.delayFor(0);
contextMenu.style.opacity = '1'; contextMenu.style.opacity = '1';
@ -97,6 +102,7 @@ export class DeesContextmenu extends DeesElement {
type: Array, type: Array,
}) })
public menuItems: plugins.tsclass.website.IMenuItem[] = []; public menuItems: plugins.tsclass.website.IMenuItem[] = [];
windowLayer: DeesWindowLayer;
constructor() { constructor() {
super(); super();
@ -173,6 +179,9 @@ export class DeesContextmenu extends DeesElement {
} }
public async destroy() { public async destroy() {
if (this.windowLayer) {
this.windowLayer.destroy();
}
this.style.opacity = '0'; this.style.opacity = '0';
this.style.transform = 'scale(0.95,0,95)'; this.style.transform = 'scale(0.95,0,95)';
await domtools.plugins.smartdelay.delayFor(100); await domtools.plugins.smartdelay.delayFor(100);

View File

@ -122,6 +122,8 @@ export const faIcons = {
users: faUsersSolid, users: faUsersSolid,
}; };
export type TIconKey = keyof typeof faIcons;
declare global { declare global {
interface HTMLElementTagNameMap { interface HTMLElementTagNameMap {
'dees-icon': DeesIcon; 'dees-icon': DeesIcon;

View File

@ -15,22 +15,16 @@ import { DeesWindowLayer } from './dees-windowlayer.js';
export class DeesMobilenavigation extends DeesElement { export class DeesMobilenavigation extends DeesElement {
// STATIC // STATIC
public static demo = () => html` public static demo = () => html`
<dees-mobilenavigation <dees-button @click=${() => {
.menuItems="${[ DeesMobilenavigation.createAndInit([
{ {
name: 'hello1', name: 'Test',
action: async () => {}, action: () => {
alert('test');
}, },
{
name: 'hello2',
action: async () => {},
}, },
{ ]);
name: 'hello3', }}></dees-button>
action: async () => {},
},
]}"
></dees-mobilenavigation>
`; `;
private static singletonRef: DeesMobilenavigation; private static singletonRef: DeesMobilenavigation;

View File

@ -2,7 +2,7 @@ import { DeesElement, property, html, customElement, domtools, type TemplateResu
import { Deferred } from '@push.rocks/smartpromise'; import { Deferred } from '@push.rocks/smartpromise';
import type pdfjsTypes from 'pdfjs-dist'; // import type pdfjsTypes from 'pdfjs-dist';
declare global { declare global {
interface HTMLElementTagNameMap { interface HTMLElementTagNameMap {
@ -51,7 +51,7 @@ export class DeesPdf extends DeesElement {
} }
public static pdfJsReady: Promise<any>; public static pdfJsReady: Promise<any>;
public static pdfjsLib: typeof pdfjsTypes; public static pdfjsLib: any // typeof pdfjsTypes;
public async connectedCallback() { public async connectedCallback() {
super.connectedCallback(); super.connectedCallback();
if (!DeesPdf.pdfJsReady) { if (!DeesPdf.pdfJsReady) {

View File

View File

@ -9,9 +9,13 @@ import {
unsafeCSS, unsafeCSS,
type CSSResult, type CSSResult,
state, state,
resolveExec,
} from '@design.estate/dees-element'; } from '@design.estate/dees-element';
import { DeesContextmenu } from './dees-contextmenu.js'
import * as domtools from '@design.estate/dees-domtools'; import * as domtools from '@design.estate/dees-domtools';
import { type TIconKey } from './dees-icon.js';
declare global { declare global {
interface HTMLElementTagNameMap { interface HTMLElementTagNameMap {
@ -19,13 +23,36 @@ declare global {
} }
} }
// interfaces
export interface IDataAction<T = any> { export interface IDataAction<T = any> {
name: string; name: string;
iconName: string; iconName: TIconKey;
/**
* the table behaviour to use for this action
* e.g. upload: allows to upload files to the table
*/
useTableBehaviour?: 'upload' | 'cancelUpload' | 'none'; useTableBehaviour?: 'upload' | 'cancelUpload' | 'none';
/**
* the type of the action
*/
type: 'inRow' | 'rightClick' | 'footer' | 'header' | 'preview' | 'keyCombination';
/**
* allows to check if the action is relevant for the given item
* @param itemArg
* @returns
*/
actionRelevancyCheckFunc?: (itemArg: T) => boolean;
/**
* the actual action function implementation
* @param itemArg
* @returns
*/
actionFunc: (itemArg: T) => Promise<any>; actionFunc: (itemArg: T) => Promise<any>;
} }
export type TDisplayFunction<T = any> = (itemArg: T) => object;
// the table implementation
@customElement('dees-table') @customElement('dees-table')
export class DeesTable<T> extends DeesElement { export class DeesTable<T> extends DeesElement {
public static demo = () => html` public static demo = () => html`
@ -70,22 +97,47 @@ export class DeesTable<T> extends DeesElement {
description: 'Office-Supplies - STAPLES BREMEN', description: 'Office-Supplies - STAPLES BREMEN',
}, },
]} ]}
.dataActions="${[{ dataName="transactions"
.dataActions="${[
{
name: 'upload', name: 'upload',
iconName: 'upload', iconName: 'bell',
useTableBehaviour: 'upload', useTableBehaviour: 'upload',
type: 'inRow',
actionFunc: async (itemArg: any) => { actionFunc: async (itemArg: any) => {
alert(itemArg.amount);
}, },
},{ },
{
name: 'visibility', name: 'visibility',
iconName: 'visibility', iconName: 'copy',
type: 'inRow',
useTableBehaviour: 'preview', useTableBehaviour: 'preview',
actionFunc: async (itemArg: any) => { actionFunc: async (itemArg: any) => {},
}, },
}] as IDataAction[]}" {
>This is a slotted Text</dees-table> name: 'create new',
iconName: 'instagram',
type: 'header',
useTableBehaviour: 'preview',
actionFunc: async (itemArg: any) => {},
},
{
name: 'to gallery',
iconName: 'message',
type: 'footer',
useTableBehaviour: 'preview',
actionFunc: async (itemArg: any) => {},
},
] as IDataAction[]}"
.displayFunction=${(itemArg) => {
return {
...itemArg,
onlyDisplayProp: 'onlyDisplay',
};
}}
>This is a slotted Text</dees-table
>
</div> </div>
`; `;
@ -105,26 +157,27 @@ export class DeesTable<T> extends DeesElement {
}) })
public data: T[] = []; public data: T[] = [];
@property({
type: String,
reflect: true,
})
public dataName: string;
@property({ @property({
type: Array, type: Array,
}) })
public dataActions: IDataAction[] = []; public dataActions: IDataAction[] = [];
@property({
attribute: false,
})
public displayFunction: TDisplayFunction = (itemArg: T) => itemArg as any;
@property({ @property({
type: Object, type: Object,
}) })
public selectedDataRow: T; public selectedDataRow: T;
@property({
type: String,
})
public type: 'normal' | 'highlighted' | 'discreet' | 'big' = 'normal';
@property({
type: String,
})
public status: 'normal' | 'pending' | 'success' | 'error' = 'normal';
public files: File[] = []; public files: File[] = [];
public fileWeakMap = new WeakMap(); public fileWeakMap = new WeakMap();
@ -139,7 +192,7 @@ export class DeesTable<T> extends DeesElement {
color: ${cssManager.bdTheme('#333', '#fff')}; color: ${cssManager.bdTheme('#333', '#fff')};
font-family: 'Mona Sans', 'Inter', sans-serif; font-family: 'Mona Sans', 'Inter', sans-serif;
font-weight: 400; font-weight: 400;
font-size: 16px; font-size: 14px;
padding: 16px; padding: 16px;
display: block; display: block;
width: 100%; width: 100%;
@ -150,11 +203,49 @@ export class DeesTable<T> extends DeesElement {
box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.3); box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.3);
overflow-x: auto; overflow-x: auto;
} }
.header {
display: flex;
justify-content: flex-end;
align-items: center;
}
.headingContainer {
}
.heading {
font-family: 'Hubot Sans', 'Inter', sans-serif;
}
.heading1 {
font-weight: 600;
}
.heading2 {
opacity: 0.6;
}
.headingSeparation { .headingSeparation {
margin-top: 7px; margin-top: 7px;
border-bottom: 1px solid ${cssManager.bdTheme('#bcbcbc', '#bcbcbc')}; border-bottom: 1px solid ${cssManager.bdTheme('#bcbcbc', '#bcbcbc')};
} }
.headerActions {
margin-left: auto;
cursor: pointer;
}
.headerAction {
display: flex;
color: ${cssManager.bdTheme('#333', '#ccc')};
}
.headerAction:hover {
color: ${cssManager.bdTheme('#555', '#fff')};
}
.headerAction dees-icon {
margin-right: 8px;
}
table, table,
.noDataSet { .noDataSet {
margin-top: 16px; margin-top: 16px;
@ -186,7 +277,7 @@ export class DeesTable<T> extends DeesElement {
background: none; background: none;
} }
tr.selected .innerCellContainer { tr.selected .innerCellContainer {
background: ${cssManager.bdTheme('#22222220', '#ffffff20')}; background: ${cssManager.bdTheme('#22222220', '#ffffff40')};
} }
th { th {
text-transform: uppercase; text-transform: uppercase;
@ -228,14 +319,37 @@ export class DeesTable<T> extends DeesElement {
background: ${cssManager.bdTheme('#CCC', '#111')}; background: ${cssManager.bdTheme('#CCC', '#111')};
} }
.tableStatistics { .footer {
padding: 4px 16px; font-size: 14px;
font-size: 12px;
color: ${cssManager.bdTheme('#111', '#ffffff90')}; color: ${cssManager.bdTheme('#111', '#ffffff90')};
background: ${cssManager.bdTheme('#eeeeeb', '#00000050')}; background: ${cssManager.bdTheme('#eeeeeb', '#00000050')};
margin: 16px -16px -16px -16px; margin: 16px -16px -16px -16px;
border-bottom-left-radius: 3px; border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px; border-bottom-right-radius: 3px;
display: flex;
}
.tableStatistics {
padding: 8px 16px;
}
.footerActions {
margin-left: auto;
}
.footerActions .footerAction {
cursor: pointer;
padding: 8px 16px;
display: flex;
}
.footerActions .footerAction:hover {
background: ${cssManager.bdTheme('#CCC', '#111')};
}
.footerActions dees-icon {
display: flex;
margin-right: 8px;
} }
`, `,
]; ];
@ -244,15 +358,44 @@ export class DeesTable<T> extends DeesElement {
return html` return html`
<div class="mainbox"> <div class="mainbox">
<!-- the heading part --> <!-- the heading part -->
<div>${this.heading1}</div> <div class="header">
<div>${this.heading2}</div> <div class="headingContainer">
<div class="heading heading1">${this.heading1}</div>
<div class="heading heading2">${this.heading2}</div>
</div>
<div class="headerActions">
${resolveExec(async () => {
const resultArray: TemplateResult[] = [];
for (const action of this.dataActions) {
if (action.type !== 'header') continue;
resultArray.push(
html`<div
class="headerAction"
@click=${() => {
action.actionFunc(this.selectedDataRow);
}}
>
${action.iconName
? html`<dees-icon .iconSize=${14} .iconFA=${action.iconName}></dees-icon>
${action.name}`
: action.name}
</div>`
);
}
return resultArray;
})}
</div>
</div>
<div class="headingSeparation"></div> <div class="headingSeparation"></div>
<!-- the actual table --> <!-- the actual table -->
<style></style> <style></style>
${this.data.length > 0 ${this.data.length > 0
? (() => { ? (() => {
const headings: string[] = Object.keys(this.data[0]); // Only pick up the keys from the first transformed data object
// as all data objects are assumed to have the same structure
const firstTransformedItem = this.displayFunction(this.data[0]);
const headings: string[] = Object.keys(firstTransformedItem);
return html` return html`
<table> <table>
<tr> <tr>
@ -273,32 +416,42 @@ export class DeesTable<T> extends DeesElement {
} }
})()} })()}
</tr> </tr>
${this.data.map( ${this.data.map((itemArg) => {
(itemArg) => html` const transformedItem = this.displayFunction(itemArg);
const getTr = (elementArg: HTMLElement): HTMLElement => {
if (elementArg.tagName === 'TR') {
return elementArg;
} else {
return getTr(elementArg.parentElement);
}
};
return html`
<tr <tr
@click=${() => { @click=${() => {
this.selectedDataRow = itemArg; this.selectedDataRow = itemArg;
}} }}
@dragenter=${async (eventArg: DragEvent) => { @dragenter=${async (eventArg: DragEvent) => {
console.log((eventArg.target as HTMLElement).tagName)
console.log('dragenter');
eventArg.preventDefault(); eventArg.preventDefault();
eventArg.stopPropagation(); eventArg.stopPropagation();
(eventArg.target as HTMLElement).parentElement.style.background = '#800000'; const realTarget = getTr(eventArg.target as HTMLElement);
console.log('dragenter');
console.log(realTarget);
setTimeout(() => {
realTarget.style.background = 'green';
}, 0);
}} }}
@dragleave=${async (eventArg: DragEvent) => { @dragleave=${async (eventArg: DragEvent) => {
console.log((eventArg.target as HTMLElement).tagName)
console.log('dragleave');
eventArg.preventDefault(); eventArg.preventDefault();
eventArg.stopPropagation(); eventArg.stopPropagation();
(eventArg.target as HTMLElement).parentElement.style.background = 'none'; const realTarget = getTr(eventArg.target as HTMLElement);
realTarget.style.background = 'none';
}} }}
@dragover=${async (eventArg: DragEvent) => { @dragover=${async (eventArg: DragEvent) => {
eventArg.preventDefault(); eventArg.preventDefault();
}} }}
@drop=${async (eventArg: DragEvent) => { @drop=${async (eventArg: DragEvent) => {
eventArg.preventDefault(); eventArg.preventDefault();
const newFiles = [] const newFiles = [];
for (const file of Array.from(eventArg.dataTransfer.files)) { for (const file of Array.from(eventArg.dataTransfer.files)) {
this.files.push(file); this.files.push(file);
newFiles.push(file); newFiles.push(file);
@ -306,17 +459,41 @@ export class DeesTable<T> extends DeesElement {
} }
const result: File[] = this.fileWeakMap.get(itemArg as object); const result: File[] = this.fileWeakMap.get(itemArg as object);
if (!result) { if (!result) {
this.fileWeakMap.set(itemArg as object, newFiles) this.fileWeakMap.set(itemArg as object, newFiles);
} else { } else {
result.push(...newFiles); result.push(...newFiles);
} }
}} }}
@contextmenu=${async (eventArg: MouseEvent) => {
DeesContextmenu.openContextMenuWithOptions(eventArg, [
{
name: 'copy',
iconName: 'copySolid',
action: async () => {
return null;
},
},
{
name: 'edit',
iconName: 'penToSquare',
action: async () => {
return null;
},
},{
name: 'paste',
iconName: 'pasteSolid',
action: async () => {
return null;
},
},
])
}}
class="${itemArg === this.selectedDataRow ? 'selected' : ''}" class="${itemArg === this.selectedDataRow ? 'selected' : ''}"
> >
${headings.map( ${headings.map(
(headingArg) => html` (headingArg) => html`
<td> <td>
<div class="innerCellContainer">${itemArg[headingArg]}</div> <div class="innerCellContainer">${transformedItem[headingArg]}</div>
</td> </td>
` `
)} )}
@ -328,9 +505,19 @@ export class DeesTable<T> extends DeesElement {
${(() => { ${(() => {
const actions: TemplateResult[] = []; const actions: TemplateResult[] = [];
for (const action of this.dataActions) { for (const action of this.dataActions) {
actions.push(html`<div class="action">${action.iconName ? html` if (action.type !== 'inRow') continue;
<dees-icon .iconName=${'upload_file'}></dees-icon> actions.push(
` : action.name}</div>`) html`<div
class="action"
@click=${() => action.actionFunc(itemArg)}
>
${action.iconName
? html`
<dees-icon .iconFA=${action.iconName}></dees-icon>
`
: action.name}
</div>`
);
} }
return actions; return actions;
})()} })()}
@ -340,17 +527,40 @@ export class DeesTable<T> extends DeesElement {
} }
})()} })()}
</tr> </tr>
` `;
)} })}
</table> </table>
`; `;
})() })()
: html` <div class="noDataSet">No data set!</div> `} : html` <div class="noDataSet">No data set!</div> `}
<div class="footer">
<div class="tableStatistics"> <div class="tableStatistics">
${this.data.length} data rows (total) | ${this.data.length} ${this.dataName || 'data rows'} (total) |
${this.selectedDataRow ${this.selectedDataRow ? '# ' + `${this.data.indexOf(this.selectedDataRow) + 1}` : `No`}
? html`Row ${this.data.indexOf(this.selectedDataRow) + 1} selected` selected
: html`No row selected`} </div>
<div class="footerActions">
${resolveExec(async () => {
const resultArray: TemplateResult[] = [];
for (const action of this.dataActions) {
if (action.type !== 'footer') continue;
resultArray.push(
html`<div
class="footerAction"
@click=${() => {
action.actionFunc(this.selectedDataRow);
}}
>
${action.iconName
? html`<dees-icon .iconSize=${14} .iconFA=${action.iconName}></dees-icon>
${action.name}`
: action.name}
</div>`
);
}
return resultArray;
})}
</div>
</div> </div>
</div> </div>
`; `;

View File

@ -13,6 +13,15 @@ export class DeesWindowLayer extends DeesElement {
// STATIC // STATIC
public static demo = () => html`<dees-windowlayer></dees-windowlayer>`; public static demo = () => html`<dees-windowlayer></dees-windowlayer>`;
public static async createAndShow() {
const domtoolsInstance = domtools.DomTools.getGlobalDomToolsSync();
const windowLayer = new DeesWindowLayer();
document.body.append(windowLayer);
await domtoolsInstance.convenience.smartdelay.delayFor(0);
windowLayer.show();
return windowLayer;
}
// INSTANCE // INSTANCE
@property({ @property({
type: Boolean type: Boolean
@ -29,7 +38,7 @@ export class DeesWindowLayer extends DeesElement {
${domtools.elementBasic.styles} ${domtools.elementBasic.styles}
<style> <style>
.windowOverlay { .windowOverlay {
transition: all 0.3s; transition: all 0.2s;
will-change: transform; will-change: transform;
position: fixed; position: fixed;
top: 0px; top: 0px;
@ -82,4 +91,11 @@ export class DeesWindowLayer extends DeesElement {
await domtools.convenience.smartdelay.delayFor(0); await domtools.convenience.smartdelay.delayFor(0);
this.visible = false; this.visible = false;
} }
public async destroy() {
const domtools = await this.domtoolsPromise;
await this.hide();
await domtools.convenience.smartdelay.delayFor(300);
this.remove();
}
} }