Skip to content

Commit

Permalink
Added role to create alias: #2888
Browse files Browse the repository at this point in the history
  • Loading branch information
GermanBluefox committed Jan 10, 2025
1 parent f27cc92 commit c6b8e5f
Show file tree
Hide file tree
Showing 6 changed files with 634 additions and 346 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ The icons may not be reused in other projects without the proper flaticon licens
<!--
### **WORK IN PROGRESS**
-->
### **WORK IN PROGRESS**

- (@GermanBluefox) Analyze the new role and set read/write flags according to the role
- (@GermanBluefox) Added min/max/role by alias creation
- (@GermanBluefox) Improved files browser in the tile mode

### 7.4.10 (2024-12-29)

- (@GermanBluefox) Corrected JSON-Config tables
Expand Down
97 changes: 68 additions & 29 deletions packages/adapter-react-v5/src/Components/FileBrowser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,30 +31,30 @@ import {

// MUI Icons
import {
Refresh as RefreshIcon,
Close as CloseIcon,
ArrowBack as IconBack,
AudioFile as TypeIconAudio,
Bookmark as JsonIcon,
BookmarkBorder as CssIcon,
Brightness6 as Brightness5Icon,
Close as CloseIcon,
Code as JSIcon,
CreateNewFolder as AddFolderIcon,
Delete as DeleteIcon,
Description as HtmlIcon,
Edit as EditIcon,
Code as JSIcon,
FolderOpen as EmptyFilterIcon,
FolderSpecial as RestrictedIcon,
FontDownload as TypeIconTxt,
Image as TypeIconImages,
InsertDriveFile as FileIcon,
Publish as UploadIcon,
KeyboardReturn as EnterIcon,
List as IconList,
MusicNote as MusicIcon,
Publish as UploadIcon,
Refresh as RefreshIcon,
SaveAlt as DownloadIcon,
CreateNewFolder as AddFolderIcon,
FolderOpen as EmptyFilterIcon,
List as IconList,
ViewModule as IconTile,
ArrowBack as IconBack,
Delete as DeleteIcon,
Brightness6 as Brightness5Icon,
Image as TypeIconImages,
FontDownload as TypeIconTxt,
AudioFile as TypeIconAudio,
Videocam as TypeIconVideo,
KeyboardReturn as EnterIcon,
FolderSpecial as RestrictedIcon,
ViewModule as IconTile,
} from '@mui/icons-material';

import type { Connection } from '@iobroker/socket-client';
Expand Down Expand Up @@ -109,7 +109,7 @@ const styles: Record<string, any> = {
position: 'relative',
},
filesDiv: {
width: 'calc(100% - 16px)',
width: 'calc(100% - 8px)',
overflowX: 'hidden',
overflowY: 'auto',
padding: 8,
Expand Down Expand Up @@ -175,7 +175,7 @@ const styles: Record<string, any> = {
top: 22,
left: 18,
zIndex: 1,
color: theme.palette.mode === 'dark' ? '#FFF' : '#000',
color: theme.palette.mode === 'dark' ? '#FFF' : '#FFF',
}),
itemSizeTile: {
width: '100%',
Expand Down Expand Up @@ -392,6 +392,8 @@ const styles: Record<string, any> = {
overflow: 'hidden',
whiteSpace: 'nowrap',
backgroundColor: theme.palette.secondary.main,
color: theme.palette.secondary.contrastText,
borderRadius: '4px 4px 0 0',
}),
pathDivInput: {
width: '100%',
Expand All @@ -400,12 +402,15 @@ const styles: Record<string, any> = {
pl: '2px',
pr: '2px',
cursor: 'pointer',
color: 'white',
'&:hover': {
background: theme.palette.primary.main,
backgroundColor: theme.palette.primary.main,
color: theme.palette.primary.contrastText,
},
}),
pathDivBreadcrumbSelected: {
// todo: add style
color: '#FFF',
},
backgroundImageLight: {
background: 'white',
Expand Down Expand Up @@ -545,7 +550,7 @@ function sortFolders(a: FolderOrFileItem, b: FolderOrFileItem): number {
}

interface FileBrowserState {
viewType: string;
viewType: 'Table' | 'Tile';
folders: Folders;
filterEmpty: boolean;
expanded: string[];
Expand Down Expand Up @@ -613,12 +618,18 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta

private readonly localStorage: Storage;

private readonly scrollPositions: Record<string, number> = {};

private readonly refFileDiv: React.RefObject<HTMLDivElement>;

constructor(props: FileBrowserProps) {
super(props);

this.localStorage = (window as any)._localStorage || window.localStorage;
const expandedStr = this.localStorage.getItem('files.expanded') || '[]';

this.refFileDiv = React.createRef();

if (this.props.limitPath) {
const parts = this.props.limitPath.split('/');
this.limitToObjectID = parts[0];
Expand All @@ -643,9 +654,9 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
expanded = [];
}

let viewType;
let viewType: 'Tile' | 'Table';
if (this.props.showViewTypeButton) {
viewType = this.localStorage.getItem('files.viewType') || TABLE;
viewType = (this.localStorage.getItem('files.viewType') as 'Tile' | 'Table') || TABLE;
} else {
viewType = TABLE;
}
Expand Down Expand Up @@ -1169,6 +1180,11 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
_folder = '';
}

// remember scroll position for this folder
if (this.state.viewType === 'Tile' && this.refFileDiv.current?.scrollTop) {
this.scrollPositions[this.state.currentDir] = this.refFileDiv.current.scrollTop;
}

this.localStorage.setItem('files.currentDir', _folder);

if (folder && e && (e.altKey || e.shiftKey || e.ctrlKey || e.metaKey)) {
Expand Down Expand Up @@ -1202,7 +1218,19 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
path: _folder,
pathFocus: false,
},
() => this.props.onSelect && this.props.onSelect(''),
() => {
if (this.props.onSelect) {
this.props.onSelect('');
}
// scroll to previous position
if (this.state.viewType === 'Tile' && this.scrollPositions[this.state.currentDir]) {
const pos = this.scrollPositions[this.state.currentDir];
delete this.scrollPositions[this.state.currentDir];
if (this.refFileDiv.current) {
this.refFileDiv.current.scrollTop = pos;
}
}
},
);
}

Expand Down Expand Up @@ -1245,9 +1273,9 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta

renderFolder(item: FolderOrFileItem, expanded?: boolean): JSX.Element | null {
if (
this.state.viewType === TABLE &&
// this.state.viewType === TABLE &&
this.state.filterEmpty &&
(!this.state.folders[item.id] || !this.state.folders[item.id].length) &&
!this.state.folders[item.id]?.length && // if the folder is empty
item.id !== USER_DATA &&
!item.temp
) {
Expand All @@ -1268,7 +1296,11 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
component="div"
key={item.id}
id={item.id}
style={this.state.viewType === TABLE ? { marginLeft: padding, width: `calc(100% - ${padding}px` } : {}}
style={
this.state.viewType === TABLE
? { marginLeft: padding, width: `calc(100% - ${padding}px` }
: undefined
}
onClick={e => (this.state.viewType === TABLE ? this.select(item.id, e) : this.changeFolder(e, item.id))}
onDoubleClick={e => this.state.viewType === TABLE && this.toggleFolder(item, e)}
title={this.getText(item.title)}
Expand Down Expand Up @@ -1522,7 +1554,11 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
}
}}
onClick={e => this.select(item.id, e)}
style={this.state.viewType === TABLE ? { marginLeft: padding, width: `calc(100% - ${padding}px)` } : {}}
style={
this.state.viewType === TABLE
? { marginLeft: padding, width: `calc(100% - ${padding}px)` }
: undefined
}
className="browserItem"
sx={Utils.getStyle(
this.props.theme,
Expand Down Expand Up @@ -1656,7 +1692,7 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
}

renderItems(folderId: string): JSX.Element | (JSX.Element | null)[] {
if (this.state.folders && this.state.folders[folderId]) {
if (this.state.folders?.[folderId]) {
// tile
if (this.state.viewType === TILE) {
const res: (JSX.Element | null)[] = [];
Expand All @@ -1678,6 +1714,7 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
return res;
}

// table
const totalResult: (JSX.Element | null)[] = [];
this.state.folders[folderId].forEach(item => {
if (item.folder) {
Expand Down Expand Up @@ -2437,7 +2474,7 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
: `/${this.state.currentDir}`.split('/');
const p: string[] = [];
return (
<Breadcrumbs style={{ paddingLeft: 8 }}>
<Breadcrumbs style={{ paddingLeft: 8, color: '#FFF' }}>
{parts.map((part, i) => {
if (part) {
p.push(part);
Expand Down Expand Up @@ -2542,6 +2579,8 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
}
}
}}
id="dev"
ref={this.refFileDiv}
>
{this.state.viewType === TABLE
? this.renderItems('/')
Expand Down
47 changes: 38 additions & 9 deletions packages/adapter-react-v5/src/Components/ObjectBrowser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ export interface TreeItem {
interface TreeInfo {
funcEnums: string[];
roomEnums: string[];
roles: string[];
roles: { role: string; type: ioBroker.CommonType }[];
ids: string[];
types: string[];
objects: Record<string, ioBroker.Object>;
Expand Down Expand Up @@ -1045,6 +1045,28 @@ function filterObject(
});
}

export function filterRoles(
roleArray: { role: string; type: ioBroker.CommonType }[],
type: ioBroker.CommonType,
defaultRoles?: { role: string; type: ioBroker.CommonType }[],
): string[] {
const bigRoleArray: string[] = [];
roleArray.forEach(
role =>
(role.type === 'mixed' || role.type) === type &&
!bigRoleArray.includes(role.role) &&
bigRoleArray.push(role.role),
);
defaultRoles.forEach(
role =>
(role.type === 'mixed' || role.type) === type &&
!bigRoleArray.includes(role.role) &&
bigRoleArray.push(role.role),
);
bigRoleArray.sort();
return bigRoleArray;
}

/**
* Function to generate a json-file for an object and trigger download it
*/
Expand Down Expand Up @@ -1606,9 +1628,9 @@ function buildTree(

if (obj) {
const common = obj.common;
const role = common && common.role;
if (role && !info.roles.includes(role)) {
info.roles.push(role);
const role = common?.role;
if (role && !info.roles.find(it => it.role === role)) {
info.roles.push({ role, type: common.type });
} else if (id.startsWith('enum.rooms.')) {
info.roomEnums.push(id);
info.enums.push(id);
Expand Down Expand Up @@ -1786,7 +1808,7 @@ function buildTree(
}
return 0;
});
info.roles.sort();
info.roles.sort((a, b) => a.role.localeCompare(b.role));
info.types.sort();

return { info, root };
Expand Down Expand Up @@ -2383,11 +2405,12 @@ interface AdapterColumn {
}

interface ObjectBrowserEditRoleProps {
roles: string[];
roleArray: { role: string; type: ioBroker.CommonType }[];
id: string;
socket: Connection;
onClose: (obj?: ioBroker.Object | null) => void;
t: Translate;
commonType: ioBroker.CommonType;
}

interface ObjectViewFileDialogProps {
Expand Down Expand Up @@ -2455,7 +2478,7 @@ interface ObjectBrowserValueProps {
interface ObjectBrowserEditObjectProps {
socket: Connection;
obj: ioBroker.AnyObject;
roleArray: string[];
roleArray: { role: string; type: ioBroker.CommonType }[];
expertMode: boolean;
themeType: ThemeType;
theme: IobTheme;
Expand All @@ -2472,6 +2495,7 @@ interface ObjectBrowserEditObjectProps {

export interface ObjectAliasEditorProps {
t: Translate;
roleArray: { role: string; type: ioBroker.CommonType }[];
socket: Connection;
objects: Record<string, ioBroker.AnyObject>;
onRedirect: (id: string, delay?: number) => void;
Expand Down Expand Up @@ -4309,7 +4333,10 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
}

private getFilterSelectRole(): JSX.Element {
return this.getFilterSelect('role', this.info.roles);
return this.getFilterSelect(
'role',
this.info.roles.map(it => it.role),
);
}

private getFilterSelectRoom(): JSX.Element {
Expand Down Expand Up @@ -6046,7 +6073,8 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
id={this.state.roleDialog}
socket={this.props.socket}
t={this.props.t}
roles={this.info.roles}
roleArray={this.info.roles}
commonType={this.info.objects[this.state.roleDialog]?.common?.type}
onClose={(obj?: ioBroker.Object | null) => {
if (obj) {
this.info.objects[this.state.roleDialog] = obj;
Expand Down Expand Up @@ -8242,6 +8270,7 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
<ObjectBrowserAliasEditor
key="editAlias"
obj={this.objects[this.state.showAliasEditor]}
roleArray={this.info.roles}
objects={this.objects}
socket={this.props.socket}
t={this.props.t}
Expand Down
Loading

0 comments on commit c6b8e5f

Please sign in to comment.