Giter Club home page Giter Club logo

Comments (15)

K-Kumar-01 avatar K-Kumar-01 commented on June 9, 2024 1

I would try the following approaches:

  1. Use delete with keepContent set to false. This API can be triggered from the Word Add-in (maybe the document panel). We can instruct a user to not delete the clause by deleting the content control directly but instead we can render a button in document panel which will trigger the above mentioned API.
  2. Similar to the above approach, you can first use the delete API for removing the CustomXMLPart and then you can remove the content control. Again, the user is expected to click a button and launch this API.
  3. I am not sure about this but maybe we can again use Office.EventType.BindingDataChanged. Whenever a user deletes the content of the content control, this event will launch and delete the XML too. However, this might be unsafe as user can delete the content control directly so this event would never trigger in that case. Moreover, I remember that I have made the content inside a content control not editable.

I agree the best approach would have been what you mentioned but as far as I recollect these preview APIs don't work even in the development environment. Anyway, they have suggested to not use it for now so let's keep it that way.

@algomaster99
Thanks for the help and clarification. I will try to implement and see if we are able to find an effective solution from these.

from cicero-word-add-in.

algomaster99 avatar algomaster99 commented on June 9, 2024 1

Yes it keeps on crashing and reloading.

That's weird. But I hope you figure out. It is tough to find things related to MS Word add-in development.

Could you please once again clarify what is meant by the above.

Sure.

  1. Append the template identifier to the state in document component whenever a contract is added to the document using the library component.
  2. Render this list of template identifiers in the document component. Make sure you also render a button corresponding to each list item (template identifiers).
  3. Whenever you click the delete button, the following should take place
    1. Delete the content control for the entire contract/clause including its content.
    2. Delete the XML node containing the template identifier.
    3. Delete the template identifier from the state you are maintaining.

When you reinitialise the document, make sure you populate the state maintained in your document component using the template identifier stored in CustomXML.

from cicero-word-add-in.

algomaster99 avatar algomaster99 commented on June 9, 2024

This is a very good issue! Looking forward to PR for this.

from cicero-word-add-in.

K-Kumar-01 avatar K-Kumar-01 commented on June 9, 2024

Going to work on this now

from cicero-word-add-in.

K-Kumar-01 avatar K-Kumar-01 commented on June 9, 2024

@algomaster99
I need some help with this issue.
I was trying to use this one. However, it states that API should not be used in a production environment. So shall we go with this?

Also, I had some difficulties setting this up in the code.

from cicero-word-add-in.

algomaster99 avatar algomaster99 commented on June 9, 2024

I would try the following approaches:

  1. Use delete with keepContent set to false. This API can be triggered from the Word Add-in (maybe the document panel). We can instruct a user to not delete the clause by deleting the content control directly but instead we can render a button in document panel which will trigger the above mentioned API.
  2. Similar to the above approach, you can first use the delete API for removing the CustomXMLPart and then you can remove the content control. Again, the user is expected to click a button and launch this API.
  3. I am not sure about this but maybe we can again use Office.EventType.BindingDataChanged. Whenever a user deletes the content of the content control, this event will launch and delete the XML too. However, this might be unsafe as user can delete the content control directly so this event would never trigger in that case. Moreover, I remember that I have made the content inside a content control not editable.

I agree the best approach would have been what you mentioned but as far as I recollect these preview APIs don't work even in the development environment. Anyway, they have suggested to not use it for now so let's keep it that way.

from cicero-word-add-in.

K-Kumar-01 avatar K-Kumar-01 commented on June 9, 2024

@algomaster99
Based on what you suggested, I have thought of a particular solution. Let me know if this can be done.

  1. In the Document component, we will keep track of the inserted templates.
  2. Also a state templatesIns can be made to keep track of OOXML of inserted templates. So the complete OOXML of the templates can be rendered using this.
  3. The templates can be kept non-deletable in the beginning. When we click on the document component, we can delete the templates from there using OfficeJs API.
  4. Also using the 3, we can delete the XML part present.

In this way, we can ensure users delete from one place only and insert from one place only thereby providing some safety.

The deletable thing can also be switched with add to document instead of the document.

if(template)render delete_template;
else render add_to_template

MAJOR DRAWBACK: If a user types anything other than the template and then deletes any template, the typed thing will vanish.

Since the debugger is not working, I am not able to debug my approach. As a result, I have posted it here to get some feedback on whether we should proceed with this or not?

from cicero-word-add-in.

algomaster99 avatar algomaster99 commented on June 9, 2024

Also a state templatesIns can be made to keep track of OOXML of inserted templates. So the complete OOXML of the templates can be rendered using this

Not sure what you mean by this. I am assuming you want to render the templates using the React state when document reopens, right? If that is the case, it is not the best way to go through because you will have to update the state first using CustomXMLPart. Better to directly use the latter to do so.

The deletable thing can also be switched with add to document instead of the document.

For now, let's keeping inserting from library component only.

If a user types anything other than the template and then deletes any template, the typed thing will vanish.

I think unlike because the you are supposed to delete 3 things only - content control, the content inside, and the XML node in CustomXMLPart. Anything outside the content control should be unaffected.

Also a state templatesIns can be made to keep track of OOXML of inserted templates. So the complete OOXML of the templates can be rendered using this

Do you mean the devtools is not working?

Yes, the approach sounds good. Proceed by creating a button. Add a JS event listener which will get triggered onclick. Delete the content control and its content inside. Once that's done, finish the process by deleting the XML node in the CustomXMLPart.

from cicero-word-add-in.

K-Kumar-01 avatar K-Kumar-01 commented on June 9, 2024

Do you mean the devtools is not working?

Yes it keeps on crashing and reloading. There's also a thread in slack where the full information regarding this is available

Yes, the approach sounds good. Proceed by creating a button. Add a JS event listener which will get triggered onclick.

I apologise but I got confused as to follow which approach and which things. 😅
Could you please once again clarify what is meant by the above.
Thanks

from cicero-word-add-in.

K-Kumar-01 avatar K-Kumar-01 commented on June 9, 2024

@algomaster99
Thanks for the explanation.
Also I will try to see if I am able to find anything to solve the debugging issue.

from cicero-word-add-in.

algomaster99 avatar algomaster99 commented on June 9, 2024

No problem. Let me know if you have any more follow up questions about the implementation.

from cicero-word-add-in.

K-Kumar-01 avatar K-Kumar-01 commented on June 9, 2024

@algomaster99
I was implementing the code but I am stuck at a particular place.

              if (!identifierExists) {
                setup(ciceroMark, template);
                newXml += `<template xmlns="${templateIdentifier}" />`;
                newXml += '</templates>';
                Office.context.document.customXmlParts.getByNamespaceAsync(CUSTOM_XML_NAMESPACE, res => {
                  if (res.status === Office.AsyncResultStatus.Succeeded) {
                    for (let index=0; index<res.value.length; ++index) {
                      res.value[index].deleteAsync();
                    }
                  }
                });
                Office.context.document.customXmlParts.addAsync(newXml);
              } else {
                console.log('XML NOW', newXml);
                Office.context.document.customXmlParts.getByNamespaceAsync(CUSTOM_XML_NAMESPACE, res => {
                  if (res.status === Office.AsyncResultStatus.Succeeded) {
                    for (let index=0; index<res.value.length; ++index) {
                      res.value[index].deleteAsync();
                    }
                  }
                });
                Office.context.document.customXmlParts.addAsync(newXml);
                toast(
                  {
                    title: 'Duplicate template',
                    description: <p>Template cannot be inserted as it is already present in the document.</p>,
                    type: 'error',
                    time: 5000,
                    animation: 'fly down',
                  },
                );
              }

This code is the part where we insert more than one template. So from what I Understood if the template to be inserted is not present. Then the newXML will include our template identifier.
Also, this is the code which removes the old Custom XML and inserts the new XML.

                Office.context.document.customXmlParts.getByNamespaceAsync(CUSTOM_XML_NAMESPACE, res => {
                  if (res.status === Office.AsyncResultStatus.Succeeded) {
                    for (let index=0; index<res.value.length; ++index) {
                      res.value[index].deleteAsync();
                    }
                  }
                });
                Office.context.document.customXmlParts.addAsync(newXml);

Now, if the identifier is already present, then we need to remove the oldXML.

                Office.context.document.customXmlParts.getByNamespaceAsync(CUSTOM_XML_NAMESPACE, res => {
                  if (res.status === Office.AsyncResultStatus.Succeeded) {
                    for (let index=0; index<res.value.length; ++index) {
                      res.value[index].deleteAsync();
                    }
                  }
                });
                Office.context.document.customXmlParts.addAsync(newXml);

As visible, both the conditions when the template is present and when it is not present use the same code. However, in the second case, the custom XML parts are not being added to the document again. I am quite not able to understand the reasoning for this. The removal of the nodes is happening but not the insertion again.

testing.zip
I have attached a zip file that contains the OOXML for the different processes made.
Let me know if there is any explanation that I have missed.

from cicero-word-add-in.

algomaster99 avatar algomaster99 commented on June 9, 2024

@K-Kumar-01 I would appreciate if you could submit a WIP pull request of the implementation. It will be easier for me to debug.

from cicero-word-add-in.

K-Kumar-01 avatar K-Kumar-01 commented on June 9, 2024

@algomaster99 Yeah sure I will submit a draft PR. I will clean the code a bit and then submit it ASAP.

from cicero-word-add-in.

K-Kumar-01 avatar K-Kumar-01 commented on June 9, 2024

@algomaster99
I have made a WIP PR. Thanks for the guidance in advance :)

from cicero-word-add-in.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.