Skip to content
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

feat: init workspace for vue webapp #2546

Open
wants to merge 70 commits into
base: main
Choose a base branch
from
Open

Conversation

zklosko
Copy link
Member

@zklosko zklosko commented May 12, 2023

Description

Initially started in #1696, starting again from scratch following feedback from lead maintainers.

This PR creates a development environment for the rewrite of Libretime's web user interface. The environment is based on Node 18.12.0 LTS and includes Vue 3, Vuetify 3, Vite, Cypress, Storybook, vue-i18n, Eslint, and Typescript.

I have updated the documentation to reflect these changes:

No documentation updates for now. Getting started notes are in Readme.MD.

Todo

  • Install packages for development (Vue, Vite, Vuetify, Cypress, etc.)
  • Initialize vue-i18n: create templates, config files
  • Configure linting and formatting tools
  • Set up Storybook
  • Set up and create basic testing with Cypress (e2e and unit)
  • Set up CI/CD with Github Actions
  • Copy over logo, image assets from legacy app
  • Add more dev instructions to the Readme file

Links

Closes #1121

@zklosko zklosko changed the title Init development workspace for new Libretime webapp Feat: Init development workspace for new Libretime webapp May 12, 2023
@jooola jooola removed their assignment May 12, 2023
@zklosko zklosko changed the title Feat: Init development workspace for new Libretime webapp feat: Init development workspace for new Libretime webapp May 15, 2023
@zklosko zklosko changed the title feat: Init development workspace for new Libretime webapp feat: init workspace for vue webapp May 15, 2023
@jooola
Copy link
Contributor

jooola commented May 16, 2023

Hey @zklosko, is there more work you want to put into this PR ? Have you come up with a good way to embed the Vue multipage views into the legacy app ?

I also have a branch with a POC that embeds some Vue pages into the legacy app, but it didn't feel clean enough to propose a PR yet. I am currently focusing on the new auth system, which is required for the new UI to work.

What is your plan in regard to this PR and with more generally the web app ?

@zklosko
Copy link
Member Author

zklosko commented May 17, 2023

Hi @jooola! My goal is to set up a base dev environment with configured plugins and CI so we have a good foundation to start building the new UI.

I haven't thought about embedding into the new app. Was planning to do the widgets first since they can be served separately. Once we have the building blocks, I would want to start redesigning from the ground up. It doesn't make sense to move from Bootstrap to Material design frameworks and then endlessly mold the CSS so it looks just like the old UI. I would want to make a new UI and then release it all together as Libretime 4.0.

@maxtimbo
Copy link
Contributor

I've been getting very friendly with Vue 3 lately. How can I help?

@zklosko zklosko marked this pull request as draft June 10, 2023 02:02
@zklosko zklosko marked this pull request as ready for review June 21, 2023 00:15
@zklosko
Copy link
Member Author

zklosko commented Jun 21, 2023

I believe I have a really basic about page set up as a demo. It mostly copies from the front page of our docs site.

Copy link
Contributor

@paddatrapper paddatrapper left a comment

Choose a reason for hiding this comment

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

2 general things:

  1. How are the translation JSON files generated? Can you add instructions to the README?
  2. How would we go about embedding this /about into the legacy app?

webapp/src/App.vue Outdated Show resolved Hide resolved
@zklosko
Copy link
Member Author

zklosko commented Jun 30, 2023

I translated the .po files using something like Localize.biz or an npm package with a CLI. It's decoupled from our Weblate workflow.

Haven't thought too much about embedding the page, but I have it set up to generate a static site so we can serve an HTML file from dist.

@paddatrapper
Copy link
Contributor

Do we have a way of generating a list of strings or keys from the strings used? Otherwise updating the set of translation source strings is difficult

@zklosko
Copy link
Member Author

zklosko commented Jun 30, 2023

I could write a node script to print all keys to a text file but I'm not sure Weblate requires that. Looking at their documentation, it seems like Weblate is fully compatible with the json files that Vue-i18n needs.

Also see: https://docs.weblate.org/en/latest/admin/projects.html#component

    "Playout History": "Playout History",
    "History Templates": "History Templates",
    "Listener Stats": "Listener Stats",

@paddatrapper
Copy link
Contributor

Maybe I am misunderstanding the JSON files, but they map a key used in the code to the translated string right? I'm asking about the mapping from used keys in the code to create the JSON files. For example, a new string is added to a view. How does that key end up in all the JSON files?

Comment on lines 31 to 33
server: {
port: 8080,
},
Copy link
Contributor

@jooola jooola Jul 1, 2023

Choose a reason for hiding this comment

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

We already use that port for other services, please remove and use the default.

@jooola
Copy link
Contributor

jooola commented Jul 1, 2023

eslint should be capable of checking if an i18n key used in the code is missing from the translation files. Maybe also the other way around.

But I would start with empty i18n json files, as we don't (almost) use translated strings yet.

The development setup should also take advantages of the vite dev server, e.g.:

<script type="module" src="http://localhost:5173/src/main.ts"></script>

@zklosko
Copy link
Member Author

zklosko commented Jul 1, 2023

Translation strings are imported globally, then selected by key for templating':

<h4 class="text-h4 py-2">{{ $t("Getting Started") }}</h4>

or as part of v-bind:

v-bind:label="$t('Language')"

I'm asking about the mapping from used keys in the code to create the JSON files. For example, a new string is added to a view. How does that key end up in all the JSON files?

I think you're thinking about it backwards. You would need to have a key:value pair in your JSON i18n translations before adding the string to a view as an i18n translatable string. It isn't automatic. All new strings would need to be added manually. For example, if we wanted to have a greeting message, we could have key:value "Greeting": "Welcome to Libretime!"; contrast this to what we're doing with PHP where our .po file looks like "Welcome to Libretime!": "Welcome to Libretime!".

I know we have a few longer blocks of text with HTML tags that we would like to translate. Instead of having i18n strings for those, we may want to have markdown files (one per language) that we could render in the view so we can have more intricate explanations for things. For example, the following would be less practical, but not impossible, to do as a key:value pair:

#: application/controllers/EmbeddablewidgetsController.php:24
msgid ""
"To configure and use the embeddable player you must:<br><br>\n"
"            1. Enable at least one MP3, AAC, or OGG stream under Settings -> Streams<br>\n"
"            2. Enable the Public LibreTime API under Settings -> Preferences"
msgstr ""

eslint should be capable of checking if an i18n key used in the code is missing from the translation files. Maybe also the other way around.

I think it's mainly the other way around. I found this, but it cleans out unused i18n strings from your locale files.

The development setup should also take advantages of the vite dev server, e.g.: <script type="module" src="http://localhost:5173/src/main.ts"></script>

There isn't a need to do that. src="/src/main.ts" is enough for Vite to work, and it doesn't require a fixed value to be changed later.

@jooola
Copy link
Contributor

jooola commented Jul 1, 2023

<h4 class="text-h4 py-2">{{ $t("Getting Started") }}</h4>

I would prefer to have keys here instead of the en_US string, I think I mentioned this already before.

e.g.: path.to-the.file.ComponentName.translate-key

There isn't a need to do that. src="/src/main.ts" is enough for Vite to work, and it doesn't require a fixed value to be changed later.

I meant within the legacy page. Development will happen on the legacy page,so the php code should be able to load the webapp files and take advantages of the vite dev server.

@zklosko
Copy link
Member Author

zklosko commented Jul 1, 2023

I would prefer to have keys here instead of the en_US string, I think I mentioned this already before.

That is the key. In this instance, the key is also the en_US string.

 I meant within the legacy page. Development will happen on the legacy page,so the php code should be able to load the webapp files and take advantages of the vite dev server.

I don't understand. Why can't we build and then serve the built pages instead of running through the dev server? Running through a dev server is much less secure and could be harder to rectify for a user if it crashes. This really doesn't seem like the simplest way forward.

@jooola
Copy link
Contributor

jooola commented Jul 2, 2023

That is the key. In this instance, the key is also the en_US string.

Yes, this is the current behavior with the PO files. Now that we have json files and vue-i18n, I would like to use keys instead (e.g. path-to.source.file.ComponentName.nested.greetings of the en_US source strings (e.g. Greetings from ComponentName). See https://vue-i18n.intlify.dev/guide/essentials/syntax.html

I don't understand. Why can't we build and then serve the built pages instead of running through the dev server? Running through a dev server is much less secure and could be harder to rectify for a user if it crashes. This really doesn't seem like the simplest way forward.

We have 2 environments, production and development. For production, we compile the multiple web app pages and serve them using some web server, the files aren't meant to change. For development, we will have to change the files often, and test the changes, we cannot rebuild the production setup every time.

Vite has a powerful development server, so we need to leverage this and use it in the dev setup while we develop the web app. This allows use to have hot reload, dev tools integration, and so on...

@zklosko
Copy link
Member Author

zklosko commented Jul 2, 2023

The development setup should also take advantages of the vite dev server, e.g.: <script type="module" src="http://localhost:5173/src/main.ts"></script>

Wouldn't doing this break any test builds we would do for the new web app?

@paddatrapper
Copy link
Contributor

How would it break tests?

@zklosko
Copy link
Member Author

zklosko commented Jul 25, 2023

If we're hard coding the URLs of script sources, it won't run on its own without that exact port setup. If we did that during dev, we would need to switch everything back and test it for production.

@jooola
Copy link
Contributor

jooola commented Jul 25, 2023

We leverage the app environement config to either setup the dev server or serve the production files, so this is not a problem.

The legacy dev setup will point to the webapp dev server, and the production with reference the files from the webapp build manifest.

This just needs a bit of php code, nothing fancy

@zklosko
Copy link
Member Author

zklosko commented Aug 30, 2023

@jooola Something like this for translations?

"ui.preview": "Vorschau",

@paddatrapper
Copy link
Contributor

"ui.preview": "Vorschau",

Yes, though I'm not sure this is actually a good idea with how weblate works. Using a source language helps translators know what meaning the string is supposed to have in the context that it is used.

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.

Proposal: Initialize Vue Env
4 participants