Skip to content

Conversation

@orangejenny
Copy link
Contributor

@orangejenny orangejenny commented Sep 10, 2024

Summary

Removes dependency on the MediaUploader component, which is based on YUI, which has been EOL for quite some time.

I'm just replacing this with a basic HTML file upload (hidden by a slightly more nicely styled button). Vellum doesn't use most of the more advanced MediaUploader functionality (multi-file uploads, sharing).

https://dimagi.atlassian.net/browse/SAAS-15969

Product Description

There are minor UI changes:

  • Removal of progress bar
  • Removal of within-popup "Cancel upload" button

Safety Assurance

  • Risk label is set correctly
  • The set of people pinged as reviewers is appropriate for the level of risk of the change
  • If QA is part of the safety story, the "Awaiting QA" label is used
  • I have confidence that this PR will not introduce a regression for the reasons below

Automated test coverage

There are tests for the code that updates filenames on upload.

QA Plan

https://dimagi.atlassian.net/browse/QA-7088

Safety story

Multimedia is historically finicky area (at least in HQ, I might be inappropriately slandering Vellum with that statement), but risk is limited to the widget.

Rollback instructions

  • This PR can be reverted after deploy with no further considerations

This in a non-standard form of substitution, and it's standard (at least in HQ)
for translations to contain a bit of HTML/underscore tags.
Intentionally sacrificing this functionality as more complex than its value justifies.
Since now there's both hqm-status and hqm-upload-status, there will likely be more naming updates.
This renames hqm-status to hqm-errors, becuase it's only used to display errors
(in multi-file versions of the uploader, it would do more). It intentionally removes the
"Cancel Upload" button shown when there are errors as a simplification. Closing and re-opening the model also
allows the user to uplaod a new file.
With the progress bar gone, add this indictor that the server is working.
The only thing this does is call updateMediaPath, which is already called in the click handler for the upload
confirmation button.
So far as I can tell, this isn't used.
Also see #1004
Now that we're no longer asynchronously loading file-uploader (hqmedia.upload_controller.js),
this doesn't need to be deferred.
This is no longer needed now that the upload controls are simpler objects,
rather than containing a YUI widget.
… opening a different modal of the same media type
There's only one modal per media type. The old code was adding a listener
to each modal for every type of multimedia (normal, help, hint), all
of which would fire whenever the modal was opened.
This doesn't appear to be used.
Copy link
Contributor

@millerdev millerdev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️

src/uploader.js Outdated

// Clear file input's value on click so that change event will fire on re-selecting the same file
$fileInput.on('click' , function() {
$(this).val('');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this destructive? Like if the user clicks the file input where a file had previously been selected, but then decides not to select a new file (maybe cancels out?), is the input now empty?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is. I didn't think that was a problem, but after testing a bit, it turns out that behavior causes a js error, and I don't think it's doing anything useful. Removed in 49f1c6d

package.json Outdated
"main": "src/main.js",
"scripts": {
"testserver": "`npm bin`/http-server -p ${VELLUM_PORT:-8088}",
"testserver": "node_modules/.bin/http-server -p ${VELLUM_PORT:-8088}",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought this was the standard way to get the "bin" path with npm. What version of npm are you running? I have 8.19.4 here (not sure how old that is), and npm bin works.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's at least middle-aged. I'm on 10 and get an error:

[Vellum] (master) $ npm --version
10.8.1
[Vellum] (master) $ npm bin
Unknown command: "bin"

To see a list of supported npm commands, run:
  npm help

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In places where commands need to be run that are not part of package.json, npm exec or npx seem to be the recommended replacement. However, in this context I'm not sure we need any of that. This works in my local environment

Suggested change
"testserver": "node_modules/.bin/http-server -p ${VELLUM_PORT:-8088}",
"testserver": "http-server -p ${VELLUM_PORT:-8088}",

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible you installed http-server globally at some point? When I was setting up my Vellum environment last week (new laptop since the last time I worked on vellum), I couldn't run just http-server until I installed the package globally. I just deleted the node_modules directory and tried again to see if it was really necessary, and I think it is:

[Vellum] (jls/drop-MediaUploader) $  rm -rf node_modules
[Vellum] (jls/drop-MediaUploader) $ ls node_modules/http-server
ls: node_modules/http-server: No such file or directory
[Vellum] (jls/drop-MediaUploader) $ yarn install --frozen-lockfile
yarn install v1.22.21
(node:36307) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Building fresh packages...
warning Your current version of Yarn is out of date. The latest version is "1.22.22", while you're on "1.22.21".
info To upgrade, run the following command:
$ curl --compressed -o- -L https://yarnpkg.com/install.sh | bash
✨  Done in 39.73s.
[Vellum] (jls/drop-MediaUploader) $ ls node_modules/http-server
LICENSE         README.md       bin             doc             lib             node_modules    package.json
[Vellum] (jls/drop-MediaUploader) $ http-server
zsh: command not found: http-server
[Vellum] (jls/drop-MediaUploader) $ npm install -g http-server

added 46 packages in 2s

15 packages are looking for funding
  run `npm fund` for details
[Vellum] (jls/drop-MediaUploader) $ http-server
Starting up http-server, serving ./

http-server version: 14.1.1
...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forgot about your first sentence. npx exec http-server and npx http-server do both work for me locally even when the package is only installed locally, thank you for pointing those out.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I verified that http-server was not on my path, and npx does not seem to be necessary in package.json. Does that not work for you? My guess is that npx http-server is only necessary when running it directly on the command line, but it's not needed in the context of a command in package.json.

$ which http-server
/usr/bin/which: no http-server in (...PATH...)

$ http-server
bash: http-server: command not found...

$ grep testserver package.json 
        "testserver": "http-server -p ${VELLUM_PORT:-8088}",

$ npm run testserver

> vellum@1.6.0 testserver
> http-server -p ${VELLUM_PORT:-8088}

Starting up http-server, serving ./
...
^Chttp-server stopped.

src/uploader.js Outdated
uploadController.value.updateMediaPath();

var newExtension = '.' + file.name.split('.').pop().toLowerCase();
uploadController.value.uploadParams.path = uploadController.value.uploadParams.path.replace(/(\.[^/.]+)?$/, newExtension);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens here if the file does not have an extension? My quick test says it will add the full name as the extension:

>> newExtension = "." + "name".split('.').pop().toLowerCase()
".name"
>> "/path/name".replace(/(\.[^/.]+)?$/, newExtension)
"/path/name.name" 

Is that expected?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's weird, but I don't think it's harmful. Ultimately the server will reject the file for having an unrecognized extension, which I think is fine, we don't need to accept files without extensions.

src/uploader.js Outdated
return $("#" + SLUG_TO_UPLOADER_SLUG[widget.form]);
};

widget.updateModalExistingFile = function (objectMap, isNew) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not obvious to me what isNew means in this context. Seems like it causes an "upload completed" thing to become visible. Would it make sense to change the name to isCompleted?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure - c423dfd

@orangejenny
Copy link
Contributor Author

QA passed, merging.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants