Skip to content

Commit

Permalink
Merge branch 'poc-finder' of github.com:django-cms/django-filer into …
Browse files Browse the repository at this point in the history
…poc-finder
  • Loading branch information
jrief committed Nov 23, 2023
2 parents a7af578 + 0016f34 commit 29c69a2
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 39 deletions.
8 changes: 3 additions & 5 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,18 @@ insert_final_newline = true
max_line_length = 80

[*.py]
max_line_length = 120
max_line_length = 119
quote_type = single

[*.{scss,js,html}]
max_line_length = 120
indent_style = space
quote_type = double

[*.js]
max_line_length = 120
quote_type = single

[*.rst]
max_line_length = 80
[*.md]
max_line_length = 100

[*.yml]
indent_size = 2
3 changes: 3 additions & 0 deletions README-Finder.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Apart from the maintainability issues, using the File and Folder models was not
Extending the file model with a more specialized implementation was possible in theory, but so complicated that apart
from the `ImageModel` no other implementations ever have been created.


## Less third-party dependencies

The "Finder" branch of django-filer has less third-party dependencies. It does not depend on
Expand Down Expand Up @@ -145,6 +146,8 @@ The permission system will also be implemented using a different model. This pro
Access Control Lists (ACLs) of [NTFS](https://learn.microsoft.com/en-us/windows/win32/secauthz/access-control-lists).
This will allow to grant permissions to users and groups for each folder (but not file) individually.

A quota system will be implemented, which allows to limit the amount of disk space a user can use.


## License

Expand Down
5 changes: 3 additions & 2 deletions client/FolderAdmin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import DownloadIcon from './icons/download.svg';
import TrashIcon from './icons/trash.svg';
import MoreVerticalIcon from './icons/more-vertical.svg';

const useLayout = (initial: string) => useCookie('django-filer-layout', initial);
const useLayout = (initial: string) => useCookie('django-finder-layout', initial);


export default function FolderAdmin(props) {
Expand Down Expand Up @@ -287,6 +287,7 @@ export default function FolderAdmin(props) {
folderTabsRef={folderTabsRef}
openUploader={() => uploaderRef.current.openUploader()}
downloadFiles={downloadFiles}
layout={layout}
setLayout={setLayout}
setSearchResult={setSearchResult}
/>
Expand All @@ -305,6 +306,6 @@ export default function FolderAdmin(props) {
</DragOverlay>
</div>
</DndContext>
<Tooltip id="django-filer-tooltip" place="bottom-start" />
<Tooltip id="django-finder-tooltip" place="bottom-start" />
</>);
}
8 changes: 4 additions & 4 deletions client/FolderTabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,21 @@ function FolderTab(props) {
}

if (folder.is_root) return (
<li ref={setNodeRef} className={cssClasses(folder)} data-tooltip-id="django-filer-tooltip" data-tooltip-content={gettext("Root folder")}>
<li ref={setNodeRef} className={cssClasses(folder)} data-tooltip-id="django-finder-tooltip" data-tooltip-content={gettext("Root folder")}>
{!isActive || isSearchResult ? <a href={folder.change_url}><RootIcon /></a> : <RootIcon />}
</li>
);

if (folder.is_trash) return (
<li ref={setNodeRef} className={cssClasses(folder)} data-tooltip-id="django-filer-tooltip" data-tooltip-content={gettext("Trash folder")}>
<li ref={setNodeRef} className={cssClasses(folder)} data-tooltip-id="django-finder-tooltip" data-tooltip-content={gettext("Trash folder")}>
{!isActive || isSearchResult ? <a href={folder.change_url}><RecycleIcon /></a> : <RecycleIcon />}
</li>
);

return (
<li ref={setNodeRef} className={cssClasses(folder)}>
{!isActive || isSearchResult ? <a href={folder.change_url}>{folder.name}</a> : folder.name}
<span onClick={togglePin.bind(folder)}>{folder.is_pinned ? <CloseIcon /> : <PinIcon data-tooltip-id="django-filer-tooltip" data-tooltip-content={gettext("Pin this folder")} />}</span>
<span onClick={togglePin.bind(folder)}>{folder.is_pinned ? <CloseIcon /> : <PinIcon data-tooltip-id="django-finder-tooltip" data-tooltip-content={gettext("Pin this folder")} />}</span>
</li>
);
}
Expand Down Expand Up @@ -96,7 +96,7 @@ export const FolderTabs = forwardRef((props: any, forwardedRef) => {

return (
<ul className="folder-tabs">
{settings.parent_url ? <li data-tooltip-id="django-filer-tooltip" data-tooltip-content={gettext("Change to parent folder")}>
{settings.parent_url ? <li data-tooltip-id="django-finder-tooltip" data-tooltip-content={gettext("Change to parent folder")}>
<a href={settings.parent_url}><UpIcon /></a>
</li> : null}
{isSearchResult ? <li className="active">{gettext("Search results")}</li> : null}
Expand Down
34 changes: 19 additions & 15 deletions client/MenuBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ import AddFolderIcon from './icons/add-folder.svg';
import DownloadIcon from './icons/download.svg';
import UploadIcon from './icons/upload.svg';

const useSorting = () => useCookie('django-filer-sorting', '');
const useSorting = () => useCookie('django-finder-sorting', '');


export const MenuBar = forwardRef((props: any, forwardedRef) => {
const settings = useContext(FinderSettings);
const {currentFolderId, columnRefs, folderTabsRef, openUploader, downloadFiles, setLayout, setSearchResult} = props;
const {currentFolderId, columnRefs, folderTabsRef, openUploader, downloadFiles, layout, setLayout, setSearchResult} = props;
const sortingRef = useRef(null);
const [numSelectedInodes, setNumSelectedInodes] = useState(0);
const [numSelectedFiles, setNumSelectedFiles] = useState(0);
Expand Down Expand Up @@ -217,6 +217,10 @@ export const MenuBar = forwardRef((props: any, forwardedRef) => {
}
}

function isActive(value) {
return layout === value ? 'active' : null;
}

console.log('MenuBar', numSelectedInodes, numSelectedFiles);

return (
Expand All @@ -225,24 +229,24 @@ export const MenuBar = forwardRef((props: any, forwardedRef) => {
<li className="search-field">
<SearchField columnRefs={columnRefs} setSearchResult={setSearchResult} />
</li>
<li style={{marginLeft: 'auto'}} onClick={() => setLayout('tiles')} data-tooltip-id="django-filer-tooltip" data-tooltip-content={gettext("Tiles view")}><TilesIcon /></li>
<li onClick={() => setLayout('mosaic')} data-tooltip-id="django-filer-tooltip" data-tooltip-content={gettext("Mosaic view")}><MosaicIcon /></li>
<li onClick={() => setLayout('list')} data-tooltip-id="django-filer-tooltip" data-tooltip-content={gettext("List view")}><ListIcon /></li>
<li onClick={() => setLayout('columns')} data-tooltip-id="django-filer-tooltip" data-tooltip-content={gettext("Columns view")}><ColumnsIcon /></li>
<li className="sorting-dropdown" onClick={() => sortingRef.current.setAttribute('aria-expanded', sortingRef.current.ariaExpanded === 'true' ? 'false': 'true')} aria-haspopup="true" data-tooltip-id="django-filer-tooltip" data-tooltip-content={gettext("Change sorting order")}>
<li style={{marginLeft: 'auto'}} className={isActive('tiles')} onClick={() => setLayout('tiles')} data-tooltip-id="django-finder-tooltip" data-tooltip-content={gettext("Tiles view")}><TilesIcon /></li>
<li className={isActive('mosaic')} onClick={() => setLayout('mosaic')} data-tooltip-id="django-finder-tooltip" data-tooltip-content={gettext("Mosaic view")}><MosaicIcon /></li>
<li className={isActive('list')} onClick={() => setLayout('list')} data-tooltip-id="django-finder-tooltip" data-tooltip-content={gettext("List view")}><ListIcon /></li>
<li className={isActive('columns')} onClick={() => setLayout('columns')} data-tooltip-id="django-finder-tooltip" data-tooltip-content={gettext("Columns view")}><ColumnsIcon /></li>
<li className="sorting-dropdown" onClick={() => sortingRef.current.setAttribute('aria-expanded', sortingRef.current.ariaExpanded === 'true' ? 'false': 'true')} aria-haspopup="true" data-tooltip-id="django-finder-tooltip" data-tooltip-content={gettext("Change sorting order")}>
<SortingIcon />
{renderSortingOptions()}
</li>
<li className={numSelectedInodes ? null : "disabled"} onClick={cutInodes} data-tooltip-id="django-filer-tooltip" data-tooltip-content={gettext("Cut selected to clipboard")}><CutIcon /></li>
<li className={numSelectedInodes ? null : "disabled"} onClick={cutInodes} data-tooltip-id="django-finder-tooltip" data-tooltip-content={gettext("Cut selected to clipboard")}><CutIcon /></li>
{settings.is_trash ? (
<li className="erase" onClick={confirmEraseTrashFolder} data-tooltip-id="django-filer-tooltip" data-tooltip-content={gettext("Empty trash folder")}><EraseIcon /></li>
<li className="erase" onClick={confirmEraseTrashFolder} data-tooltip-id="django-finder-tooltip" data-tooltip-content={gettext("Empty trash folder")}><EraseIcon /></li>
) : (<>
<li className={numSelectedInodes ? null : "disabled"} onClick={copyInodes} data-tooltip-id="django-filer-tooltip" data-tooltip-content={gettext("Copy selected to clipboard")}><CopyIcon /></li>
<li className={clipboard.length === 0 ? "disabled" : null} onClick={pasteInodes} data-tooltip-id="django-filer-tooltip" data-tooltip-content={gettext("Paste from clipboard")}><PasteIcon /></li>
<li className={numSelectedInodes ? null : "disabled"} onClick={deleteInodes} data-tooltip-id="django-filer-tooltip" data-tooltip-content={gettext("Move selected to trash folder")}><TrashIcon /></li>
<li onClick={addFolder} data-tooltip-id="django-filer-tooltip" data-tooltip-content={gettext("Add new folder")}><AddFolderIcon /></li>
<li className={numSelectedFiles ? null : "disabled"} onClick={downloadSelectedFiles} data-tooltip-id="django-filer-tooltip" data-tooltip-content={gettext("Download selected files")}><DownloadIcon /></li>
<li onClick={openUploader} data-tooltip-id="django-filer-tooltip" data-tooltip-content={gettext("Upload files from local host")}><UploadIcon /></li>
<li className={numSelectedInodes ? null : "disabled"} onClick={copyInodes} data-tooltip-id="django-finder-tooltip" data-tooltip-content={gettext("Copy selected to clipboard")}><CopyIcon /></li>
<li className={clipboard.length === 0 ? "disabled" : null} onClick={pasteInodes} data-tooltip-id="django-finder-tooltip" data-tooltip-content={gettext("Paste from clipboard")}><PasteIcon /></li>
<li className={numSelectedInodes ? null : "disabled"} onClick={deleteInodes} data-tooltip-id="django-finder-tooltip" data-tooltip-content={gettext("Move selected to trash folder")}><TrashIcon /></li>
<li onClick={addFolder} data-tooltip-id="django-finder-tooltip" data-tooltip-content={gettext("Add new folder")}><AddFolderIcon /></li>
<li className={numSelectedFiles ? null : "disabled"} onClick={downloadSelectedFiles} data-tooltip-id="django-finder-tooltip" data-tooltip-content={gettext("Download selected files")}><DownloadIcon /></li>
<li onClick={openUploader} data-tooltip-id="django-finder-tooltip" data-tooltip-content={gettext("Upload files from local host")}><UploadIcon /></li>
</>)}
</ul>
</nav>
Expand Down
4 changes: 2 additions & 2 deletions client/Search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import SearchIcon from './icons/search.svg';
import {FinderSettings} from './FinderSettings';
import {useCookie} from './Storage';

const useSearchRealm = initial => useCookie('django-filer-search-realm', initial);
const useSearchRealm = initial => useCookie('django-finder-search-realm', initial);


function useSearchParam(key) : [string, (value: string) => any] {
Expand Down Expand Up @@ -100,7 +100,7 @@ export function SearchField(props) {
<input ref={searchRef} type="search" defaultValue={searchQuery} placeholder={gettext("Search for …")} onChange={handleSearch} onKeyDown={handleSearch} />
<div>
<span className="search-icon" onClick={handleSearch}><SearchIcon /></span>
<span className="search-realm" onClick={() => searchRealmRef.current.setAttribute('aria-expanded', searchRealmRef.current.ariaExpanded === 'true' ? 'false': 'true')} aria-haspopup="true" data-tooltip-id="django-filer-tooltip" data-tooltip-content={gettext("Restrict search")}>
<span className="search-realm" onClick={() => searchRealmRef.current.setAttribute('aria-expanded', searchRealmRef.current.ariaExpanded === 'true' ? 'false': 'true')} aria-haspopup="true" data-tooltip-id="django-finder-tooltip" data-tooltip-content={gettext("Restrict search")}>
{renderSearchRealmOptions()}
</span>
</div>
Expand Down
16 changes: 8 additions & 8 deletions client/finder-admin.scss
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ $copied-inode-border: 2px dashed rgb(48, 164, 0);
background-color: #e6e6e6;
}

&.active {
background-color: rgb(255, 255, 204);
}

&.disabled {
opacity: 0.5;
cursor: not-allowed;
Expand Down Expand Up @@ -180,14 +184,10 @@ $copied-inode-border: 2px dashed rgb(48, 164, 0);
line-height: 32px;
font-size: 16px;

&.active {
background-color: rgb(255, 255, 204);

&::after {
content: "";
position: absolute;
right: 10px;
}
&.active::after {
content: "";
position: absolute;
right: 10px;
}
}
}
Expand Down
9 changes: 6 additions & 3 deletions finder/admin/folder.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def has_add_permission(self, request):
return False

def changelist_view(self, request, extra_context=None):
# always redirect the list view to the detail view of either the last used, ot the root folder
# always redirect the list view to the detail view of either the last used, or the root folder
fallback_folder = self.get_fallback_folder(request)
return HttpResponseRedirect(reverse(
'admin:finder_foldermodel_change',
Expand Down Expand Up @@ -136,7 +136,7 @@ def render_change_form(self, request, context, add=False, change=False, form_url
is_trash=False,
parent_url=parent_url,
)
if not obj.is_root and not next(filter(lambda f: f['id'] == obj.id and f.get('is_pinned'), favorite_folders), None):
if not next(filter(lambda f: f['id'] == obj.id and f.get('is_pinned'), favorite_folders), None):
request.session['finder_last_folder_id'] = str(obj.id)
else:
context['finder_settings'].update(
Expand Down Expand Up @@ -182,7 +182,10 @@ def fetch_inodes(self, request, folder_id):
sorting = request.COOKIES.get('django-finder-sorting')
if query := request.GET.get('q'):
search_realm = request.COOKIES.get('django-finder-search-realm')
starting_folder = FolderModel.objects.root_folder if search_realm == 'everywhere' else current_folder
if search_realm == 'everywhere':
starting_folder = FolderModel.objects.get_root_folder(self.admin_site.name)
else:
starting_folder = current_folder
inodes = self.search_for_inodes(starting_folder, query, sorting=sorting)
else:
inodes = self.get_inodes(parent=current_folder, sorting=sorting)
Expand Down

0 comments on commit 29c69a2

Please sign in to comment.