Skip to content

Commit

Permalink
UI changes to file browser
Browse files Browse the repository at this point in the history
  • Loading branch information
piotrWichlinskiSoftwaremind authored and diocas committed May 19, 2023
1 parent dd9ddbc commit ed1b997
Show file tree
Hide file tree
Showing 12 changed files with 140 additions and 75 deletions.
3 changes: 2 additions & 1 deletion cs3api4lab/api/cs3_file_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import cs3.storage.provider.v1beta1.provider_api_pb2 as cs3sp
from google.protobuf.json_format import MessageToDict

from cs3api4lab.exception.exceptions import ResourceNotFoundError, FileLockedError
from cs3api4lab.exception.exceptions import ResourceNotFoundError

from cs3api4lab.utils.file_utils import FileUtils
from cs3api4lab.api.storage_api import StorageApi
Expand Down Expand Up @@ -268,3 +268,4 @@ def _handle_error(self, response):
self.log.error(response)
raise Exception("Incorrect server response: " +
response.status.message)

2 changes: 1 addition & 1 deletion cs3api4lab/api/cs3apismanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ def get(self, path, content=True, type=None, format=None):
elif type == 'notebook' or (type is None and path.endswith('.ipynb')):
try: #this needs to be fixed/refactored in a separate issue
model = self._notebook_model(path, content=content)
except Exception:
except Exception as e:
self.log.info("Notebook does not exist %s", path)
else:
if path.endswith('.ipynb'):
Expand Down
Empty file removed cs3api4lab/api/lock_manager.py
Empty file.
9 changes: 3 additions & 6 deletions cs3api4lab/locks/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,9 @@ def get_current_user(self):
metadata=[('x-access-token', self.auth.authenticate())])
return self.user.user

def resolve_file_path(self, stat):
if self.is_valid_external_lock(stat):
file_name = stat['filepath'].split('/')[-1]
file_dir = '/'.join(stat['filepath'].split('/')[0:-1])
return self._resolve_directory(file_dir, self.config.endpoint) + self._get_conflict_filename(file_name)
return stat['filepath']
def resolve_file_path(self, path):
file_name = path.split('/')[-1]
return self._get_conflict_filename(file_name)

@abstractmethod
def is_valid_external_lock(self, stat):
Expand Down
39 changes: 2 additions & 37 deletions cs3api4lab/tests/test_cs3apismanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,42 +225,8 @@ def test_is_editor(self):
finally:
try:
self.contents_manager.delete_file(file_path)
except Exception:
pass

def test_is_editor_shared_as_viewer(self):
self.content = "Lorem ipsum dolor sit amet..."
file_path = '/home/test_is_editor_file.txt'
remote_path = '/reva/richard/test_is_editor_file.txt'
einstein_id = '4c510ada-c86b-4815-8820-42cdf82c3d51'
einstein_idp = 'cernbox.cern.ch'
try:
richards_share = self.create_share('richard', einstein_id, einstein_idp, file_path, 'viewer')
self.share_id = richards_share['opaque_id']
stat = self.file_api.stat_info(remote_path, self.config.endpoint)
result = self.contents_manager._is_editor(stat)
self.assertEqual(result, False, 'Is editor should be false')
finally:
try:
self.remove_test_share('richard', self.share_id)
self.remove_test_file('richard', file_path)
except Exception:
pass #we don't need any actions here


def test_is_editor(self):
file_path = '/home/test_is_editor_file.txt'
message = "Lorem ipsum dolor sit amet..."
try:
self.file_api.write_file(file_path, message, self.endpoint)
stat = self.file_api.stat_info(file_path, self.config.endpoint)
result = self.contents_manager._is_editor(stat)
self.assertEqual(result, True, 'Incorrect check if file is editor')
finally:
try:
self.contents_manager.delete_file(file_path)
except Exception:
pass
except Exception as e:
self.log.warn("Cannot remove %s:%s" % (file_path, e))

def test_is_editor_shared_as_viewer(self):
self.content = "Lorem ipsum dolor sit amet..."
Expand All @@ -281,7 +247,6 @@ def test_is_editor_shared_as_viewer(self):
except Exception:
pass #we don't need any actions here


def test_delete_non_exits_file(self):
file_path = "/test_delete_non_exits_file.txt"
with self.assertRaises(web.HTTPError):
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
"typescript": "~4.1.6"
},
"sideEffects": [
"style/*.css",
"style/**/*.css",
"style/index.js"
],
"jupyterlab": {
Expand Down
31 changes: 22 additions & 9 deletions src/cs3panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,15 +134,17 @@ export class Cs3HeaderWidget extends ReactWidget {
}

export const Bottom = (props: BottomProps): JSX.Element => {
const [text, setText] = useState('');
// const [text, setText] = useState('');
const [hiddenFiles, setHiddenFiles] = useState(0);
const [action, setAction] = useState('show');

const setLabel = async (): Promise<void> => {
const showHidden: boolean = (await props.db.fetch('showHidden')) as boolean;
const hiddenFilesNo: number = (await props.db.fetch(
'hiddenFilesNo'
)) as number;
const hiddenFilesNo: number =
((await props.db.fetch('hiddenFilesNo')) as number) || 0;
const action = showHidden === undefined || !showHidden ? 'show' : 'hide';
setText(`${hiddenFilesNo} hidden files (${action})`);
setHiddenFiles(hiddenFilesNo);
setAction(action);
};

props.browser.model.pathChanged.connect(async () => {
Expand All @@ -153,7 +155,13 @@ export const Bottom = (props: BottomProps): JSX.Element => {
await setLabel();
});

return <div className={'jp-bottom-div'}>{text}</div>;
return (
<div className={'jp-bottom-div'}>
<div className="jp-bottom-hidden-files">
{hiddenFiles} hidden files (<a>{action}</a>)
</div>
</div>
);
};

export class Cs3BottomWidget extends ReactWidget {
Expand All @@ -170,7 +178,8 @@ export class Cs3BottomWidget extends ReactWidget {
browser: FileBrowser
) {
super(options);
this.addClass('c3-bottom-widget');
// this.addClass('c3-bottom-widget');
// this.addClass('p-Widget');
this.id = id;
this.title.closable = false;
this.bottomProps = { db: stateDB, browser: browser };
Expand All @@ -189,13 +198,17 @@ export class Cs3BottomWidget extends ReactWidget {
}

export class Cs3TabWidget extends ReactWidget {
constructor(title: string, icon: LabIcon, options: Widget.IOptions = {}) {
constructor(title: string, icon?: LabIcon, options: Widget.IOptions = {}) {
super(options);
this.addClass('c3-tab-widget');

this.title.label = title;
this.title.caption = title;
this.title.icon = icon;
this.title.className = 'jp-main-tab';
this.title.iconClass = 'jp-main-tab-icon';
if (icon) {
this.title.icon = icon;
}
}

protected render(): JSX.Element {
Expand Down
12 changes: 12 additions & 0 deletions src/icons.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import accept from '../style/icons/accept.svg';
import decline from '../style/icons/decline.svg';
import share from '../style/icons/share.svg';
import info from '../style/icons/info.svg';
import { LabIcon } from '@jupyterlab/ui-components';

export const acceptIcon = new LabIcon({
Expand All @@ -11,3 +13,13 @@ export const declineIcon = new LabIcon({
name: 'cs3api4lab:decline',
svgstr: decline
});

export const shareIcon = new LabIcon({
name: 'cs3api4lab:share',
svgstr: share
});

export const infoIcon = new LabIcon({
name: 'cs3api4lab:info',
svgstr: info
});
33 changes: 17 additions & 16 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,13 @@ import {
import { PendingSharesListWrapper } from './pendingShares';
import { addHomeDirButton, addLaunchersButton } from './utils';
import { AccordionPanel } from '@lumino/widgets';
import {
kernelIcon,
caseSensitiveIcon,
inspectorIcon,
newFolderIcon,
circleIcon
} from '@jupyterlab/ui-components';
import { kernelIcon } from '@jupyterlab/ui-components';
import { Contents } from '@jupyterlab/services';
import { addCommands, createLauncher, restoreBrowser } from './browserCommands';
import { IMainMenu } from '@jupyterlab/mainmenu';
import { ITranslator } from '@jupyterlab/translation';
import { requestAPI } from './services';
// import { cs3AccordionChild } from './cs3Accordion';
import { infoIcon, shareIcon } from './icons';

/**
* The command IDs used by the react-widget plugin.
Expand Down Expand Up @@ -179,7 +173,8 @@ const cs3share: JupyterFrontEndPlugin<void> = {
dialogTracker.add(dialog);
}
},
iconClass: () => 'jp-MaterialIcon jp-FileUploadIcon',
// iconClass: () => 'jp-MaterialIcon jp-FileUploadIcon',
icon: infoIcon,
label: () => {
return 'File info';
}
Expand All @@ -205,7 +200,8 @@ const cs3share: JupyterFrontEndPlugin<void> = {
});
}
},
iconClass: () => 'jp-MaterialIcon jp-FileUploadIcon',
// iconClass: () => 'jp-MaterialIcon jp-FileUploadIcon',
icon: shareIcon,
label: () => {
return 'Share file';
}
Expand Down Expand Up @@ -276,12 +272,14 @@ const cs3browser: JupyterFrontEndPlugin<void> = {
// const fileBrowser = factory.defaultBrowser
factory.defaultBrowser.title.label = 'My Files';
factory.defaultBrowser.title.caption = 'My Files';
factory.defaultBrowser.title.icon = caseSensitiveIcon;
factory.defaultBrowser.title.className = 'jp-main-tab';
factory.defaultBrowser.title.iconClass = 'jp-main-tab-icon';
// factory.defaultBrowser.title.icon = caseSensitiveIcon;

factory.defaultBrowser.toolbar.addItem(
'Share files',
new ToolbarButton({
icon: circleIcon,
icon: shareIcon,
tooltip: 'Share files',
onClick: () => {
const selectedFileList: Contents.IModel[] = toArray(
Expand Down Expand Up @@ -312,7 +310,9 @@ const cs3browser: JupyterFrontEndPlugin<void> = {
const cs3BottomWidget: ReactWidget = new Cs3BottomWidget(
'cs3Api Bottom',
'cs3-bottom-widget',
{},
{
// he
},
stateDB,
factory.defaultBrowser
);
Expand Down Expand Up @@ -363,8 +363,8 @@ const cs3browser: JupyterFrontEndPlugin<void> = {
// Projects tab
//
const cs3TabWidget3: ReactWidget = new Cs3TabWidget(
'Projects',
newFolderIcon
'Projects'
// newFolderIcon
);

/**
Expand Down Expand Up @@ -448,7 +448,8 @@ const cs3browser: JupyterFrontEndPlugin<void> = {
cs3Accordion.id = 'sharesPanel';
cs3Accordion.title.caption = 'Shares';
cs3Accordion.title.label = 'Shares';
cs3Accordion.title.icon = inspectorIcon;
cs3Accordion.title.iconClass = 'jp-main-tab-icon';
cs3Accordion.title.className = 'jp-main-tab';
cs3Accordion.hide();

const pendingShares = new PendingSharesListWrapper();
Expand Down
71 changes: 67 additions & 4 deletions style/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,18 @@
{
display: flex;
}
jp-bottom-hidden-files {
display: flex;

}
.jp-bottom-div
{
display: block;
text-align: right;
margin-bottom: 5px;
width: auto;
height: 100%;
margin-right: 10px;
margin-top: 5px;
}

.jp-file-info
Expand Down Expand Up @@ -200,17 +207,30 @@

.c3-panel-header
{
height: 75px !important;
/*height: 75px !important;*/
}

#cs3-bottom-widget {
box-sizing: border-box;
}

.c3-panel-bottom
{
height: 25px !important;
display: flex;
align-content: center;
text-align: right;
background-color: var(--jp-layout-color2);
border-top: 1px solid var(--jp-border-color1);
}

.c3-panel-bottom > div
{
padding-left: 10px;
font-family: var(--jp-ui-font-family);
color: var(--jp-ui-font-color2);
}

#cs3-header-widget {
background-color: var(--jp-layout-color0);
}

#cs3-dock-panel-header h1
Expand Down Expand Up @@ -310,4 +330,47 @@
content: var(--jp-icon-caret-up);
font-weight: bold;
color: var(--jp-ui-font-color0);
}

#cs3-panel .m-TabBar {
border-bottom: 1px solid var(--jp-layout-color3) !important;
}

.jp-main-tab {
/*background-color: var(--jp-layout-color3);*/
border: none !important;

border-bottom: 1px solid var(--jp-layout-color3) !important;
background-color: var(--jp-layout-color0) !important;
}
#cs3-dock-panel-main .lm-TabBar-tab.lm-mod-current {

transform: none !important;
/*border-bottom: 1px solid var(--jp-layout-color3) !important;*/
}

#cs3-dock-panel-main .lm-TabBar {
border: none !important;
/*border-bottom: 1px solid var(--jp-layout-color3) !important;*/
}

.jp-main-tab.lm-mod-current > div {
background-color: var(--jp-layout-color3) !important;
color: var(--jp-ui-font-color0) !important;
/*border-bottom: 1px solid var(--jp-layout-color3) !important;*/
}

.jp-main-tab > div {
background-color: var(--jp-layout-color0) !important;
color: var(--jp-ui-font-color0) !important;
text-align: center;
text-transform: capitalize;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}
.jp-main-tab-icon {
display: none;
}
#cs3-panel {
background-color: var(--jp-layout-color0);
}
9 changes: 9 additions & 0 deletions style/icons/info.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit ed1b997

Please sign in to comment.