From e5332068787503d8d901ae7f848bcdad8fef8f25 Mon Sep 17 00:00:00 2001 From: Tim Berners-Lee Date: Thu, 29 Aug 2024 13:48:40 -0400 Subject: [PATCH 01/10] remove licenseOptions code and call --- src/outline/licenseOptions.js | 105 ---------------------------------- src/outline/manager.js | 9 --- 2 files changed, 114 deletions(-) delete mode 100644 src/outline/licenseOptions.js diff --git a/src/outline/licenseOptions.js b/src/outline/licenseOptions.js deleted file mode 100644 index 6b6e63b..0000000 --- a/src/outline/licenseOptions.js +++ /dev/null @@ -1,105 +0,0 @@ -// This was a student project to -// allow the user to chose favoite CC license terms and have them highlighted - -// tabulator.options becaome UI.licenseOptions -// Possible future alternative directoons: Store license preferences in a solid preferences file -import { store } from 'solid-logic' - -export const licenseURI = [ - 'http://creativecommons.org/licenses/by-nc-nd/3.0/', - 'http://creativecommons.org/licenses/by-nc-sa/3.0/', - 'http://creativecommons.org/licenses/by-nc/3.0/', - 'http://creativecommons.org/licenses/by-nd/3.0/', - 'http://creativecommons.org/licenses/by-sa/3.0/', - 'http://creativecommons.org/licenses/by/3.0/' -] - -const names = ['BY-NC-ND', 'BY-NC-SA', 'BY-NC', 'BY-ND', 'BY-SA', 'BY'] - -export function licenseOptions () { - this.options = {} - this.references = [] - this.checkedLicenses = [] - - this.openCheckBoxWindow = function () { - this.this.display = window.open( - ' ', - 'NewWin', - 'menubar=0,location=no,status=no,directories=no,toolbar=no,scrollbars=yes,height=200,width=200' - ) - } - let message = "
" - const lics = this.checkedLicenses - for (let kk = 0; kk < lics.length; kk++) { - message += - "CC: ' + - names[kk] + - '
' - } - - message += - "
[Select All] " // @@ FIXME - message += " [Deselect All]" // @@ FIXME - message += '
' - - this.display.document.write(message) - - this.display.document.close() - - let i - for (i = 0; i < 6; i++) { - this.references[i] = this.this.display.document.checkboxes.elements[i] - } - - this.selectAll = function () { - let i - for (i = 0; i < 6; i++) { - this.display.document.checkboxes.elements[i].checked = true - this.references[i].checked = true - this.checkedLicenses[i] = true - } - } - - this.deselectAll = function () { - let i - for (i = 0; i < 6; i++) { - this.display.document.checkboxes.elements[i].checked = false - this.references[i].checked = false - this.checkedLicenses[i] = false - } - } - - this.submit = function () { - // alert('this.submit: checked=' + this.references[0].checked) - for (let i = 0; i < 6; i++) { - this.checkedLicenses[i] = !!this.references[i].checked - } - } - - this.checkLicense = function checkLicense (statement) { - const licenses = store.each( - statement.why, - store.sym('http://creativecommons.org/ns#license'), - null, - statement.why - ) - // UI.log.info('licenses:' + statement.why + ': ' + licenses) - for (let i = 0; i < licenses.length; i++) { - for (let j = 0; j < this.checkedLicenses.length; j++) { - if (this.checkedLicenses[j] && licenses[i].uri === licenseURI[j]) { - return true - // theClass += ' licOkay' // icon_expand - // break - } - } - } - return false - } - return this -} - -// ends diff --git a/src/outline/manager.js b/src/outline/manager.js index 12e780b..50541ab 100644 --- a/src/outline/manager.js +++ b/src/outline/manager.js @@ -7,8 +7,6 @@ import * as $rdf from 'rdflib' import * as UI from 'solid-ui' import { authn, authSession, store } from 'solid-logic' import { propertyViews } from './propertyViews' -import { licenseOptions } from './licenseOptions' - import { outlineIcons } from './outlineIcons.js' // @@ chec import { UserInput } from './userInput.js' import * as queryByExample from './queryByExample.js' @@ -179,13 +177,6 @@ export default function (context) { td.setAttribute('notSelectable', 'false') let theClass = 'obj' - // check the IPR on the data. Ok if there is any checked license which is one the document has. - if (statement && statement.why) { - if (licenseOptions && licenseOptions.checklicense && licenseOptions.checklicense()) { - theClass += ' licOkay' // flag as light green etc .licOkay {background-color: #dfd} - } - } - // set about and put 'expand' icon if ( obj.termType === 'NamedNode' || From bf639dd121b6f088c8a05a24187e152f2adbadb3 Mon Sep 17 00:00:00 2001 From: Tim Berners-Lee Date: Sat, 31 Aug 2024 09:33:53 -0400 Subject: [PATCH 02/10] fix ts errors in tests --- tsconfig.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tsconfig.json b/tsconfig.json index afd02da..2094252 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -53,6 +53,9 @@ "./typings" ] /* List of folders to include type definitions from. */, // "types": [], /* Type declaration files to be included in compilation. */ + + "types": ["node", "jsdom", "@testing-library/jest-dom"], /* https://medium.com/heybooster/debugging-typescript-jest-dom-matchers-in-vue-js-6962dab4d4cc */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ From 689656991eae28cb5f08d716012f98099cef6b78 Mon Sep 17 00:00:00 2001 From: Tim Berners-Lee Date: Tue, 3 Sep 2024 15:38:44 -0400 Subject: [PATCH 03/10] remove tests from exclude in tsconfig --- tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index 2094252..6fa7534 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -71,5 +71,5 @@ // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ }, "include": ["src/**/*"], - "exclude": ["node_modules", "**/*.test.ts"] + "exclude": ["node_modules"] // was , "**/*.test.ts" } From 5b5cbe734dbbea965a5b9b94195e97fe145eec9d Mon Sep 17 00:00:00 2001 From: Tim Berners-Lee Date: Tue, 3 Sep 2024 16:05:44 -0400 Subject: [PATCH 04/10] test also mbox anchor text --- src/outline/propertyViews.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/outline/propertyViews.test.ts b/src/outline/propertyViews.test.ts index 37766eb..df02a6e 100644 --- a/src/outline/propertyViews.test.ts +++ b/src/outline/propertyViews.test.ts @@ -30,6 +30,7 @@ describe('property views', () => { const view = views.defaults[property] const result = view(sym('mailto:alice@mail.example')) expect(result).toBeInstanceOf(HTMLAnchorElement) - expect(result).toHaveAttribute('href', 'mailto:alice@mail.example') + expect(result).toHaveAttribute('href', 'mailto:alice@mail.example'); + expect(result).toHaveTextContent('alice@mail.example'); }) }) From fcdc420285b0d407e8021556f7e375d5b87ce36b Mon Sep 17 00:00:00 2001 From: Tim Berners-Lee Date: Tue, 3 Sep 2024 16:07:02 -0400 Subject: [PATCH 05/10] types for jest-dom --- package.json | 2 +- tsconfig.json | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 245a784..99410b9 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "homepage": "https://github.com/solidos/solid-panes", "dependencies": { "@solid/better-simple-slideshow": "^0.1.0", + "@types/jest": "^29.5.12", "activitystreams-pane": "^0.6.13", "chat-pane": "^2.4.26", "contacts-pane": "^2.6.12", @@ -68,7 +69,6 @@ "@babel/preset-typescript": "^7.24.1", "@testing-library/dom": "^9.3.4", "@testing-library/jest-dom": "^6.4.2", - "@types/jest": "^29.5.12", "@types/webpack-env": "^1.18.4", "@typescript-eslint/eslint-plugin": "^6.21.0", "@typescript-eslint/parser": "^6.21.0", diff --git a/tsconfig.json b/tsconfig.json index 6fa7534..5d229f1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,4 +1,6 @@ { + // See https://stackoverflow.com/questions/54139158/cannot-find-name-describe-do-you-need-to-install-type-definitions-for-a-test + "compilerOptions": { /* Basic Options */ "target": "es5" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */, @@ -50,11 +52,12 @@ // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ "typeRoots": [ "node_modules/@types", + "node_modules/@testing-library", "./typings" ] /* List of folders to include type definitions from. */, // "types": [], /* Type declaration files to be included in compilation. */ - "types": ["node", "jsdom", "@testing-library/jest-dom"], /* https://medium.com/heybooster/debugging-typescript-jest-dom-matchers-in-vue-js-6962dab4d4cc */ + "types": ["node", "jsdom", "jest", "jest-dom"], /* https://medium.com/heybooster/debugging-typescript-jest-dom-matchers-in-vue-js-6962dab4d4cc */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ From 830a511a7be28fa6de4d7d22ca53b387b517200f Mon Sep 17 00:00:00 2001 From: Tim Berners-Lee Date: Sun, 15 Sep 2024 15:07:25 -0400 Subject: [PATCH 06/10] jest: mock ttl files --- jest.config.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/jest.config.js b/jest.config.js index a34f62e..645ace7 100644 --- a/jest.config.js +++ b/jest.config.js @@ -4,6 +4,9 @@ module.exports = { testEnvironmentOptions: { customExportConditions: ['node'] }, + moduleNameMapper: { + '^[./a-zA-Z0-9$_-]+\\.ttl$': '/__mocks__/fileMock.js', // '\\.ttl$' + }, collectCoverage: true, // For some reason Jest is not measuring coverage without the below option. // Unfortunately, despite `!(.test)`, it still measures coverage of test files as well: From e79e8eff1d4d667697fc8a51dfb7e45282fe0cc7 Mon Sep 17 00:00:00 2001 From: Tim Berners-Lee Date: Mon, 16 Sep 2024 08:22:23 -0400 Subject: [PATCH 07/10] Removed editProfile pane to profile-pane repo --- src/profile/editProfile.view.ts | 164 -------------- src/profile/profile.dom.ts | 20 -- src/profile/profileFormText.ttl | 386 -------------------------------- src/registerPanes.js | 7 +- 4 files changed, 5 insertions(+), 572 deletions(-) delete mode 100644 src/profile/editProfile.view.ts delete mode 100644 src/profile/profile.dom.ts delete mode 100644 src/profile/profileFormText.ttl diff --git a/src/profile/editProfile.view.ts b/src/profile/editProfile.view.ts deleted file mode 100644 index 7c2de5c..0000000 --- a/src/profile/editProfile.view.ts +++ /dev/null @@ -1,164 +0,0 @@ -/** - * Profile Editing App Pane - * - * Unlike view panes, this is available any place whatever the real subject, - * and allows the user to edit their own profile. - * - * Usage: paneRegistry.register('profile/profilePane') - * or standalone script adding onto existing mashlib. - */ - -import { PaneDefinition } from 'pane-registry' -import { NamedNode, parse, Store, sym } from 'rdflib' -import { icons, login, ns, style, widgets } from 'solid-ui' -import { paneDiv } from './profile.dom' -import profileFormText from './profileFormText.ttl' - -const highlightColor = style.highlightColor || '#7C4DFF' - -const editProfileView: PaneDefinition = { - global: true, - - icon: icons.iconBase + 'noun_492246.svg', - - name: 'editProfile', - - label: () => null, - - render: function (subject, context) { - const dom = context.dom - const store = context.session.store as Store - - function complainIfBad (ok: Boolean, mess: any) { - if (ok) return - div.appendChild(widgets.errorMessageBlock(dom, mess, '#fee')) - } - - function renderProfileForm (div: HTMLElement, subject: NamedNode) { - const preferencesForm = sym('https://solidos.github.io/solid-panes/dashboard/profileStyle.ttl#this') - const preferencesFormDoc = preferencesForm.doc() - if (!store.holds(undefined, undefined, undefined, preferencesFormDoc)) { - // If not loaded already - parse(profileFormText, store, preferencesFormDoc.uri, 'text/turtle', () => null) // Load form directly - } - - widgets.appendForm( - dom, - div, - {}, - subject, - preferencesForm, - editableProfile, - complainIfBad - ) - } // renderProfileForm - - const div = dom.createElement('div') - let editableProfile: NamedNode | null - div.setAttribute('style', `border: 0.3em solid ${highlightColor}; border-radius: 0.5em; padding: 0.7em; margin-top:0.7em;`) - - const table = div.appendChild(dom.createElement('table')) - // const top = table.appendChild(dom.createElement('tr')) - const main = table.appendChild(dom.createElement('tr')) - const bottom = table.appendChild(dom.createElement('tr')) - const statusArea = bottom.appendChild(dom.createElement('div')) - statusArea.setAttribute('style', 'padding: 0.7em;') - - function comment (str: string) { - const p = main.appendChild(dom.createElement('p')) - p.setAttribute('style', 'padding: 1em;') - p.textContent = str - return p - } - - function heading (str: string) { - const h = main.appendChild(dom.createElement('h3')) - h.setAttribute('style', 'color:' + highlightColor + ';') - h.textContent = str - return h - } - - const profileContext = { - dom: dom, - div: main, - statusArea: statusArea, - me: null - } - login.ensureLoadedProfile(profileContext) - .then(theContext => { - const me = theContext.me! - - heading('Edit your public profile') - - const profile = me.doc() - if (!store.updater) { - throw new Error('Store has no updater') - } - if (store.any(me, ns.solid('editableProfile'))) { - editableProfile = store.any(me as any, ns.solid('editableProfile')) as NamedNode - } else if (store.updater.editable(profile.uri, store)) { - editableProfile = profile - } else { - statusArea.appendChild(widgets.errorMessageBlock(dom, `⚠️ Your profile ${profile} is not editable, so we cannot do much here.`, 'straw')) - return - } - - comment(`Everything you put here will be public. - There will be other places to record private things.`) - - heading('Your contact information') - - main.appendChild(paneDiv(context, me, 'contact')) - - - heading('People you know who have WebIDs') - - comment(`This is your public social network. - Only put people here to whom you are happy to be publicly connected. - (You can always keep private track of friends and family in your contacts.)`) - - // TODO: would be useful to explain what it means to "drag people" - // what is it that is being dragged? - // is there a way to search for people (or things to drag) on this page? - if (editableProfile) { - comment('Drag people onto the target below to add people.') - } - - widgets.attachmentList(dom, me, main, { - doc: profile, - modify: !!editableProfile, - predicate: ns.foaf('knows'), - noun: 'friend' - }) - - heading('Communities you participate in') - - comment(`These are organizations and projects (etc) whose stuff you share`) - - // TODO: would be useful to explain what it means to "drag organizations" - // what is it that is being dragged? - // is there a way to search for people (or things to drag) on this page? - // Also provide a way of using cut and paste - if (editableProfile) { - comment('Drag organizations onto the target below to add organizations.') - } - - widgets.attachmentList(dom, me, main, { - doc: profile, - modify: !!editableProfile, - predicate: ns.solid('community'), - noun: 'community' - }) - - // heading('The style of your public profile') headings are in form now - renderProfileForm(main, me) - - heading('Thank you for filling your profile.') - }).catch(error => { - statusArea.appendChild(widgets.errorMessageBlock(dom, error, '#fee')) - }) - return div - } -} - -export default editProfileView diff --git a/src/profile/profile.dom.ts b/src/profile/profile.dom.ts deleted file mode 100644 index d0d1d3b..0000000 --- a/src/profile/profile.dom.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { DataBrowserContext } from 'pane-registry' -import { NamedNode } from 'rdflib' - -export function paneDiv ( - context: DataBrowserContext, - subject: NamedNode, - paneName: string -): HTMLElement { - const view = context.session.paneRegistry.byName(paneName) - if (!view) { - const warning = context.dom.createElement('div') - warning.innerText = `Unable to load view: ${paneName}` - return warning - } - const viewContainer = view.render(subject, context) - viewContainer.setAttribute( - 'style', 'border: 0.3em solid #444; border-radius: 0.5em' - ) - return viewContainer -} diff --git a/src/profile/profileFormText.ttl b/src/profile/profileFormText.ttl deleted file mode 100644 index afccb85..0000000 --- a/src/profile/profileFormText.ttl +++ /dev/null @@ -1,386 +0,0 @@ -# 20210404a -@prefix rdf: . -@prefix rdfs: . -@prefix foaf: . -@prefix owl: . -@prefix solid: . -@prefix ui: . -@prefix schema: . -@prefix vcard: . - -@prefix org: . -@prefix esco: . -@prefix wd: . -@prefix wdt: . - -@prefix : <#>. - -:this - "Profile form" ; - a ui:Form ; - # ui:part :backgroundColor, :highlightColor; - ui:parts ( - :styleGroup - :nicknameField - :pronounsForm - :LanguagesPrompt :LanguagesForm - :CVGroup - :SkillsPrompt :SkillsForm - ). - -:styleGroup a ui:Group; ui:weight 0; ui:parts ( :styleHeading :backgroundColor :highlightColor ). - :styleHeading a ui:Heading; ui:contents "The style of your public profile.". - :backgroundColor a ui:ColorField; ui:property solid:profileBackgroundColor; - ui:label "Background color"; ui:default "#ffffff". - :highlightColor a ui:ColorField; ui:property solid:profileHighlightColor; - ui:label "Highlight color"; ui:default "#000000". - -# Nickname - -:nicknameField a ui:SingleLineTextField; ui:size 12; ui:property foaf:nick; - ui:label "Short name for chats, etc."@en, "nom court"@fr. - - # Pronouns - - :pronounsForm a ui:Group; ui:weight 0; ui:parts ( :pronounsPrompt :subjectPronounForm :objectPronounForm :relativePronounForm) . - - :pronounsPrompt a ui:Comment; ui:contents "What are your pronouns?" . - - :subjectPronounForm a ui:SingleLineTextField; ui:property solid:preferredSubjectPronoun; - ui:size 10; ui:label "he/she/they..." . - :objectPronounForm a ui:SingleLineTextField; ui:property solid:preferredObjectPronoun; - ui:size 10; ui:label "him/her/them..." . - :relativePronounForm a ui:SingleLineTextField; ui:property solid:preferredRelativePronoun; - ui:size 10; ui:label "his/hers/theirs..." . - - # Curriculum Vitae: membership of organizations - - :CVHeading a ui:Heading; ui:contents "Public Curriculum Vitae". - :CVPrompt a ui:Comment; ui:contents "What organizations have you been involved with?" . - - :CVGroup a ui:Group; ui:weight 1; ui:parts ( :CVHeading :CVPrompt :involvementWithOrganizationsForm ). - - - solid:Role a rdfs:Class; owl:oneOf ( solid:CurrentRole solid:FormerRole solid:FutureRole ). # Future Role too? - - org:member owl:inverse [ ui:label "involvement with company, org etc" ]. # timelimited involvement - - :involvementWithOrganizationsForm a ui:Multiple; - ui:label "Involvement with Organization"; - ui:property org:member; ui:reverse true; # link back from role to member - ui:ordered false; # Allow user to order CV secions rather than force date order? No. - ui:part :RoleMembershipForm. - -# This is a big important form for one of a series of roles in the list. - - :RoleMembershipForm a ui:Group; ui:weight 3; ui:parts ( :MembershipFormHeading :roleNameField - :escoOccupationField :orgField :RoleClassifier :RoleDatesForm :RoleDescriptionForm). - - :MembershipFormHeading a ui:Heading; ui:contents "Details of this role"@en, "Détailes de ce rôle"@fr . - - :orgField a ui:Choice; ui:label "Organization"@en, "Organization"@fr; - ui:canMintNew true; ui:use :OrganizationCreationForm ; - ui:property org:organization; - ui:from vcard:Organization . - :roleNameField a ui:SingleLineTextField; ui:property vcard:role; ui:size 60 . - - :escoOccupationField a ui:AutocompleteField; - ui:label "occupation"; ui:size 60; - ui:property org:role; - ui:dataSource :ESCO_Occupation_DataSource; - ui:targetClass schema:Occupation . - - :ESCO_Occupation_DataSource a ui:DataSource; - schema:name "ESCO"; - ui:targetClass schema:Occupation ; - schema:logo ; - ui:searchByNameURI "https://ec.europa.eu/esco/api/search?language=$(language)&type=occupation&text=$(name)". - - :instituteIdentityField a ui:AutocompleteField; ui:label "in wikidata"; - ui:size 60; - ui:property solid:publicId; ui:dataSource :WikidataOnOrganizations. - - :WikidataOnOrganizations a ui:DataSource ; - schema:name "Wikidata"; - ui:endpoint "https://query.wikidata.org/sparql" ; - ui:targetClass ; # Use if nothing else - ui:searchByNameQuery """SELECT ?subject ?name - WHERE { - ?klass wdt:P279* $(targetClass) . - ?subject wdt:P31 ?klass . - ?subject rdfs:label ?name. - FILTER regex(?name, "$(name)", "i") - } LIMIT $(limit) """ . - - :WikidataOnOrganizations ui:classMap - [ ui:internalClass schema:Corporation; ui:externalClass ], #Enterprise is for-profit - [ ui:internalClass schema:EducationalOrganization; ui:externalClass ], #insitution - [ ui:internalClass schema:ResearchOrganization; ui:externalClass ], # reearch insitutie - [ ui:internalClass schema:GovernmentOrganization; ui:externalClass ], #government agency - [ ui:internalClass schema:MedicalOrganization; ui:externalClass ], - [ ui:internalClass schema:MusicGroup; ui:externalClass ], #music organization - [ ui:internalClass schema:NGO; ui:externalClass ], #nonprofit organization @@ - [ ui:internalClass schema:Occupation; ui:externalClass ], # superclass: Profession - [ ui:internalClass schema:Organization; ui:externalClass ], # Superclass; Organization - [ ui:internalClass schema:Project; ui:externalClass ], - [ ui:internalClass schema:SportsOrganization; ui:externalClass ] . - - -# eposodes in one's career - Roles - -solid:Role owl:disjointUnionOf ( solid:PastRole solid:CurrentRole solid:FutureRole ) . -solid:PastRole a rdfs:Class; rdfs:label "former role"@en, "ancien rôle"@fr, "vergangene Rolle"@de, "rol anterior"@es . -solid:CurrentRole a rdfs:Class; rdfs:label "current role"@en, "rôle actuel"@fr, "momentane Rolle"@de , "rol actual"@es . -solid:FutureRole a rdfs:Class; rdfs:label "future role"@en, "rôle à venir"@fr, "zukünftige Rolle"@de, "rol futuro"@es . - -:RoleDatesGroup a ui:Group; ui:weight 0; ui:parts ( :RoleClassifier :RoleDatesForm ) . - :RoleClassifier a ui:Classifier; ui:label "What sort of role?"@en; - ui:category solid:Role . - - :RoleDatesForm a ui:Options; ui:dependingOn rdf:type; ui:case - [ ui:for solid:PastRole; ui:use :TwoDateForm ], - [ ui:for solid:CurrentRole; ui:use :StartDateForm ], - [ ui:for solid:FutureRole; ui:use :StartDateForm ]. - - :StartDateForm a ui:DateField; ui:label "start"@en,"début"@fr; - ui:property schema:startDate . - :TwoDateForm a ui:Group; ui:weight 0; ui:parts ( :StartDateForm :EndDateForm ) . - :EndDateForm a ui:DateField; ui:label "end"@en,"fin"@fr; - ui:property schema:endDate . - -:RoleDescriptionForm a ui:MultiLineTextField; ui:property schema:description; - ui:label "Describe your role" . - -# Organizations - - vcard:Organization ui:creationForm :OrganizationCreationForm . - -# Ontology data to drive the classifier - -solid:InterestingOrganization owl:disjointUnionOf ( -# Airline - a Corporation -# Consortium - a Corporation or a NGO - schema:Corporation - schema:EducationalOrganization - schema:ResearchOrganization # Proposed. https://github.com/schemaorg/schemaorg/issues/2877 -# FundingScheme - eh? - schema:GovernmentOrganization -# LibrarySystem -# LocalBusiness - Corporation -# MedicalOrganization - a Corporation or a NGO - schema:NGO - # NewsMediaOrganization - a Corporation or a NGO -schema:PerformingGroup # a band -schema:Project # like Solid -schema:SportsOrganization # a Team -solid:OtherOrganization - ) . - -# This until the schema.org ontology adopts it -schema:ResearchOrganization a rdfs:Class; rdfs:label "Research Organization"@en, "Organization de Recherche"@fr , - "organización de investigación"@es, "منظمة البحث"@ar, "अनुसंधान संगठन"@hi, "Forschungsorganisation"@de, "shirika la utafiti"@sw . - - :OrganizationCreationForm a ui:Form; schema:name "Form for editing an organization using public data" ; - ui:parts ( :OrgClassifier :OrgSwitch :OrganizationNameField :homePageURIField ) . - - - :OrgClassifier a ui:Classifier; ui:label "What sort of organization?"@en; - ui:category solid:InterestingOrganization . - - :OrganizationNameField - a ui:SingleLineTextField ; - ui:label "Organization Name"; - ui:maxLength "200" ; - ui:property schema:name ; - ui:size 80 . - - :homePageURIField a ui:NamedNodeURIField; ui:size 80; - ui:label "Home page URI"@en; - ui:property schema:uri . # @@ ?? - - :initituteTypeField a ui:Classifier; - ui:label "What sort of organization"; - ui:category solid:InterestingOrganization . - -# Depending on the type of org, chose a different form - - :OrgSwitch a ui:Options; ui:dependingOn rdf:type; - ui:case - [ ui:for schema:Corporation; ui:use :CorporationForm ], - [ ui:for schema:GovernmentOrganization; ui:use :GovernmentOrganizationForm ], - [ ui:for schema:PerformingGroup; ui:use :PerformingGroupForm ], - [ ui:for schema:Project; ui:use :ProjectForm ], - [ ui:for schema:NGO; ui:use :NGOForm ], - [ ui:for schema:EducationalOrganization; ui:use :EducationalOrganizationForm ], - [ ui:for schema:ResearchOrganization; ui:use :ResearchOrganizationForm ], - [ ui:for :SportsOrganization; ui:use :SportsOrganizationForm ], - [ ui:for solid:OtherOrganization; ui:use :OtherOrganizationForm ]. - - - :CorporationForm a ui:Group; ui:weight 0; ui:parts ( :CorporationPrompt :CorporationAutocomplete ) . - - :CorporationPrompt a ui:Comment; ui:contents "Which corporation?". - - :CorporationAutocomplete a ui:AutocompleteField; - a ui:AutocompleteField; ui:label "Corporation in wikidata"; - ui:size 60; - ui:targetClass ; # Enterprise - ui:property solid:publicId; ui:dataSource :WikidataInstancesByName. - - :WikidataInstancesByName a ui:DataSource ; - schema:name "Wikidata instances by name"; - ui:endpoint "https://query.wikidata.org/sparql" ; - ui:searchByNameQuery """SELECT ?subject ?name - WHERE { - ?klass wdt:P279* $(targetClass) . - ?subject wdt:P31 ?klass . - ?subject rdfs:label ?name. - FILTER regex(?name, "$(name)", "i") - } LIMIT $(limit) """ ; - - # Note this form of the query is very experimental - ui:searchByName [ ui:construct { ?subject schema:name ?name } ; - ui:where { ?klass wdt:P279 ?targetClass . - ?subject wdt:P31 ?klass; rdfs:label ?name . - }; - ]. - - :GovernmentOrganizationForm a ui:Group; ui:weight 0; ui:parts ( :GovernmentOrganizationPrompt :GovernmentOrganizationAutocomplete ) . - - :GovernmentOrganizationPrompt a ui:Comment; ui:contents "Which GovernmentOrganization?". - - :GovernmentOrganizationAutocomplete - a ui:AutocompleteField; ui:label "GovernmentOrganization in wikidata"; - ui:size 60; - ui:targetClass ; # GovernmentOrganization - ui:property solid:publicId; ui:dataSource :WikidataInstancesByName. - - :EducationalOrganizationForm a ui:Group; ui:weight 1; ui:parts ( :EducationalOrganizationPrompt :EducationalOrganizationAutocomplete ) . - - :EducationalOrganizationPrompt a ui:Comment; ui:contents "Which Educational Organization?". - - :EducationalOrganizationAutocomplete - a ui:AutocompleteField; ui:label "Educational Organization in wikidata"; - ui:size 60; - ui:targetClass ; # EducationalOrganization - ui:property solid:publicId; ui:dataSource :WikidataInstancesByName. - - - :ResearchOrganizationForm a ui:Group; ui:weight 0; ui:parts ( :ResearchOrganizationPrompt :ResearchOrganizationAutocomplete ) . - - :ResearchOrganizationPrompt a ui:Comment; ui:contents "Which Research Organization?". - - :ResearchOrganizationAutocomplete - a ui:AutocompleteField; ui:label "Research Insitute in wikidata"; - ui:size 60; - ui:targetClass ; # research institute - ui:property solid:publicId; ui:dataSource :WikidataInstancesByName. - - - :NGOForm a ui:Group; ui:weight 0; ui:parts ( :NGOPrompt :NGOAutocomplete ) . - - :NGOPrompt a ui:Comment; ui:contents "Which NGO?". - - :NGOAutocomplete - a ui:AutocompleteField; ui:label "NGO in wikidata"; - ui:size 60; - ui:targetClass ; # Non-profit org - ui:property solid:publicId; ui:dataSource :WikidataInstancesByName. - - :PerformingGroupForm a ui:Group; ui:weight 0; ui:parts ( :PerformingGroupPrompt :PerformingGroupAutocomplete ) . - - :PerformingGroupPrompt a ui:Comment; ui:contents "Which PerformingGroup?". - - :PerformingGroupAutocomplete - a ui:AutocompleteField; ui:label "PerformingGroup in wikidata"; - ui:size 60; - ui:targetClass ; # Music Org - ui:property solid:publicId; ui:dataSource :WikidataInstancesByName. - - - :ProjectForm a ui:Group; ui:weight 0; ui:parts ( :ProjectPrompt :ProjectAutocomplete ) . # :ProjectAutocomplete - no: supress, as not in WD - - :ProjectPrompt a ui:Comment; ui:contents "Which Project?". - - :ProjectAutocomplete - a ui:AutocompleteField; ui:label "Project in wikidata"; - ui:size 60; - ui:targetClass ; # Project - ui:property solid:publicId; ui:dataSource :WikidataInstancesByName. - - :SportsOrganizationForm a ui:Group; ui:weight 0; ui:parts ( :SportsOrganizationPrompt :SportsOrganizationAutocomplete ) . - - :SportsOrganizationPrompt a ui:Comment; ui:contents "Which Sports Organization?". - - :SportsOrganizationAutocomplete - a ui:AutocompleteField; ui:label "SportsOrganization in wikidata"; - ui:size 60; - ui:targetClass ; # SportsOrganization - ui:property solid:publicId; ui:dataSource :WikidataInstancesByName. - - :OtherOrganizationForm a ui:Group; ui:weight 0; ui:parts ( :OrganizationNameField :homePageURIField ) . - - #################### Skills - - :SkillsPrompt a ui:Comment; ui:contents "Skills?" . - - :SkillsForm a ui:Multiple; - ui:label "Skills"; - ui:property schema:skills; - ui:ordered false; # Allow reader to order skills - ui:part :SkillForm. - - :SkillForm a ui:Group; ui:weight 1; ui:parts ( :escoSkillField ). - - # :skillNameField a ui:SingleLineTextField; ui:property vcard:role; ui:size 30 . - - :escoSkillField a ui:AutocompleteField; - ui:label "skill"; ui:size 30; - ui:property solid:publicId; - ui:dataSource :ESCO_Skill_DataSource; - ui:targetClass schema:Skill . - - :ESCO_Skill_DataSource a ui:DataSource; - schema:name "ESCO Skill"; - ui:targetClass esco:Skill ; - schema:logo ; - ui:searchByNameURI "https://ec.europa.eu/esco/api/search?language=$(language)&limit=$(limit)&type=skill&text=$(name)". - -# Language - -:LanguagesPrompt a ui:Comment; ui:contents "Languages?" . - -:LanguagesForm a ui:Multiple; - ui:label "Languages"; - ui:property schema:knowsLanguage; # @@@ - ui:ordered true; # Allow user to order languages most important first. - ui:part :LanguageForm. - -:LanguageForm a ui:Group; ui:weight 1; ui:parts ( :WikidataLanguageField ). - - :WikidataLanguageField a ui:AutocompleteField; - ui:label "Language"; ui:size 30; - ui:property solid:publicId; # @@ - ui:dataSource :WikidataLanguageDataSource; - ui:targetClass schema:Language . - - :WikidataLanguageDataSource - schema:name "Wikidata languages"; - ui:endpoint "https://query.wikidata.org/sparql" ; - ui:objectURIBase ; - # Add this to any literal string returned as ?subject - - ui:searchByNameQuery """SELECT ?item ?subject ?name -WHERE -{ ?item wdt:P305 ?subject . - OPTIONAL {?item rdfs:label ?name} - OPTIONAL {?item wdt:P1705 ?name} - FILTER regex(?name, "$(name)", "i") - FILTER regex(?subject, "^..$", "i") -}""" . - # Note we restrict code to two-letter codes with the second regex, so as to limit the deluge of languages - # Hope there are not any important ones which have three-letter codes. - # Omitted: SERVICE wikibase:label { bd:serviceParam wikibase:language "$(languages)". } - - -# ENDS diff --git a/src/registerPanes.js b/src/registerPanes.js index 00d571c..2ed2438 100644 --- a/src/registerPanes.js +++ b/src/registerPanes.js @@ -1,5 +1,5 @@ import profilePane from 'profile-pane' -import editProfileView from './profile/editProfile.view' +// import editProfileView from './profile/editProfile.view' import trustedApplications from './trustedApplications/trustedApplications.view' import dashboardPane from './dashboard/dashboardPane' import basicPreferences from './dashboard/basicPreferences' @@ -48,7 +48,10 @@ export function registerPanes (register) { // Developer designed: register(profilePane) // View someone's public profile - dominates all other panes. - register(editProfileView) // Edit my profile. App. 201900802 + const editProfileView = profilePane.editor + assert !! editProfileView, "profilePane is not providing an editor pane" + + register(editProfileView) // Edit my profile. register(trustedApplications) // must be registered before basicPreferences register(dashboardPane) From 9261d4e60df5a4749a60ae80658f4558c2c25a0b Mon Sep 17 00:00:00 2001 From: Tim Berners-Lee Date: Mon, 16 Sep 2024 08:31:40 -0400 Subject: [PATCH 08/10] typo --- src/registerPanes.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/registerPanes.js b/src/registerPanes.js index 2ed2438..a7fecc4 100644 --- a/src/registerPanes.js +++ b/src/registerPanes.js @@ -48,8 +48,8 @@ export function registerPanes (register) { // Developer designed: register(profilePane) // View someone's public profile - dominates all other panes. - const editProfileView = profilePane.editor - assert !! editProfileView, "profilePane is not providing an editor pane" + const editProfileView = profilePane.editor ; + console.log("@@@ editProfileView", "profilePane is not providing an editor pane") register(editProfileView) // Edit my profile. From cbadbc64f33ed8973d5fe59670f3ecd634783685 Mon Sep 17 00:00:00 2001 From: Tim Berners-Lee Date: Mon, 16 Sep 2024 10:00:41 -0400 Subject: [PATCH 09/10] actions/download-artifact@v4 --- .github/workflows/ci.yml | 4 ++-- src/registerPanes.js | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a03daac..3d7e5a9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,7 +47,7 @@ jobs: needs: build runs-on: ubuntu-latest steps: - - uses: actions/download-artifact@v2 + - uses: actions/download-artifact@v4 with: name: build - uses: actions/setup-node@v1 @@ -68,7 +68,7 @@ jobs: runs-on: ubuntu-latest if: github.ref == 'refs/heads/main' steps: - - uses: actions/download-artifact@v2 + - uses: actions/download-artifact@v4 with: name: build - uses: actions/setup-node@v1 diff --git a/src/registerPanes.js b/src/registerPanes.js index a7fecc4..64a8cde 100644 --- a/src/registerPanes.js +++ b/src/registerPanes.js @@ -49,7 +49,9 @@ export function registerPanes (register) { register(profilePane) // View someone's public profile - dominates all other panes. const editProfileView = profilePane.editor ; - console.log("@@@ editProfileView", "profilePane is not providing an editor pane") + if (!editProfileView) { + console.log("@@@ editProfileView", "profilePane is not providing an editor pane") + } register(editProfileView) // Edit my profile. From 5c9da1cd2e8bc1bee49495616fd1679584fdb8d2 Mon Sep 17 00:00:00 2001 From: Tim Berners-Lee Date: Mon, 16 Sep 2024 10:03:53 -0400 Subject: [PATCH 10/10] actions/upload-artifact@v4 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3d7e5a9..309231d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,7 +35,7 @@ jobs: - run: npm run build --if-present - name: Save build if: matrix.node-version == '16.x' - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: build path: |