-
-
Notifications
You must be signed in to change notification settings - Fork 356
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support editing data files in sub-directories #349
Conversation
read from the `id` attribute for path generation - redefine `relative_path` from the `data_file_id` by stripping away `data_dir` in the file id. - redefine `absolute_path` here to include subdirectories based on `splat` params. - point `path` to the data file `id` instead of returning the same data from `relative_path` as previously. - consistent `resource_path`
8f761b0
to
e4f02c9
Compare
- hrefs for data file folders require a trailing slash to differentiate from data files without an extension. - separate `datafiles` to render `Data Files` instead of `Datafiles`
Front-end Changes
|
@benbalter This is ready for your review. |
src/components/Breadcrumbs.js
Outdated
href: `${base}/${before}${path}`, | ||
label: path | ||
}; | ||
if (type == "data files") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we include the trailing slash in path
variable like we do with other types?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are you referring to the pre-API variable or path
within Breadcrumbs
? If its the latter, the reason is that variable before
uses path
to generate its value and I get the following:
Data Files / movies/ / genres/ /
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trailing slash should be optional for the API. For example while /_api/data/movies/
returns a result , /_api/data/movies
doesn't.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, /_api/data/movies/
returns result for the /movies/
folder and /_api/data/movies
returns for movies.yml
file, both being valid data source in their own context and both resulting in site.data.movies
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But we defined our routes so that individuals are called with their extensions.
get "/*?/?:path.:ext"
/_api/data/movies
returning for movies.yml
file doesn't make sense for me. IMO we need to be as specific as possible while calling the endpoints.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/_api/data/movies returning for movies.yml file doesn't make sense for me.
It didn't make sense to me too till I read the spec files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm suggesting to fix it since we are proposing sub-directory support now.
@benbalter What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But we defined our routes so that individuals are called with their extensions.
Its not so according to master
get "/:path.?:ext?" do
(I vote for the more sensible resolution too)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I just noticed that :face_palm:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it was a flexible solution at the time, props to @benbalter 🎉 Directories change everything 😄
@@ -12,7 +12,7 @@ export default class Breadcrumbs extends Component { | |||
let base; | |||
if (type == 'pages') { | |||
base = `${ADMIN_PREFIX}/pages`; | |||
} else if (type == 'datafiles') { | |||
} else if (type == 'data files') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why rename?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had included the explanation for this in the commit message:
[...] to render into 'Data Files' instead of 'Datafiles'
src/containers/views/DataFileEdit.js
Outdated
@@ -47,23 +63,36 @@ export class DataFileEdit extends Component { | |||
} | |||
} | |||
|
|||
getDirectoryfromPath(path) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can retrieve the directory via;
const [directory, ...rest] = params.splat;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes I've used that in a few places elsewhere.
2c61786
to
7d762af
Compare
src/components/form/InputPath.js
Outdated
}else if (type == 'datafiles') { | ||
placeholder = 'your-filename.yml'; | ||
}else if (type == 'data files') { | ||
placeholder = '<directory/>your-filename.yml'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo here => <directory> / your-filename.yml
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually, it was intended to show that directory
and /
are optional. The /
needed only if there was a directory param.
(directory/)?filename.yml
(directory/)filename.yml
[directory/]filename.yml
<directory/>filename.yml
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't get it. I don't think non-technical users will do 😬 HTML tag came to my mind directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah! I see. I'll settle for the your suggestion then <directory> / your-filename.yml
src/containers/views/DataFileEdit.js
Outdated
<InputPath | ||
onChange={onDataFileChanged} | ||
type="data files" | ||
path={path} // TODO: Support using `relative_path` from API instead |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For pages and documents, only filenames
are passed to InputPath
component. Relative paths are shown in the Breadcrumb
component. We should be consistent with them. I'm testing locally and seeing /_data/data_file.yml
instead for InputPath. Before the filename is already shown to users in the Breadcrumbs component. No need to repeat it. Let's abstract that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/_data/data_file.yml
is shown because that parameter (path
) is required to be changed to rename the data file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
renaming /_data/data_file.yml
to /_data/foo/data_file.yml
will move the data file into a subdirectory named foo
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that's expected. What I'm saying is just show data_file.yml
like posts, for example. You can rename it to foo/data_file.yml
and it will drop into /_data/foo/data_file.yml
automagically 😄 Just check out other types, you will understand the difference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did check other types. Hence added the //TODO
here for a future PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That info is already exposed via path
, relative_path
and api_url
. We just need to parse it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On master
, path == relative_path
for this resource.
In this PR, they are redefined.
So, do we parse it like below ?
const data_dir = path - relative_path
--
update: strings cannot be subtracted only concatenated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that should work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what do you think about enabling the tooltip for DataFileEdit
? If yes, what should the message be?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't think of one.
I intentionally disabled this functionality when I was implementing directory support for IMO, these type of operations should be done via OS, not via the GUI. And also I don't want to bring extra complexity to the codebase. This feature requires a bit too much validation to deal with for now. In the future, when Jekyll Admin can be hosted on the cloud, we may implement this or maybe drag-and-drop functionality for files. Finishing off by quoting from Ben Balter: Sometimes removing/omitting a feature is a feature ☯️ |
Alrite then, I'll make the change.. funny, that field's label says Regarding the other concerns, directory traversal is already delimited by the API. The
Cool quote! But it doesn't send a clear answer: |
Nope, you can go deeper from the current directory by passing |
@mertkahyaoglu addressed the two things that bothered you.. 😄 |
lib/jekyll-admin/server/data.rb
Outdated
end | ||
|
||
get "/:path.?:ext?" do | ||
get "/*?/?:path.?:ext?" do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's go with /*?/?:path.:ext
👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so to confirm, we're dropping support for accessing extension-less data files?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeap.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
k.. so change frontend to send requests to /data/foo-dir
or leave it at /data/foo-dir/
?
lib/jekyll-admin/server/data.rb
Outdated
@@ -23,7 +24,7 @@ class Server < Sinatra::Base | |||
json written_file.to_api(:include_content => true) | |||
end | |||
|
|||
delete "/:path.?:ext?" do | |||
delete "/*?/?:path.?:ext?" do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here.
src/containers/views/DataFileNew.js
Outdated
@@ -117,7 +117,7 @@ export class DataFileNew extends Component { | |||
datafileChanged, fieldChanged, onDataFileChanged, datafile, updated, errors, params | |||
} = this.props; | |||
const { path, raw_content } = datafile; | |||
const initialPath = params.splat ? (params.splat + "/") : ""; | |||
const initialPath = params.splat ? (params.splat) : ""; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is easier.
const initialPath = params.splat || '';
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually this is not used at all.
src/containers/views/DataFiles.js
Outdated
@@ -30,14 +30,13 @@ export class DataFiles extends Component { | |||
handleClickDelete(path) { | |||
const { deleteDataFile, params } = this.props; | |||
const confirm = window.confirm(getDeleteMessage(path)); | |||
const directory = params.splat ? (params.splat.replace(/\/$/, "")) : ""; | |||
const goTo = params.splat ? (params.splat) : ""; | |||
const directory = params.splat ? (params.splat) : ""; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again.
const directory = params.splat || '';
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yes.. its a remnant from an earlier commit. One cant call replace
on a nil
entity..
will change..
src/containers/views/DataFiles.js
Outdated
const { deleteDataFile, params } = this.props; | ||
const confirm = window.confirm(getDeleteMessage(path)); | ||
const directory = params.splat || ""; | ||
const dir = directory ? `/${directory}` : "" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Semicolon here 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
aargh.. I hate it that the linter doesn't report this while running npm run test:watch
@ashmaroli What do you think about type converting? Let's say I created a JSON data file first, then decided to switch to YAML using the selectbox. Currently it's not converting. Shall we support it or expect users to decide first then input their data accordingly? 😄 |
} | ||
|
||
handleClickSave(e) { | ||
const { datafile, datafileChanged, fieldChanged, putDataFile, params } = this.props; | ||
const { path, relative_path } = datafile; | ||
const data_dir = path.replace(relative_path, ""); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Try to use single quote for convention please. I also do that 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the convention I saw used in all container/views/*
is that single quotes are used at the top when importing components, and double quotes within the current component class body.
So I think its best to handle all those files in a separate dedicated PR..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah. I also forget them sometimes 😬 Just a reminder for future commitments. Appreciate for the PR though 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me know if that PR will get merged.. I can then correct files here as part of resolving conflicts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was planning to merge it last.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay then..
I had added support for it via the DataGUI.. but checking now, it seems like minor refactors I made to the UPDATE: Raw Editor won't handle data type conversion as its output is WYSIWYG |
@ashmaroli One last thing. Could you move |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @ashmaroli . This one is huge 😄
Sorry for the long list of commits 😇 |
@ashmaroli Glad to work with you 😄 Should've hit |
Fixes #302
API Breaking Changes
path
,relative_path
,absolute_path
is now derived from data file id'path' != 'relative_path'
relative_path
is now relative todata_dir
and does not have a leading/
id
now has a.yml
extension even if the assoc. file doesn't.