import QtQuick import qs.Commons import qs.Ui // ServerStage.qml - Where a server provider is, and whether it needs a key. // // One stage of the claude-mode panel. Panel.qml hands itself in as `panel` // and owns all the state and actions; this file only draws them. Column { id: stage required property var panel width: parent.width visible: stage.panel.stage === "server" spacing: Style.space(8) Text { width: parent.width text: "Server for '" + stage.panel.serverPreset + "'" color: Color.popups.text elide: Text.ElideRight font.family: stage.panel.uiFont font.pixelSize: Style.space(13) font.bold: true } Text { width: parent.width text: stage.panel.serverHint color: Color.muted wrapMode: Text.WordWrap lineHeight: 1.2 font.family: stage.panel.uiFont font.pixelSize: Style.space(10) } TextField { id: urlField width: parent.width text: stage.panel.serverUrl placeholderText: stage.panel.serverDefault !== "" ? stage.panel.serverDefault : "https://…" foreground: Color.popups.text font.family: stage.panel.uiFont font.pixelSize: Style.space(11) onTextChanged: stage.panel.serverUrl = text onAccepted: stage.panel.saveServerSettings() } // Flow, not Row: these can total more than the card is wide, and a // Row lays them straight past its right edge instead of wrapping. Flow { width: parent.width spacing: Style.space(7) // A custom endpoint has no usual address to go back to. PillButton { fontFamily: stage.panel.uiFont; label: "Use local default" visible: stage.panel.serverDefault !== "" onTriggered: { stage.panel.serverUrl = stage.panel.serverDefault; urlField.text = stage.panel.serverDefault } } } PanelSeparator { width: parent.width } Row { width: parent.width spacing: Style.space(9) ToggleSwitch { id: authToggle anchors.verticalCenter: parent.verticalCenter checked: stage.panel.serverNeedsKey foreground: Color.popups.text accent: Color.accent onToggled: stage.panel.serverNeedsKey = !stage.panel.serverNeedsKey } Column { anchors.verticalCenter: parent.verticalCenter width: parent.width - authToggle.width - parent.spacing spacing: Style.space(1) Text { width: parent.width text: "Server requires an API key" color: Color.popups.text elide: Text.ElideRight font.family: stage.panel.uiFont font.pixelSize: Style.space(11) } Text { width: parent.width text: stage.panel.serverNeedsKey ? "Kept in the vault as '" + stage.panel.serverKeyRef + "', never in settings.json." : "Sends " + stage.panel.pTitle(stage.panel.serverProvider) + "'s placeholder token, which is not a secret." color: Color.muted wrapMode: Text.WordWrap font.family: stage.panel.uiFont font.pixelSize: Style.space(10) } } } // Flow, not Row: these can total more than the card is wide, and a // Row lays them straight past its right edge instead of wrapping. Flow { width: parent.width spacing: Style.space(7) visible: stage.panel.serverNeedsKey PillButton { fontFamily: stage.panel.uiFont; label: "Store the key…"; onTriggered: stage.panel.storeServerKey() } } PanelSeparator { width: parent.width } // Flow, not Row: these can total more than the card is wide, and a // Row lays them straight past its right edge instead of wrapping. Flow { width: parent.width spacing: Style.space(7) PillButton { fontFamily: stage.panel.uiFont; label: "Save"; primary: true; onTriggered: stage.panel.saveServerSettings() } PillButton { fontFamily: stage.panel.uiFont; label: stage.panel.serverReturn !== "" ? "Back" : "Cancel" onTriggered: { if (stage.panel.serverReturn !== "") stage.panel.stage = stage.panel.serverReturn else stage.panel.resetFlow() } } } }