Skip to content

Conditional “X-Prompt” in Angular Schematics #18578

Closed

Description

@Ankit-sagar32

It seems feature to add conditional x-prompts is missing in angular schematics.

Requirement : To display conditional prompts, based on the previous selection ( "Analytics", in this case ).

Problem : For any selection, it is still displaying the prompt to add Google Analytics's Tracking Id even if i select AppDynamics or none.

References : Applying Subschemas Conditionally
Angular Schematics

Note: For Simplicity, i have removed "allOf","anyOf" etc. and code for any other analytics tool, still it was not working.

Code (Schema.json):

{
  "$schema": "http://json-schema.org/schema",
  "id": "MyDemoSchema",
  "title": "My Demo Schematics Schema",
  "type": "object",
  "properties": {
    "analytics": {
      "enum": [
        "none",
        "GoogleAnalytics",
        "AppDynamics"
      ],
      "x-prompt": "Which Analytics would you like to use?"
    }
  },
  "if": {
    "properties": {
      "analytics": {
        "const": "GoogleAnalytics"  
      }
    }
  },
  "then": {
    "properties": {
      "GoogleAnalytics": {
        "type": "string",
        "x-prompt": "Enter Tracking ID?"
      }
    }
  }
}

Activity

  1. transferred this issue fromangular/angularon Aug 19, 2020
  2. modified the milestone: Backlog on Aug 19, 2020
  3. changed the title [-]Conditional “X-Prompt” in Angular Scehmatics[/-] [+]Conditional “X-Prompt” in Angular Schematics[/+] on Aug 19, 2020
  4. Stupidism commented on Dec 16, 2020

    @Stupidism

    Any progress or workaround?

  5. kroeder commented on Aug 23, 2021

    @kroeder

    I have the same goal but a different proposal. Instead of increasing the basic schema.json feature-set, I'd rather use a second function-driven API. I believe adding a condition API to a json file will increase the complexity tremendously.

    Here's a proposal. It certainly contains lots of flaws and is meant as a start to discuss further possible approaches.

    collection.json

    {
      "$schema": "../../../node_modules/@angular-devkit/schematics/collection-schema.json",
        "dynamic-generate-props": {
            "description": "Dynamic inputs",
            "factory": "./dynamic/index#dynamicSchematic",
            "schema": "./dynamic/schema#conditionalInputs"
        }
      }
    }

    dynamic/schema.ts#conditionalInputs

    /**
     * User code
     */
    interface MyInput {
        name: string;
        path: string;
        needsFooter: boolean;
        footerColor?: FooterColor;
    }
    
    type FooterColor = 'blue' | 'green' | 'red';
    
    export function conditionalInputs() {
        return schematicsSchema<MyInput>({
            name: () => createInput({
                type: InputTypes.STRING,
                xPrompt: "Name of your component"
            }),
            path: () => executionPath(),
            needsFooter: () => createInput({
                type: InputTypes.BOOLEAN,
                xPrompt: "Do you need a footer?"
            }),
            footerColor: (prevValues) => prevValues.needsFooter 
                ? createInput({
                    type: InputTypes.ENUM,
                    enum: [
                        "blue",
                        "green",
                        "red"
                    ],
                    xPrompt: "Footer color"
                })
              : noop()
        })
    }

    Angular framework (pseudo code)

    enum InputTypes { STRING, BOOLEAN, NUMBER, ENUM }
    type InputFunction<TInput> = { [key: string]: (prevValues?: TInput) => any; }
    
    function schematicsSchema<TInput>(userInputs: InputFunction<TInput>) {
        return {};
    }
    
    function createInput(options: any) {}
    
    function executionPath() {}
    
    function noop() {}

    Having an interface in the user code is intentional. Right now, if I am writing a schematic, the input properties are not typed and I need to manage two lists of inputs in parallel (schema.json inputs / schematic factory code input type)

    Any thoughts on this? Or maybe disagreement to a TS API? 🙂

  6. tomeustace commented on Aug 27, 2021

    @tomeustace

    I think you are correct that there is potential for the json to become unwieldy. However, the json approach seems like it would be more consistent and simpler to author, for most use cases. Maybe there's a case for beginning with json and allow for more powerful use cases to use what you suggest?

  7. kroeder commented on Aug 27, 2021

    @kroeder

    Exactly! I might have not been clear enough

    My intention was to allow two types of schema sources.

    Json: easy to use for easy use cases
    Ts: advanced use cases, leaving the easy to use area (though, with a good api it could still be easy enough)

  8. angular-robot commented on Feb 2, 2022

    @angular-robot
    Contributor

    Just a heads up that we kicked off a community voting process for your feature request. There are 20 days until the voting process ends.

    Find more details about Angular's feature request process in our documentation.

  9. modified the milestones: Backlog, needsTriage on Feb 2, 2022
  10. Jordan-Hall commented on Feb 12, 2022

    @Jordan-Hall

    I have the same goal but a different proposal. Instead of increasing the basic schema.json feature-set.

    This wouldn't exactly be increasing the schema.json rather than implementing draft-7 of Json schema.

    As for your typing solution https://ajv.js.org/guide/schema-language.html#json-type-definition I imagine that would be good enough.

    Angular currently uses AJV for validation and running the registry. Looking through the code I cant see it being to difficult to add support for a typed implementation.

    With that said I think to add xprompt support its changing the code around this section

    await this._applyPrompts(data, definitions);
    however thats only from a brief look.

  11. Jordan-Hall commented on Feb 12, 2022

    @Jordan-Hall

    @Ankit-sagar32 have you tried this way:

    {
      type: "integer",
      minimum: 1,
      maximum: 1000,
      if: {minimum: 100},
      then: {multipleOf: 100},
      else: {
        if: {minimum: 10},
        then: {multipleOf: 10}
      }
    }
    
    

    I know officially documentation says it should us const. But AJV says this is the way.

  12. added
    feature: under considerationFeature request for which voting has completed and the request is now under consideration
    and removed
    feature: votes requiredFeature request which is currently still in the voting phase
    on Feb 12, 2022
  13. dgp1130 commented on Aug 4, 2022

    @dgp1130
    Collaborator

    Duplicate of #22242

  14. dgp1130 commented on Aug 4, 2022

    @dgp1130
    Collaborator

    Using #22242 as the canonical issue here around the general feature request of "making schematics options more dynamic". Exposing the if/then syntax of JSON schema is probably too specific to this particular dependency and tricky to reason about. Most likely this would like a TypeScript API to prompt users imperatively.

  15. angular-automatic-lock-bot commented on Sep 4, 2022

    @angular-automatic-lock-bot

    This issue has been automatically locked due to inactivity.
    Please file a new issue if you are encountering a similar or related problem.

    Read more about our automatic conversation locking policy.

    This action has been performed automatically by a bot.

  16. locked and limited conversation to collaborators on Sep 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: @angular-devkit/schematicsfeatureLabel used to distinguish feature request from other issuesfeature: under considerationFeature request for which voting has completed and the request is now under consideration

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions