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

Angular Integration (into an already existing application) #149

Open
ejthan opened this issue May 14, 2020 · 39 comments
Open

Angular Integration (into an already existing application) #149

ejthan opened this issue May 14, 2020 · 39 comments
Assignees
Labels

Comments

@ejthan
Copy link

ejthan commented May 14, 2020

Hi this looks very promising.

At the moment i do not understand how this could be integrated into an already existing Angular application.

For example, i would like to use this in an already existing angular ecommerce application.
I don't need the full implementation, i would like to use the editor only on specific pages.

Is there any chance you could explain, how a possible implementation into an already existing app would look like?

@azaslonov
Copy link
Member

azaslonov commented May 15, 2020

Hi @ejthan, short answers would be to look at pageHost.ts file which you can find in paperbits-core module. We didn't really design it to be used the way you're asking about, but with some refactoring it can be achieved fairly cheap . If you decide to go with Paperbits, we can assess it properly and work together to solve it.

@pandabuilt
Copy link

Yes, this is what I'm interested in. Paperbits functionality is only.a small bit of my app that people who use our app will build small pages with. The rest of the app will have nothing to do with Paperbits only a small section.

@ejthan you want to work together? They have some contribution guidelines

@azaslonov thanks for your response. Are you implying you are working on it?

@ejthan
Copy link
Author

ejthan commented May 18, 2020

@pandabuilt yes i would like to work together, i'm a product manager and i'm new to coding... so i'm not sure if i can be very helpful. We have an angular developer at the company i work for, i will check if he is able to help us but he probably won't be able to do so until August.

@azaslonov
Copy link
Member

@pandabuilt we're working on integration stories: one of them is having widgets in a number of UI frameworks (including Angular), and the other one I hear about is partial integration (similar to what you guys described above), and we are assessing it now.

I also have a few questions to better understand the scope:

  • What format you store content? (if you went through our key concepts, you know that we output JSON for all parts of content and have publishing step to generate actual HTML. Does this work in your case?)
  • What about styling? Do you need the entire styling system? Style editors? How does this fit to your app?
  • What is your app lifecycle? What is content lifecycle?

@azaslonov azaslonov self-assigned this May 19, 2020
@pandabuilt
Copy link

  • What format you store content? (if you went through our key concepts, you know that we output JSON for all parts of content and have publishing step to generate actual HTML. Does this work in your case?)

JSON will always work. I'd rather have you handle the publishing than me.

  • What about styling? Do you need the entire styling system? Style editors? How does this fit to your app?

I would say yes, I'd like users to style.

  • What is your app lifecycle? What is content lifecycle?

The lifecycle is to add "Builder" module and create / edit screens and publish them. When they are published (not draft status) they are live in the users plugin. I am looking into storing versions and also thinking about storing default templates they can start from.

@ejthan
Copy link
Author

ejthan commented May 19, 2020

Our idea for implementing paperbits in our app would look like this:

paperbits is inserted as an angular component.
The component serves as a wrapper class in which the logic of the paperbits editor is used.

The logic to create new pages is already available in our app, so we do not need it again.

Saving styles, layouts and adding new widgets would then work in the same way as the already implemented logic of paperbits.

@pandabuilt
Copy link

pandabuilt commented May 20, 2020

So like something like :
<paperbits (output)="jsonPublished"></paperbits>
?

That would work for me.

@azaslonov
Copy link
Member

azaslonov commented May 20, 2020

Ok, that makes sense. I believe that you can do your PoC even now:
You can attach the paperbits app to an element (inside your Angular widget template) with ko.applyBindings(undefined, yourElement) (see startup.design.ts in paperbits-demo), and use StaticObjectStorage (in paperbits-demo) as a starting point, it has Save and Load methods that could be adapted to [input] and (output).

@pandabuilt
Copy link

pandabuilt commented May 29, 2020

Okay, @azaslonov got it. I will create a component.

As far as dependencies go for the component? Is it correct that I will need the following:
"@paperbits/common": "0.1.284", "@paperbits/core": "0.1.284", "@paperbits/emails": "0.1.284", "@paperbits/firebase": "0.1.284", "@paperbits/forms": "0.1.284", "@paperbits/gtm": "0.1.284", "@paperbits/intercom": "0.1.284", "@paperbits/prosemirror": "0.1.284", "@paperbits/styles": "0.1.284",

@pandabuilt
Copy link

@azaslonov Is that correct to add to my existing angular project?

@azaslonov
Copy link
Member

azaslonov commented Jun 17, 2020

Hi @pandabuilt, sorry, I missed your previous message somehow. So, answering that one first:
"@paperbits/common", "@paperbits/core", "@paperbits/prosemirror" and "@paperbits/styles" for sure, the others are just extensions.

Not sure what exactly you mean. I guess there are two ways of integration:

  1. You bring paperbits into your project as an Angular component(s) (the one we discussed above).
  2. You bring your Angular components into paperbits as runtime widgets (see example here).

@pandabuilt
Copy link

@azaslonov I'm doing 1 (discussed here) Paperbits is only a part of my project.

@azaslonov
Copy link
Member

So yes, those libs I mentioned are the required minimum for paperbits to run. And startup.ts in paperbits-demo is a good bootstrapping example that you can do inside your Angular component.

Please let me know if you need help with that.

@tmmschmit
Copy link

Hi, I'm interested by this too, i've already discussed with @azaslonov the procedure to follow to achieve this. But I'm stuck with many compilation errors in the module :

Screenshot from 2020-07-22 09-18-46

@pandabuilt have you seen this type of errors ?

I don't understand how Angular can compile a Knockout module... 🤔

Thanks.

@azaslonov
Copy link
Member

Hi @tmmschmit, I assume you created a new project and trying to move some parts there. So, this one happens because of missing module.d.ts (please see ./src/module.d.ts). Another thing that might come up is webpack's html-loader (see webpack.designer.js).

@azaslonov
Copy link
Member

Btw, we published basic information about that integration here https://paperbits.io/wiki/ui-frameworks#A1Jea. We'll continue to work on it, so please check back there from time to time.

@tmmschmit
Copy link

Thanks again @azaslonov, the module.d.ts fix many compilation errors. i still have some errors :

Screenshot from 2020-07-23 09-23-15

For the two first one, i think you override these functions in staticSettingsProvider.ts, but for the Knockout errors, i haven't find yet ; i installed the same Knockout modules as you :

    "knockout": "^3.5.1",
    "knockout-mapping": "^2.6.0",
    "knockout.validation": "^2.0.4",

in dev deps : 
 "@types/knockout": "^3.4.67",
 "@types/knockout.mapping": "^2.0.35",
 "@knockout.validation": "^0.0.37",

🤔

@starostin
Copy link

starostin commented Oct 5, 2020

Hi @azaslonov ! I am also trying to insert paperbits as separate component to my angular app. Could you please advise what should I do? Because description in documentation is not very clear for me. Should I build designer app and include js files angular.json of my application?

@pandabuilt
Copy link

@starostin Hi. I hope @azaslonov doesn't mind me chiming in. He's helped me so much

Go check out @paperbits/examples and they have a ui example for angular in that repo.

Step 1 - add paperbits packages to package.json - currently I have:

"@paperbits/common": "0.1.328",
"@paperbits/core": "0.1.328",
"@paperbits/prosemirror": "0.1.328",
"@paperbits/styles": "0.1.328",

You're going to need Jeb's @angular-builders/custom-webpack package - Just checkout that example repo for all the packages. Just run a diff against your angular app.

Cause you have an entire angular app. You'll want to proceed with caution. Your building will change by following his examples

Step 2. Diff check their angular.json compared to yours.... change what you need to to ensure the new builder is used....

Step 3. Make sure your tsconfig.json / tsconfig.app.json are similar

Step 4. Copy over webpack.config.js into your root folder

Step 5. Add any missing polyfills

Step 6. Add import "./paperbits/startup.design"; to your main.ts

Step 7. Build your component with Make sure that you import this into the module.

@pandabuilt
Copy link

Hi @azaslonov ! I am also trying to insert paperbits as separate component to my angular app. Could you please advise what should I do? Because description in documentation is not very clear for me. Should I build designer app and include js files angular.json of my application?

ENSURE this is in your tsconfig.app.json - "emitDecoratorMetadata": false

@starostin
Copy link

starostin commented Oct 6, 2020

Thanks a lot guys. Now it works fine. And I am trying to get data from staticObjectStorage in my main angular app. So I have created service, registered it in demo.design.module like this
injector.bindSingleton("paperbitsService", PaperbitsService);
And than use it in staticObjectStorage. And it works fine. But the issue that when I try to use this service from the angular app, it creates second instance. As I understand I have injected service in paperbits app and in angular app, that is why I have 2 instances. But seems I need to use 1 instance. Can you please help me with that? Thanks in advance

@azaslonov
Copy link
Member

I think that's because Angular has it's own DI container (this, btw, is something for us to look in the future). What you can do is to register same instance of the service, if possible:

const myService = new MyService()

Angular
{ provide: MyService, useValue: myService }

Paperbits
injector.bindInstance("myService", myService)

@starostin
Copy link

Thanks @azaslonov, I am using the same approach. Also I wanted to ask, is it possible to reload design app component with different json?. So I have angular app which is sending website json to the server and save in to db (it is already done), and also I need the ability to get json from the server and show website from it. I see in staticObjectStorage getData method which is loading data from the file (demo.json), I have modified this method a bit to be able to get json as parameter. But any way, I see that website loading from localStorage default/stateObject, so seems I need to clear it before setting json from server. But it looks a bit weird. Is there any other normal way to do that?

@azaslonov
Copy link
Member

azaslonov commented Oct 7, 2020

Ok, this one is simple, there is a default registration of ILocalCache:
injector.bindSingleton<ILocalCache>("changesCache", LocalStorageCache);

You can either replace it (in startup.design.ts) with, i.e. instance of MemoryCache (@paperbits/common/caching/memoryCache) and clear it when required, or just implement your own thing and bind required logic to it (maybe you'll have cache per widget or something else).

@starostin
Copy link

starostin commented Oct 8, 2020

Thanks @azaslonov , each day I am learning something new. So I have changed changesCache to MemoryCache. And now when I load json from the server I call changesCache.clear() and then changesCache.setItem('stateObject', json). And after that I am rerendering paperbits component. But nothing changes after it. Am I doing something wrong? As i understand designer read data from this cache module, and should apply my new json, or not?

@starostin
Copy link

starostin commented Oct 8, 2020

And also I found that when I rerender the component, and then try to navigate in designer app I am getting error.
Screenshot 2020-10-08 at 11 06 10
Or may be there are some method exist to rerender designer app? Without rerendering component from angular?

@starostin
Copy link

starostin commented Oct 9, 2020

I have found solution. So I don't rerender angular component, I am using loadData from staticObjectStorage, and after this I am dispatching event

eventManager.dispatchEvent("onDataPush");
eventManager.dispatchEvent("onDataChange");

or also I can use eventManager.dispatchEvent("onLoadData", data);, but in that case I need to override some methods a bit, in order to pass data in arguments. So my whole solution looks like this

   await objectStorage.discardChanges()
   await remoteObjectStorage.loadData(data);
   eventManager.dispatchEvent("onDataPush");
   eventManager.dispatchEvent("onDataChange");

@starostin
Copy link

After that I have tried to update layout (made top menu vertical), and tried to refresh website (like I described in previous post), but it did not work. It there some other way to update layout?

@azaslonov
Copy link
Member

You mean you update layout through designer? Or you push data?

@starostin
Copy link

Update layout through designer, and after that tried to load other website from server, but it does not work. Without changing layout it works fine

@azaslonov
Copy link
Member

azaslonov commented Oct 9, 2020

Sorry, just to understand, you changed a layout of one website and wanted to apply it to another website? Could you please describe the scenario a bit more?

@starostin
Copy link

No, I changed the layout of one website, and just want to load different website from the server, without applying any changes which I made (so they will be lost)

@azaslonov
Copy link
Member

I see, I think could reproduce this. You changed the layout, and without exiting layout editing, tried to load another website data, right?

@starostin
Copy link

Actually, seems I exited layout editing. I pressed Esc on the keyboard and it closed Editing mode

@starostin
Copy link

But interesting thing, that when I start preview mode, go to different page, and go back, I see that website changed

@azaslonov
Copy link
Member

Ok, we never thought about this scenario, I guess we'll bring some kind of "reset" operation. For now, I think what you can do is to invoke this.viewManager.setHost({ name: "page-host" }); in addition to:

   await objectStorage.discardChanges()
   await remoteObjectStorage.loadData(data);
   eventManager.dispatchEvent("onDataPush");
   eventManager.dispatchEvent("onDataChange");

@starostin
Copy link

It does not work for me. And also I debugged a bit, and see that this.viewManager.mode is paused. That is why refreshContent is not called in 'layoutHosts.ts' file. Is it a bug?

@azaslonov
Copy link
Member

Not sure yet. Give me 2-3 days, I'll investigate and make adjustments.

@starostin
Copy link

starostin commented Oct 12, 2020

Also I have an error in demo app when try to use ClickCounter widget from angular
Screenshot 2020-10-12 at 13 52 54

When I use this widget from other frameworks- everything works fine

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants